datacommsserver/esockserver/test/protocols/pdummy/PDUMMY.CPP
changeset 0 dfb7c4ff071f
child 4 928ed51ddc43
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/test/protocols/pdummy/PDUMMY.CPP	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,2471 @@
+// Copyright (c) 1997-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:
+//
+
+#include <es_prot.h>
+#include <e32test.h>
+#include "ES_DUMMY.H"
+#include <comms-infras/nifif.h>
+#include <es_mbuf.h>
+#include <ss_std.h>
+#include <ss_pman.h>
+#include <ss_glob.h>
+#include <e32math.h>
+#include <dns_qry.h>
+#include <agenterrors.h>
+#include <e32property.h>
+#include <nifman_internal.h>
+#include "pdummy.h"
+
+
+#ifdef _DEBUG
+// Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
+// (if it could happen through user error then you should give it an explicit, documented, category + code)
+_LIT(KSpecAssert_ESockTestPDUMMY, "ESockTestPDUMMY.");
+#endif
+
+const TInt KPDummyDefaultGranularity=0xA; // Default number of incoming messages the protocol can queue up
+
+//---------------------------------------------------------------------------------------------------------
+
+
+CAsyncSocketErrorer* CAsyncSocketErrorer::NewL(MSocketNotify& aSocket,TInt aErrorCode,TUint aOpMask,
+                                  CDummyProtocol * apProtocols, CDummyProvd* aOwner,const TDesC8* aListenData )
+	{
+	return new(ELeave) CAsyncSocketErrorer(aSocket, aErrorCode, aOpMask,apProtocols,aOwner,aListenData);
+	}
+
+CAsyncSocketErrorer::CAsyncSocketErrorer(MSocketNotify& aSocket, TInt aErrorCode, TUint aOpMask,
+		CDummyProtocol* apProtocols, CDummyProvd* aOwner, const TDesC8* aListenData):
+    CActive(KMaxTInt),
+	iSocket(aSocket),
+	iErrorCode(aErrorCode),
+	iOpMask(aOpMask),
+	ipProtocols(apProtocols),
+	iOwner(aOwner),
+	iListenData(aListenData)
+	{
+	CActiveScheduler::Add(this);
+	SetActive();
+	TRequestStatus* p = &iStatus;
+	User::RequestComplete(p, KErrNone);
+	}
+
+void CAsyncSocketErrorer::RunL()
+	{
+	CDummyProvd* p = NULL;
+    if ( iErrorCode == KErrNone )
+        {
+	    TRAP(iErrorCode,p = CDummyProvd::NewL(*ipProtocols););
+	    if (iErrorCode)
+	    	{
+	    	iOpMask = MSocketNotify::EErrorFatal;
+	    	}
+        }
+    if ( iErrorCode == KErrNone )
+        {
+	    if(iListenData)
+	    	{
+	    	iSocket.ConnectComplete(*p, *iListenData);
+	    	}
+	    else
+	    	{
+	    	iSocket.ConnectComplete(*p);
+	    	}
+        }
+    else
+        {
+	    iSocket.Error(iErrorCode,iOpMask);
+        }
+	iOwner->DestroyAsyncErrorer();	// ie "delete this"
+	}
+
+CAsyncSocketErrorer::~CAsyncSocketErrorer()
+	{
+	Cancel();
+	}
+
+void CAsyncSocketErrorer::DoCancel()
+	{
+	}
+
+//---------------------------------------------------------------------------------------------------------
+
+NONSHARABLE_CLASS(CDummyProvd::CFlowOnTimer): public CTimer
+	{
+public:
+	static CFlowOnTimer* NewL(CDummyProvd& aProvd, MSocketNotify& aSocketNotify);
+	virtual ~CFlowOnTimer();
+
+	virtual void RunL();
+
+private:
+	CFlowOnTimer(CDummyProvd& aProvd, MSocketNotify& aSocket);
+
+	CDummyProvd& iProvd;
+	MSocketNotify& iSocketNotify;
+	};
+
+
+CDummyProvd::CFlowOnTimer* CDummyProvd::CFlowOnTimer::NewL(CDummyProvd& aProvd, MSocketNotify& aSocketNotify)
+	{
+	CFlowOnTimer* self = new(ELeave) CFlowOnTimer(aProvd, aSocketNotify);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CActiveScheduler::Add(self);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CDummyProvd::CFlowOnTimer::CFlowOnTimer(CDummyProvd& aProvd, MSocketNotify& aSocketNotify)
+	: CTimer(CActive::EPriorityStandard), iProvd(aProvd), iSocketNotify(aSocketNotify)
+	{
+	}
+
+
+CDummyProvd::CFlowOnTimer::~CFlowOnTimer()
+	{
+	Cancel();
+	}
+
+void CDummyProvd::CFlowOnTimer::RunL()
+	{
+	iProvd.iFlowOffWriteTimeout = 0;
+	iSocketNotify.CanSend();
+	}
+
+enum TDPanic
+	{
+	EBadProtocol,
+	EBadCall,
+	ENotBound,
+	ENotStarted,
+	EInterfaceNotDeleted,
+	EIdAndNoHolder,
+	EIfAndHolder,
+	ETestPanic
+	};
+
+// RTest test(_L("Dummy protocol"));
+
+LOCAL_C void Panic(TDPanic aPanic)
+//
+// Panic the Protocol
+//
+	{
+
+	User::Panic(_L("Dummy Prot"),aPanic);
+	}
+
+extern "C"
+	{
+	IMPORT_C CProtocolFamilyBase* InstallDummy(void);	// Force export
+
+	EXPORT_C CProtocolFamilyBase * InstallDummy(void)
+	//
+	// Create a new protocol family
+	//
+		{
+		return CDProtocolFamily::NewL();
+		}
+	}
+
+CDProtocolFamily* CDProtocolFamily::NewL()
+//
+//
+//
+	{
+	CDProtocolFamily* pf = new (ELeave) CDProtocolFamily();
+	CleanupStack::PushL(pf);
+	pf->ConstructL();
+	CleanupStack::Pop();
+	return pf;
+	}
+
+void CDProtocolFamily::ConstructL()
+//
+//
+//
+	{
+	// Force a fail on Memory tests
+	char* ptr=new(ELeave) char;
+	delete ptr;
+
+	}
+
+CDProtocolFamily::CDProtocolFamily() : CProtocolFamilyBase()
+	{
+	iProtocolDescs[0].iAddrFamily=KDummyAddrFamily;
+	iProtocolDescs[0].iSockType=KSockDatagram;
+	iProtocolDescs[0].iProtocol=KDummyOne;
+	iProtocolDescs[0].iVersion=TVersion(KDummyMajor,KDummyMinor,KDummyBuild);
+	iProtocolDescs[0].iByteOrder=EBigEndian;
+	// KSIRequiresOwnerInfo is required to ensure that SetOption(KSoSetPlatSecApi) is issued to
+	// TransportFlowShim for NoBearer() testing.
+	iProtocolDescs[0].iServiceInfo=kDDatagramServiceInfo|KSIPeekData|KSIRequiresOwnerInfo;
+	iProtocolDescs[0].iSecurity=KSocketNoSecurity;
+	iProtocolDescs[0].iMessageSize=0x300;
+	iProtocolDescs[0].iName=KDummyOneName;
+	iProtocolDescs[0].iServiceTypeInfo=ESocketSupport|ECantProcessMBufChains;
+	iProtocolDescs[0].iNamingServices=KNSNameResolution|KNSServiceResolution|KNSInfoDatabase;
+	iProtocolDescs[0].iNumSockets=100;
+
+	iProtocolDescs[1].iAddrFamily=KDummyAddrFamily;
+	iProtocolDescs[1].iSockType=KSockStream;
+	iProtocolDescs[1].iProtocol=KDummyTwo;
+	iProtocolDescs[1].iVersion=TVersion(KDummyMajor,KDummyMinor,KDummyBuild);
+	iProtocolDescs[1].iByteOrder=EBigEndian;
+	iProtocolDescs[1].iServiceInfo=KDStreamServiceInfo;
+	iProtocolDescs[1].iSecurity=KSocketNoSecurity;
+	iProtocolDescs[1].iMessageSize=KSocketMessageSizeIsStream;
+	iProtocolDescs[1].iName=KDummyTwoName;
+	iProtocolDescs[1].iServiceTypeInfo=ESocketSupport|ECantProcessMBufChains;
+	iProtocolDescs[1].iNamingServices=0;
+	iProtocolDescs[1].iNumSockets=100;
+
+	iProtocolDescs[2].iAddrFamily=KDummyAddrFamily;
+	iProtocolDescs[2].iSockType=KSockSeqPacket;
+	iProtocolDescs[2].iProtocol=KDummyThree;
+	iProtocolDescs[2].iVersion=TVersion(KDummyMajor,KDummyMinor,KDummyBuild);
+	iProtocolDescs[2].iByteOrder=EBigEndian;
+	iProtocolDescs[2].iServiceInfo=KSIReliable|KSIInOrder|KSIDatagram|KSIGracefulClose|KSIBroadcast|KSIQOS|KSICanReconnect|KSIConnectData|KSIDisconnectData;
+	iProtocolDescs[2].iSecurity=KSocketNoSecurity;
+	iProtocolDescs[2].iMessageSize=KSocketMessageSizeNoLimit;
+	iProtocolDescs[2].iName=KDummyThreeName;
+	iProtocolDescs[2].iServiceTypeInfo=ESocketSupport|ECantProcessMBufChains|ETransport|EPreferDescriptors|EUseCanSend;
+	iProtocolDescs[2].iNamingServices=0;
+	iProtocolDescs[2].iNumSockets=100;
+
+	iProtocolDescs[3].iAddrFamily=KDummyAddrFamily;
+	iProtocolDescs[3].iSockType=KSockStream;
+	iProtocolDescs[3].iProtocol=KDummyFour;
+	iProtocolDescs[3].iVersion=TVersion(KDummyMajor,KDummyMinor,KDummyBuild);
+	iProtocolDescs[3].iByteOrder=EBigEndian;
+	iProtocolDescs[3].iServiceInfo=KDStreamServiceInfo;
+	iProtocolDescs[3].iSecurity=KSocketNoSecurity;
+	iProtocolDescs[3].iMessageSize=KSocketMessageSizeIsStream;
+	iProtocolDescs[3].iName=KDummyFourName;
+	iProtocolDescs[3].iServiceTypeInfo=ESocketSupport|ENeedMBufs;
+	iProtocolDescs[3].iNamingServices=0;
+	iProtocolDescs[3].iNumSockets=100;
+
+	iProtocolDescs[4].iAddrFamily=KDummyAddrFamily;
+	iProtocolDescs[4].iSockType=KSockDatagram;
+	iProtocolDescs[4].iProtocol=KDummyFive;
+	iProtocolDescs[4].iVersion=TVersion(KDummyMajor,KDummyMinor,KDummyBuild);
+	iProtocolDescs[4].iByteOrder=EBigEndian;
+	iProtocolDescs[4].iServiceInfo=kDDatagramServiceInfo|KSIPeekData;
+	iProtocolDescs[4].iSecurity=KSocketNoSecurity;
+	iProtocolDescs[4].iMessageSize=KSocketMessageSizeNoLimit;
+	iProtocolDescs[4].iName=KDummyFiveName;
+	iProtocolDescs[4].iServiceTypeInfo=ESocketSupport|ECantProcessMBufChains;
+	iProtocolDescs[4].iNamingServices=KNSNameResolution|KNSServiceResolution|KNSInfoDatabase;
+	iProtocolDescs[4].iNumSockets=100;
+
+	__DECLARE_NAME(_S("CDProtocolFamily"));
+	}
+
+#pragma warning( disable : 4100 )
+
+TInt CDProtocolFamily::Install()
+	{
+	// Force a fail on Memory tests
+	char* ptr=new char;
+	if (!ptr)
+		return KErrNoMemory;
+	delete ptr;
+	return KErrNone;
+	}
+
+TInt CDProtocolFamily::Remove()
+	{
+	return KErrNone;
+	}
+
+TUint CDProtocolFamily::ProtocolList(TServerProtocolDesc *& aProtocolDescPointer)
+	{
+
+  	aProtocolDescPointer=new TServerProtocolDesc[KPDummyNumProtocols];
+  	if (!aProtocolDescPointer)
+  		return 0;
+
+	Mem::Copy(aProtocolDescPointer, iProtocolDescs, sizeof(TServerProtocolDesc)*KPDummyNumProtocols);
+
+	TRAP_IGNORE(Nif::CheckInstalledMBufManagerL();)
+
+	return KPDummyNumProtocols;
+	};
+
+CProtocolBase * CDProtocolFamily::NewProtocolL(TUint /* aSockType */,TUint aProtocol)
+	{
+
+	CDummyProtocol* p=CDummyProtocol::NewL(aProtocol, &iProtocolDescs[aProtocol-1]);
+	return p;
+	}
+
+
+//---------------------------------------------------------------------------------------------------------
+
+
+CServProviderBase * CDummyProtocol::NewSAPL(TUint /*aProtocol*/)
+	{
+	return CDummyProvd::NewL(*this);
+	}
+
+
+CHostResolvProvdBase* CDummyProtocol::NewHostResolverL()
+	{
+	return CDatagramHostResolver::NewL();
+	}
+
+CServiceResolvProvdBase* CDummyProtocol::NewServiceResolverL()
+	{
+	return CDatagramServResolver::NewL();
+	}
+
+CNetDBProvdBase* CDummyProtocol::NewNetDatabaseL()
+	{
+	return CDatagramNetDataBase::NewL();
+	}
+
+CDummyProtocol::~CDummyProtocol()
+	{
+	for (TInt i=0;i<iProtocols.Count();i++)
+		{
+		iProtocols[i]->Close();
+		}
+	}
+
+
+void CDummyProtocol::InitL(TDesC& /*aTag*/)
+	{
+	// Force a fail on Memory tests
+	char* ptr=new(ELeave) char;
+	delete ptr;
+	}
+
+void CDummyProtocol::BindL(CProtocolBase* /*aProtocol*/, TUint /*anId*/)
+	{
+	// Force a fail on Memory tests
+	char* ptr=new(ELeave) char;
+	delete ptr;
+	}
+
+void CDummyProtocol::BindToL(CProtocolBase* aProtocol)
+	{
+	// Force a fail on Memory tests
+	char* ptr=new(ELeave) char;
+	delete ptr;
+	iProtocols.AppendL(aProtocol);
+	aProtocol->Open();
+	}
+
+
+void CDummyProtocol::StartL(void)
+	{
+	// Force a fail on Memory tests
+	char* ptr=new(ELeave) char;
+	delete ptr;
+	iIsStarted=ETrue;
+	}
+
+TInt CDummyProtocol::Send(RMBufChain &,CProtocolBase* /*aSourceProtocol*/)
+	{
+	return 1;
+	}
+
+TInt CDummyProtocol::Send(TDes8 &, TSockAddr* /*to*/,TSockAddr* /*from*/,CProtocolBase* /*aSourceProtocol*/)
+	{
+	return 1;
+	}
+
+void CDummyProtocol::Process(RMBufChain &,CProtocolBase* /*aSourceProtocol*/)
+	{
+	}
+
+void CDummyProtocol::Process(TDes8 & ,TSockAddr* /*from*/,TSockAddr* /*to*/,CProtocolBase* /*aSourceProtocol*/)
+	{
+	}
+
+void CDummyProtocol::Identify(TServerProtocolDesc *aDesc) const
+	{
+	Mem::Copy(aDesc, iProtoDesc, sizeof(TServerProtocolDesc));
+	}
+
+TInt CDummyProtocol::GetOption(TUint level,TUint,TDes8&,CProtocolBase* /*aSourceProtocol*/)
+	{
+
+	if(level==KNifOptLevel)
+		{
+		return KErrNotSupported;
+		}
+	return KErrNone;
+	}
+
+TInt CDummyProtocol::SetOption(TUint /*level*/,TUint /*name*/,const TDesC8& /*option*/,CProtocolBase* /*aSourceProtocol*/)
+	{
+	return KErrNone;
+	}
+
+void CDummyProtocol::Error(TInt /*anerror*/,CProtocolBase* /*aSourceProtocol*/)
+	{
+	}
+
+
+EXPORT_C CDummyProtocol *CDummyProtocol::NewL(TInt aType, TServerProtocolDesc* aProtoDesc)
+	{
+
+	CDummyProtocol* p=0;
+	switch (aType)
+		{
+	case KDummyOne:
+	case KDummyTwo:
+	case KDummyFive:
+		p=new (ELeave) CDummyProtocol(aProtoDesc);
+		break;
+
+	case KDummyThree:
+	case KDummyFour:
+		p=new (ELeave) CInterfaceProtocol(aProtoDesc);
+		break;
+
+	default:
+		p=(CDummyProtocol*)0xABCD; // keep lint happy
+		Panic(EBadProtocol);
+		}
+	p->iType=aType;
+	return p;
+	}
+
+
+EXPORT_C CDummyProtocol::CDummyProtocol(TServerProtocolDesc* aProtoDesc)
+
+	:CProtocolBase(),iProtoDesc(aProtoDesc),iProtocols(0x16)
+	{
+	__DECLARE_NAME(_S("CDummyProtocol"));
+	iIsStarted=EFalse;
+	}
+
+
+/* exported functions that are used to exercise ProtocolBase functionality
+*/
+EXPORT_C TInt CDummyProtocol::ProtocolBaseBind(CProtocolBase* aProt, TUint aId)
+	// expected to Panic(EDoesNotBindBelow);
+	{
+	TRAPD(ret, CProtocolBase::BindL(aProt, aId));
+	return ret;
+	}
+
+
+EXPORT_C TInt CDummyProtocol::ProtocolBaseBindTo(CProtocolBase* aProt)
+	// expected to Panic(EDoesNotBindAbove);
+	{
+	TRAPD(ret, CProtocolBase::BindToL(aProt));
+	return ret;
+	}
+
+EXPORT_C TInt CDummyProtocol::ProtocolBaseError(CProtocolBase* aProt)
+	// expected to Panic(EErrorCallNotHandled)
+	{
+	CProtocolBase::Error(KErrNone, aProt);
+	return KErrNone;
+	}
+
+EXPORT_C TInt CDummyProtocol::ProtocolBaseGetOption(TUint aLevel, TUint aName, TDes8& aBuf, CProtocolBase* aProt)
+	{
+	// expected to return KErrNotSupported
+	TInt ret = CProtocolBase::GetOption(aLevel,aName,aBuf,aProt);
+	__ASSERT_DEBUG(ret == KErrNotSupported, User::Panic(KSpecAssert_ESockTestPDUMMY, 1));
+	return ret;
+	}
+
+EXPORT_C TInt CDummyProtocol::ProtocolBaseNewHostResolver()
+	// expected to panic with Fault(EBadHostResolver);
+	{
+	TRAPD(ret, CProtocolBase::NewHostResolverL());
+	return ret;
+	}
+
+EXPORT_C TInt CDummyProtocol::ProtocolBaseNewNetDatabase()
+	// expected to panic with Fault(EBadNetDBRequest)
+	{
+	TRAPD(ret, CProtocolBase::NewNetDatabaseL());
+	return ret;
+	}
+
+EXPORT_C TInt CDummyProtocol::ProtocolBaseNewSAP(TUint aProt)
+	// expected to panic with Fault(EOddSock)
+	{
+	TRAPD(ret, CProtocolBase::NewSAPL(aProt));
+	return ret;
+	}
+
+EXPORT_C TInt CDummyProtocol::ProtocolBaseNewServiceResolver()
+	// expected to panic with Fault(EBadServiceResolver)
+	{
+	TRAPD(ret, CProtocolBase::NewServiceResolverL());
+	return ret;
+	}
+
+EXPORT_C TInt CDummyProtocol::ProtocolBaseProcess(RMBufChain &aChain, CProtocolBase* aProt)
+	// expected to panic with Panic(ECantProcessMbufs)
+	{
+	CProtocolBase::Process(aChain, aProt);
+	return KErrNone;
+	}
+
+EXPORT_C TInt CDummyProtocol::ProtocolBaseSend(RMBufChain &aChain, CProtocolBase* aProt)
+	// expected to panic with Panic(ECantSendMBufs);
+	{
+	TInt ret = CProtocolBase::Send(aChain, aProt);
+	return ret;
+	}
+
+EXPORT_C TInt CDummyProtocol::ProtocolBaseSetOption(TUint aLevel, TUint aName, TDes8& aBuf, CProtocolBase* aProt)
+	// expected to return KErrNotSupported
+	{
+	TInt ret = CProtocolBase::SetOption(aLevel, aName, aBuf, aProt);
+	__ASSERT_DEBUG(ret == KErrNotSupported, User::Panic(KSpecAssert_ESockTestPDUMMY, 2));
+	return ret;
+	}
+
+EXPORT_C TInt CDummyProtocol::ProtocolBaseSendWithAddress(TDes8& aBuf,TSockAddr* aTo ,TSockAddr* aFrom, CProtocolBase* aProt)
+	// expected to panic with Panic(ECantSendMBufs);
+	{
+	TInt ret = CProtocolBase::Send(aBuf, aTo, aFrom, aProt);
+	return ret;
+	}
+
+
+EXPORT_C TInt CDummyProtocol::ProtocolBaseProcessWithAddress(TDes8& aBuf, TSockAddr* aFrom, TSockAddr* aTo, CProtocolBase* aProt)
+	// expected to panic with Panic(ECantProcessMbufs)
+	{
+	CProtocolBase::Process(aBuf, aFrom, aTo, aProt);
+	return KErrNone;
+	}
+
+//---------------------------------------------------------------------------------------------------------
+
+CDummyProvd *CDummyProvd::NewL(CDummyProtocol &aProtocol)
+	{
+	CDummyProvd *sp=new(ELeave) CDummyProvd(aProtocol);
+	CleanupStack::PushL(sp);
+	sp->ConstructL();
+	CleanupStack::Pop(sp);
+	return sp;
+
+	}
+
+void CDummyProvd::ConstructL()
+	{
+	iDataArray = new (ELeave) CArrayFixFlat<RMBufChain>(KPDummyDefaultGranularity);
+	iChain.AllocL(128);
+	}
+
+TInt CDummyProvd::NoBearerCB(TAny* aArg)
+/**
+Issue a NoBearer() upcall to ESock.
+ */
+    {
+    CDummyProvd* This = static_cast<CDummyProvd*>(aArg);
+    // Scoped NoBearer() prevents a connection from being started by ESock - a side-effect we aren't interested in.
+    _LIT8(KScoped, "scoped");
+    This->iSocket->NoBearer(KScoped()); 
+    return KErrNone;
+    }
+
+CDummyProvd::CDummyProvd(CDummyProtocol &aProtocol) :
+	  iCancelIoctl(EFalse),
+	  iFlowOffWriteTimeout(0),
+	  iErrNoMBufs(EFalse),
+	  iNoBearerCB(TCallBack(NoBearerCB, this), EPriorityNormal)
+	{
+	__DECLARE_NAME(_S("CDummyProvd"));
+	iIsBound=EFalse;
+	iProtocol=&aProtocol;
+	iCompleteIoctl = FALSE;
+	iConnectCompleteState = ETrue;
+	iConnectPending = EFalse;
+	}
+
+CDummyProvd::~CDummyProvd()
+//
+
+	{
+	if (iDataArray)
+		{
+		TInt c = iDataArray->Count();
+		TInt i;
+		for (i=0; i < c; ++i)
+			{
+			iDataArray->At(i).Free();
+			}
+		delete iDataArray;
+		}
+
+	iListenData.Close();
+	iChain.Free();
+	delete iFlowOnTimer;
+	}
+
+void CDummyProvd::DestroyAsyncErrorer()
+	{
+	delete iAsyncErrorer;
+	iAsyncErrorer = NULL;
+	}
+
+
+void CDummyProvd::LocalName(TSockAddr& anAddr) const
+	{
+	anAddr=iAddr;
+	}
+
+TInt CDummyProvd::SetLocalName(TSockAddr& anAddr)
+	{
+	iAddr=anAddr;
+	iIsBound=ETrue;
+	return KErrNone;
+	}
+
+void CDummyProvd::RemName(TSockAddr& /*anAddr*/)const
+	{
+	}
+
+TInt CDummyProvd::SetRemName(TSockAddr& /*anAddr*/)
+	{
+	return KErrNone;
+	}
+
+TInt CDummyProvd::GetOption(TUint aLevel, TUint aName, TDes8& anOption) const
+	{
+	if(aLevel==KNifOptLevel)
+		{
+		return iProtocol->GetOption(aLevel, aName, anOption, 0);
+		}
+	else
+		{
+		switch(aName)
+			{
+			case KDummyOptionSetBlockConnect:
+				{
+				TBool blockedConnect = !iConnectCompleteState;
+				const TUint8* opt = reinterpret_cast<const TUint8*>(&blockedConnect);
+				anOption.Copy(opt,sizeof(blockedConnect));
+				return KErrNone;
+				}
+			case KDummyOptionSetErrorNextWrite:
+				{
+				anOption.Copy(reinterpret_cast<const TUint8*>(&iErrorForNextWrite), sizeof(iErrorForNextWrite));
+				return KErrNone;
+				}
+			case KDummyOptionSetErrorNextShutdown:
+				{
+				anOption.Copy(reinterpret_cast<const TUint8*>(&iErrorForNextShutdown), sizeof(iErrorForNextShutdown));
+				return KErrNone;
+				}
+			case KDummyOptionSetErrorNextConnect:
+				{
+				anOption.Copy(reinterpret_cast<const TUint8*>(&iErrorForNextConnect), sizeof(iErrorForNextConnect));
+				return KErrNone;
+				}
+			case KDummyOptionGetMBufFreeSpace:
+				{
+				RMBufAllocator mBufAllocator;
+				TInt availableBytes = mBufAllocator.BytesAvailable();
+				anOption.Copy(reinterpret_cast<const TUint8*>(&availableBytes), sizeof(availableBytes));
+				return KErrNone;
+				}
+			default:
+				return KErrNotSupported;
+			}
+		}
+	}
+
+TInt CDummyProvd::SetOption(TUint level,TUint name,const TDesC8& anOption)
+	{
+	switch(name)
+		{
+		case KDummyOptionSetErrorNextListen:
+			iListenErrorCode=*(TInt*)&anOption[0];
+			break;
+		case KDummyOptionSetConnectComplete:
+			__ASSERT_DEBUG(!iAsyncErrorer, User::Panic(KSpecAssert_ESockTestPDUMMY, 3));	// to support multiple outstanding would need a list
+				{
+				TInt ret = KErrNone;
+				if (iListenData.Length())
+					{
+					TRAP(ret,iAsyncErrorer = CAsyncSocketErrorer::NewL(*iSocket, KErrNone,0, iProtocol, this, &iListenData));
+					}
+			    else
+			    	{
+			    	TRAP(ret,iAsyncErrorer = CAsyncSocketErrorer::NewL(*iSocket,KErrNone,0,iProtocol,this,NULL));
+			    	}
+	            return ret;
+				}
+		case KDummyOptionSetBlockConnect:
+			return SetBlockedConnect(anOption);
+		case KDummyOptionSetBlockConnectData:
+			{
+			TBool opt = *reinterpret_cast<const TBool*>(anOption.Ptr());
+			if (!opt)	
+				{
+				iListenData.Create(KConnectCompleteData());
+				}
+			else
+				{
+				iConnectPending = ETrue;	
+				}
+			return SetBlockedConnect(anOption);
+			}			
+		case KDummyOptionSetIocltComplete:
+			if (iCompleteIoctl)
+				{
+				iSocket->IoctlComplete(NULL);
+				iCompleteIoctl = EFalse;
+				}
+			break;
+		case KDummyOptionSetErrorNextWrite:
+			return OptToErr(anOption,iErrorForNextWrite);
+		case KDummyOptionSetErrorNextShutdown:
+			return OptToErr(anOption,iErrorForNextShutdown);
+		case KDummyOptionSetErrorNextConnect:
+			return OptToErr(anOption,iErrorForNextConnect);
+
+	case KDummyOptionSetFlowOffWrite:
+		{
+		if (anOption.Length() != sizeof(TBool))
+			return KErrArgument;
+
+		iFlowOffWrite = *reinterpret_cast<const TBool*>(anOption.Ptr());
+		if (!iFlowOffWrite)
+			iSocket->CanSend();
+		}
+		break;
+
+
+	case KDummyOptionSetTimedFlowOffWrite:
+		{
+		if (anOption.Length() != sizeof(TInt))
+			return KErrArgument;
+
+		iFlowOffWriteTimeout = *reinterpret_cast<const TInt*>(anOption.Ptr());
+		if (iFlowOffWriteTimeout > 0)
+			{
+			if (!iFlowOnTimer)
+				{
+				TRAPD(ret, iFlowOnTimer = CFlowOnTimer::NewL(*this, *iSocket));
+				if (ret)
+					return ret;
+				}
+			}
+		else if (iFlowOffWriteTimeout == 0)
+			{
+			delete iFlowOnTimer;
+			iFlowOnTimer = NULL;
+			}
+		else
+			return KErrArgument;
+		}
+		break;
+
+	case KDummyOptionSetGobbleMBufs:
+		{
+		iErrNoMBufs = ETrue;
+		return GobbleMBufs();
+		}
+
+	case KDummyOptionSetFreeMBufs:
+		{
+		iErrNoMBufs = EFalse;
+		FreeMBufs();
+		break;
+		}
+
+	case KDummyOptionSetFreeSomeMBufs:
+		{
+		iErrNoMBufs = EFalse;
+		FreeMBufs(level);
+		break;
+		}
+
+
+	case KDummyOptionLeakMemory:
+		{
+		for(TUint i = 0; i < level; ++i)
+			{
+			(void) new TInt;	// deliberately leak the allocs
+			}
+		return KErrNone;
+		}
+		
+	case KDummyOptionIssueNoBearer:
+	    {
+	    // Issue a NoBearer() upcall.  We are testing the behaviour whereby NoBearer() is called
+	    // outside the context of any pending IPC.  We use an async callback to ensure that the current
+	    // SetOption() IPC is completed by ESock before the NoBearer() upcall.
+	    iNoBearerCB.Call();
+	    return KErrNone;
+	    }
+
+	default:
+		return KErrNotSupported;
+		}
+	return KErrNone;
+	}
+
+TInt CDummyProvd::GobbleMBufs()
+// Eat all the available mBufs in the mBuf pool
+	{
+	RMBufAllocator allocator;
+	RMBufChain aChain;
+	TInt size = allocator.NextMBufSize(0);
+	while (size != KErrNotFound)
+		{
+		TInt ret = KErrNone;
+		while (ret == KErrNone)
+			{
+			TRAP(ret, aChain.AllocL(size));
+			iChain.Append(aChain);
+			}
+		size = allocator.NextMBufSize(size);
+		}
+		
+	TInt length = iChain.Length();
+	RDebug::Print(_L("Out of MBuf Memory... Total MBuf memory in use %d"), length);
+	TInt numBufs = iChain.NumBufs();
+	RDebug::Print(_L("Out of MBuf Memory... Total MBufs in use %d"), numBufs);
+	return numBufs;
+	}
+
+void CDummyProvd::FreeMBufs()
+// Free All the MBufs that were allocated by GobbleMBufs
+	{
+	if(iChain.IsEmpty())
+		{
+		return;
+		}
+	iChain.Free();
+	TInt length = iChain.Length();
+	RDebug::Print(_L("MBufMemory De-Allocated... Total MBuf memory in use %d"), length);
+	}
+
+void CDummyProvd::FreeMBufs(TUint aNumber)
+// Free aNumber of mBufs that were allocated by GobbleMBufs
+	{
+	if(iChain.IsEmpty())
+		{
+		return;
+		}
+	TInt length = 0;
+	while (aNumber-- > 0)
+		{
+		TInt length = iChain.Length();
+		if (length == 0)
+			{
+			break;
+			}
+		TInt trimOffset = length - iChain.Last()->Size();
+		iChain.TrimEnd(trimOffset);
+		}
+	length = iChain.Length();
+	RDebug::Print(_L("MBufMemory De-Allocated... Total MBuf memory in use %d"), length);
+	}
+
+
+TInt CDummyProvd::OptToErr(const TDesC8 &aOption, TInt &aRes)
+	{
+	if (aOption.Length() != sizeof(TInt))
+		{
+		return KErrCorrupt;
+		}
+	const TInt &opt = *reinterpret_cast<const TInt*>(aOption.Ptr());
+	if (opt > KErrNone)
+		{
+		return KErrCorrupt;
+		}
+	aRes = opt;
+	return KErrNone;
+	}
+
+TInt CDummyProvd::SetBlockedConnect(const TDesC8 &anOption)
+	{
+	if (anOption.Length() != sizeof(TBool))
+		{
+		return KErrCorrupt;
+		}
+	TBool opt = *reinterpret_cast<const TBool*>(anOption.Ptr());
+	if (opt != TRUE && opt != FALSE)
+		{
+		return KErrCorrupt;
+		}
+	iConnectCompleteState = !opt;
+	if (iConnectCompleteState && iConnectPending)
+		{
+			if (iErrorForNextConnect != KErrNone)
+			{
+			iSocket->Error(iErrorForNextConnect, MSocketNotify::EErrorConnect);
+			iErrorForNextConnect = KErrNone;
+			return KErrNone;
+			}
+		if (iListenData.Length())
+			{
+			iSocket->ConnectComplete(iListenData);
+			}
+		else
+			{
+			iSocket->ConnectComplete();
+			}
+		iConnectPending = EFalse;
+		}
+	return KErrNone;
+	}
+
+void CDummyProvd::Ioctl(TUint /*level*/,TUint name,TDes8* anOption)
+	{
+	switch (name)
+		{
+		case KDummyIoctlCheckBound:
+			if (!iIsBound)
+				Panic(ENotBound);
+			iSocket->IoctlComplete(NULL);
+			break;
+		case KDummyIoctlCheckStarted:
+			if (!iProtocol->IsStarted())
+				Panic(ENotStarted);
+			iSocket->IoctlComplete(NULL);
+			break;
+		case KDummyIoctlIgnore:
+			iCancelIoctl=EFalse;
+			break;
+		case KDummyIoctlCancelled:
+			if(iCancelIoctl)
+				{
+				iSocket->IoctlComplete(NULL);
+				}
+			else
+				{
+				iSocket->Error(KErrNotFound,MSocketNotify::EErrorIoctl);
+				}
+			break;
+		case KDummyIoctlPanicProtocolModule:
+			Panic(ETestPanic);
+			iSocket->IoctlComplete(NULL); //Should never get here
+			break;
+		case KDummyIocltNonCompleting: //Ioclt never send back a complete message
+			iCompleteIoctl = TRUE;
+			break;
+		case KDummyIoctBlockHardOnClose:
+			iBlockOnClose = TRUE;
+			iSocket->IoctlComplete(NULL);
+			break;
+
+		case KDummyIoctlSlowIoctlReturn:
+			iSocket->IoctlComplete(NULL);
+			User::After(100000);
+			break;
+		case KDummyIoctlHangIoctlReturn:
+			iSocket->IoctlComplete(NULL);
+			HangModule();
+			break;
+		case KDummyIocltJustComplete:
+			iSocket->IoctlComplete(NULL);
+			break;
+		case KDummyIocltRemoteDisconnect:
+			if (anOption)
+				{
+				TBuf8<40> tmp(*anOption);
+				iSocket->Disconnect(tmp);
+				}
+			else
+				{
+				iSocket->Disconnect();
+				}
+			iSocket->IoctlComplete(NULL);
+			break;
+		
+		case KDummyIoctlCompleteWithData:
+			{
+			TBuf8<64> ioctlBuffer(KIoctlData());
+			iSocket->IoctlComplete(	&ioctlBuffer );	
+			}
+			
+			break;
+		default:
+			iSocket->Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
+		}
+	}
+
+void CDummyProvd::CancelIoctl(TUint /*aLevel*/,TUint /*aName*/)
+	{
+	iCancelIoctl=ETrue;
+	}
+
+TInt CDummyProvd::Write(RMBufChain& aData,TUint aOptions, TSockAddr*)
+	{
+	if (iFlowOffWriteTimeout > 0)
+		{
+		__ASSERT_DEBUG(iFlowOffWriteTimeout, User::Panic(KSpecAssert_ESockTestPDUMMY, 4));
+		iFlowOnTimer->After(iFlowOffWriteTimeout);
+		return 0;
+		}
+
+	if (iFlowOffWrite)
+		return 0;
+
+	if (aOptions==KSockWriteUrgent)
+		{
+		iSocket->Error(KErrNotSupported);
+		return 0;
+		}
+	if (iErrorForNextWrite != KErrNone)
+		{
+		iSocket->Error(iErrorForNextWrite, MSocketNotify::EErrorSend);
+		iErrorForNextWrite = KErrNone;
+		return 0;
+		}
+
+	// From opposite angle, we dont need a new chain if it is a stream
+	// we just append to the existing, unless there isn't an existing...
+	if(iDataArray->Count()==0 || IsTransportType(KSockDatagram))
+		{
+		RMBufChain chain;
+		TRAPD(ret, iDataArray->AppendL(chain));
+		if(ret!=KErrNone)
+			return ret;
+		}
+
+	iDataArray->At(iDataArray->Count()-1).Append(aData);
+
+	// Gotta save the length of the chain before calling
+	// NewData, as it could be changed after the call
+	// (We need to be re-entrant).
+	TInt consumed;
+	if(IsTransportType(KSockStream))
+		{
+		consumed = iDataArray->At(iDataArray->Count()-1).Length();
+		}
+	else
+		{
+		consumed = 1;
+		}
+
+	if(!iInputStopped)
+		{
+		if(IsTransportType(KSockDatagram))
+			iSocket->NewData(1);
+		else
+			iSocket->NewData(consumed);
+		}
+
+	return consumed;
+	}
+
+TUint CDummyProvd::Write(const TDesC8& aDesc, TUint options, TSockAddr* anAddr)
+	{
+	if (iFlowOffWriteTimeout > 0)
+		{
+		__ASSERT_DEBUG(iFlowOffWriteTimeout, User::Panic(KSpecAssert_ESockTestPDUMMY, 5));
+		iFlowOnTimer->After(iFlowOffWriteTimeout);
+		return 0;
+		}
+
+	if (iFlowOffWrite)
+		return 0;
+
+	RMBufChain chain;
+	TRAPD(r,chain.CreateL(aDesc));
+	if (r != KErrNone)
+		{
+		return r;
+		}
+
+	TInt ret = Write(chain, options, anAddr);
+	if (ret<0)
+		{
+		return 0;
+		}
+	return ret;
+	}
+
+TBool CDummyProvd::IsTransportType(TUint aType)
+	{
+	TServerProtocolDesc info;
+	iProtocol->Identify(&info);
+	return (info.iSockType==aType);
+	}
+
+void CDummyProvd::GetData(TDes8& aDesc,TUint aOptions,TSockAddr* aAddr)
+	{
+	RMBufChain chain;
+	GetData(chain,aDesc.MaxLength(),aOptions, aAddr);
+	aDesc.SetMax();
+	chain.CopyOut(aDesc);
+	chain.Free();
+	}
+
+TInt CDummyProvd::GetData(RMBufChain& aData,TUint aLength, TUint aOptions,TSockAddr* aAddr)
+	{
+	__ASSERT_DEBUG(iDataArray->Count()>0, User::Panic(KSpecAssert_ESockTestPDUMMY, 6));
+	TInt res = KErrNone;
+
+	// If KSockReadPeek we copy the whole bally lot instead of moving it out.
+	if((aOptions&KSockReadPeek)==KSockReadPeek)
+		{
+		TInt err;
+		// For datagram, copy all datagram else copy just aLength
+		if(!IsTransportType(KSockDatagram))
+			{
+			TRAP(err, iDataArray->At(0).CopyL(aData, 0, aLength));
+//			iDataArray->At(0).TrimStart(aLength);
+			}
+		else
+			{
+			TRAP(err, iDataArray->At(0).CopyL(aData));
+//			iDataArray->At(0).TrimStart(aData.Length());
+			}
+		if(res==KErrNone)
+			{
+			iSocket->NewData(1);
+			}
+		else
+			{
+			iDataArray->At(0).Free();
+			}
+		}
+	else // Not KSockReadPeek
+		{
+		// Move datablock to receiving chain
+		aData.Assign(iDataArray->At(0));
+
+		// For non-datagram types exact only amount of bytes
+		// if they have more than asked for
+		// so we move some of the data back to our array
+		if( !IsTransportType(KSockDatagram) &&
+			(((TUint)aData.Length())>aLength) )
+			{
+			// Put the tail back into our array for another good time
+			TRAP(res, aData.SplitL(aLength, iDataArray->At(0)));
+			// If it didnt work, save data internally again and return error
+			if(res!=KErrNone)
+				{
+				iDataArray->At(0).Assign(aData);
+				}
+			}
+		}
+
+	// No errors? Return number of bytes copied (stream) or 1 (dgram)
+	if(res==KErrNone)
+		{
+		if(IsTransportType(KSockStream))
+			{
+			res = aData.Length();
+			}
+		else
+			{
+			res = 1;
+			}
+		}
+	else // else report mbuf shortage
+		{
+		res=KErrNoMBufs;
+		}
+
+	// Cleanup possibly unused chain
+	if(iDataArray->At(0).Length()==0)
+		iDataArray->Delete(0);
+	
+	// Copy the TSockAddr if requested
+	if ( aAddr )
+		{
+		const TUint KProxyAddrFamily=0x20000;		
+		TSockAddr addr(KProxyAddrFamily);
+		aAddr->Copy(addr);
+		}
+	return res;
+	}
+
+
+void CDummyProvd::ActiveOpen(void)
+	{
+	if (iErrorForNextConnect != KErrNone)
+		{
+		iSocket->Error(iErrorForNextConnect, MSocketNotify::EErrorConnect);
+		iErrorForNextConnect = KErrNone;
+		return;
+		}
+	if (iConnectCompleteState)
+		{
+		iSocket->ConnectComplete();
+		}
+	else
+		{
+		if(iListenData.Length())
+			{
+			iListenData.Close();
+			}
+		iConnectPending = ETrue;
+		}
+	}
+
+void CDummyProvd::ActiveOpen(const TDesC8& aConnectionData)
+	{
+		if (iErrorForNextConnect != KErrNone)
+		{
+		iSocket->Error(iErrorForNextConnect, MSocketNotify::EErrorConnect);
+		iErrorForNextConnect = KErrNone;
+		return;
+		}
+	if (iConnectCompleteState)
+		{
+		iSocket->ConnectComplete(aConnectionData);
+		}
+	else
+		{
+		if(iListenData.Length())
+			{
+			iListenData.Close();
+			}
+		iListenData.Create(aConnectionData);
+		iConnectPending = ETrue;
+		}
+	}
+
+TInt CDummyProvd::PassiveOpen(TUint /*aQue*/)
+	{
+//	test.Printf(_L("CDummyProvd::Open\n"));
+	if(iListenErrorCode)
+		{// We're going to error this call, but can't do it synchonously.
+		// Do it with an AO of max prio, so we know it will happen next
+//		iSocket->Error(iListenErrorCode);// Error all operations
+		__ASSERT_DEBUG(!iAsyncErrorer, User::Panic(KSpecAssert_ESockTestPDUMMY, 7));	// to support multiple outstanding would need a list
+		TRAPD(err, iAsyncErrorer = CAsyncSocketErrorer::NewL(*iSocket,iListenErrorCode,MSocketNotify::EErrorConnect,0,this,NULL));
+		iListenErrorCode=KErrNone;
+		return err;
+		}
+	return KErrNone;
+	}
+
+TInt CDummyProvd::PassiveOpen(TUint /*aQue*/, const TDesC8& aConnectionData)
+	{
+	iListenData.Close();
+	TInt ret = iListenData.Create(aConnectionData);
+	if (ret != KErrNone)
+		{
+		return ret;
+		}
+		if(iListenErrorCode)
+		{// We're going to error this call, but can't do it synchonously.
+		// Do it with an AO of max prio, so we know it will happen next
+//		iSocket->Error(iListenErrorCode);// Error all operations
+		__ASSERT_DEBUG(!iAsyncErrorer, User::Panic(KSpecAssert_ESockTestPDUMMY, 8));	// to support multiple outstanding would need a list
+		TRAPD(err, iAsyncErrorer = CAsyncSocketErrorer::NewL(*iSocket, iListenErrorCode, MSocketNotify::EErrorConnect, 0, this, &aConnectionData));
+		iListenErrorCode=KErrNone;
+		return err;
+		}
+	return KErrNone;
+	}
+
+
+void CDummyProvd::Shutdown(TCloseType anOption)
+	{
+	if (iErrorForNextShutdown != KErrNone)
+		{
+		iSocket->Error(iErrorForNextShutdown, MSocketNotify::EErrorClose);
+		iErrorForNextShutdown = KErrNone;
+		return;
+		}
+	if (iBlockOnClose)
+		{
+		HangModule();
+		}
+	DestroyAsyncErrorer();
+
+	if(anOption==EStopInput)
+		iInputStopped=ETrue;
+	if(anOption==EStopOutput)
+		{
+
+		TInt c = iDataArray->Count();
+		TInt i;
+		for (i=0; i < c; ++i)
+			{
+			iDataArray->At(i).Free();
+			}
+		iDataArray->Reset();
+
+
+		_LIT8(KEndOfData, "End of Data");
+		RMBufChain datachain;
+		TRAPD(res, iDataArray->AppendL(datachain));
+
+		if(res!=KErrNone)
+			iSocket->Error(KErrNoMemory);
+		else
+			{
+			TRAPD(res, iDataArray->At(0).CreateL(KEndOfData));
+
+			if(res!=KErrNone)
+				iSocket->Error(KErrNoMemory);
+			else
+				{
+				if(IsTransportType(KSockDatagram))
+					{
+					iSocket->NewData(1);
+					}
+				else
+					{
+					iSocket->NewData(iDataArray->At(0).Length());
+					}
+				iSocket->NewData(KNewDataEndofData);
+				}
+			}
+		}
+	if (anOption==ENormal)
+		iSocket->CanClose();
+	}
+
+void CDummyProvd::Start()
+//
+//
+//
+	{
+	}
+
+void CDummyProvd::Shutdown(TCloseType /*anOption*/,const TDesC8 &/*aDisconnectData*/)
+	{
+	Panic(EBadCall);
+	}
+
+void CDummyProvd::AutoBind( void )
+	{
+//	test.Printf(_L("CDummyProvd::AutoBind\n"));
+	iIsBound=ETrue;
+
+	}
+void CDummyProvd::HangModule(void)
+	{
+	TInt val;
+	TInt shutdownVal;
+	RProperty hangProp;
+	TRequestStatus hangStat;
+
+	hangProp.Attach(KDummyUid,KDummyTerminationProperty);
+	hangProp.Subscribe(hangStat);
+	hangProp.Get(shutdownVal);
+	val = shutdownVal + 1;
+	hangProp.Set(val);
+
+	while (val > shutdownVal)
+		{
+		User::WaitForRequest(hangStat);
+		hangProp.Subscribe(hangStat);
+		hangProp.Get(val);
+		}
+	hangProp.Set(shutdownVal - 1);
+	hangProp.Cancel();
+	User::WaitForRequest(hangStat);
+	hangProp.Close();
+	}
+
+//
+
+TInt CDummyProvd::SecurityCheck(MProvdSecurityChecker* /*aChecker*/)
+/**
+Perform a security policy check on the client process (default implementation).
+*/
+	{
+	return KErrNone;
+	}
+
+
+//---------------------------------------------------------------------------------------------------------
+
+#pragma warning( default : 4100)
+
+CDatagramHostResolver::CDatagramHostResolver()
+//
+//
+//
+	{
+	__DECLARE_NAME(_S("CDatagramHostResolver"));
+	}
+
+CDatagramHostResolver::~CDatagramHostResolver()
+{
+    delete ipDNSQueryProcessor;
+}
+
+CDatagramHostResolver* CDatagramHostResolver::NewL()
+//
+// Make a new resolver
+//
+	{
+
+      CDatagramHostResolver* self = new(ELeave) CDatagramHostResolver();
+
+      CleanupStack::PushL(self);
+      self->ConstructL();
+      CleanupStack::Pop();
+
+      return  self;
+	}
+
+void CDatagramHostResolver::ConstructL()
+{
+    //-- construct DNS Query processor
+    ipDNSQueryProcessor = CDNSQueryProcessor::NewL();
+}
+
+void CDatagramHostResolver::CancelCurrentOperation()
+//
+//
+//
+	{
+	    //-- cancel possible pending DNS Query processor request
+        if(ipDNSQueryProcessor)
+            ipDNSQueryProcessor->Cancel();
+	}
+
+
+void CDatagramHostResolver::GetByName(TNameRecord &aName)
+//
+//
+//
+	{
+
+	if(aName.iName==_L("DontComplete"))
+		return;
+
+	aName.iAddr.SetFamily(KDummyAddrFamily);
+	aName.iAddr.SetPort(0);
+	if(aName.iFlags==0)
+		{
+		aName.iName=_L("Name One");
+		aName.iFlags=0;
+		iNotify->QueryComplete(KErrNone);
+		}
+	else if(aName.iFlags==1)
+		{
+		aName.iName=_L("Name Two");
+		aName.iFlags=0;
+		iNotify->QueryComplete(KErrNone);
+		}
+	else if(aName.iFlags==4)
+		{
+		aName.iName=_L("Name Five");
+		aName.iFlags=0;
+		iNotify->QueryComplete(KErrNone);
+		}
+	else
+		iNotify->QueryComplete(KErrEof);
+	}
+
+void CDatagramHostResolver::GetByAddress(TNameRecord &aName)
+//
+//
+//
+	{
+
+	aName.iName=_L("");
+	if(aName.iFlags==0)
+		{
+		aName.iAddr.SetPort(10);
+		aName.iFlags=0;
+		iNotify->QueryComplete(KErrNone);
+		}
+	else if(aName.iFlags==1)
+		{
+		aName.iAddr.SetPort(11);
+		aName.iFlags=0;
+		iNotify->QueryComplete(KErrNone);
+		}
+	else
+		iNotify->QueryComplete(KErrEof);
+	}
+
+void CDatagramHostResolver::SetHostName(TDes & aNameBuf)
+//
+//
+//
+	{
+	if(aNameBuf!=_L("Tara"))
+		iNotify->QueryComplete(KErrNotSupported);
+	else
+		iNotify->QueryComplete(KErrNone);
+	}
+
+void CDatagramHostResolver::GetHostName(TDes &aNameBuf)
+//
+//
+//
+	{
+	aNameBuf=_S("PDummyHostName");
+	iNotify->QueryComplete(KErrNone);
+	}
+
+/**
+*   Implementation "Query" function for CHostResolver. Simulates Query(...) behaviour, checks query data validity
+*   and forges query response that shall be checked at client side.
+*
+* @param    aQryBuf  descriptor representing query data.
+* @param    aResBuf  descriptor representing query response data.
+* @param    aCounter query sequential number counter. From the client's point of view it will be 0 for "Query" call
+*           and increased by 1 for each "QueryGetNext" call.
+* @note     for aCounter > 0 data in aQryBuf may be invalid.
+*/
+void CDatagramHostResolver::Query(const TDesC8& aQryBuf, TDes8& aResBuf, TInt aCounter)
+{
+
+    //-- convert 1st parameter to the reference to TDnsQuery.
+    //-- Actually, for pdummy.prt and tcpip6.prt aQryBuf is a reference to the TDnsQueryBuf indeed,
+    //-- but for the RHostresolver and CHostResolver protocol independency all the data passes like references to
+    //-- the raw buffers.
+    const TDnsQuery &dnsQry = * (reinterpret_cast<const TDnsQuery*> (aQryBuf.Ptr()));
+
+    //-- set Query proccessor notifier.
+    //-- On request completion Query processor will call iNotify->QueryComplete();
+    ipDNSQueryProcessor->SetNotifier(iNotify);
+
+    //-- process and complete query, calling iNotify->QueryComplete() later
+    ipDNSQueryProcessor->ProcessQuery(dnsQry, aResBuf, aCounter);
+}
+
+
+TInt CDatagramHostResolver::SetOption(TUint /*aLevel*/, TUint /*aName*/, const TDesC8 &/*anOption*/)
+//
+//
+//
+	{
+	return (KErrNotSupported);
+	}
+
+
+
+TInt CDatagramHostResolver::SecurityCheck(MProvdSecurityChecker* /*aChecker*/)
+/**
+Perform a security policy check on the client process (default implementation).
+*/
+	{
+	return KErrNone;
+	}
+
+CDatagramServResolver::CDatagramServResolver()
+//
+//
+//
+	{
+	__DECLARE_NAME(_S("CDatagramServResolver"));
+	}
+
+CDatagramServResolver* CDatagramServResolver::NewL()
+//
+//
+//
+	{
+	return new(ELeave) CDatagramServResolver;
+	}
+
+void CDatagramServResolver::CancelCurrentOperation()
+//
+//
+//
+	{
+	// were always synchronous so don't actually do anything
+	}
+
+void CDatagramServResolver::GetByName(const TDesC & aNameBuf,TInt32 & aPortNum)
+
+//
+//
+//
+	{
+
+	if(aNameBuf!=_L("DummyName"))
+		{
+		iNotify->QueryComplete(KErrNotFound);
+		return;
+		}
+	aPortNum=64;
+	iNotify->QueryComplete(KErrNone);
+	}
+
+void CDatagramServResolver::GetByNumber(TDes & aNameBuf,TInt32 aPortNum)
+//
+//
+//
+	{
+
+	if(aPortNum==66) // for testing cancel
+		{
+		return;
+		}
+
+	if(aPortNum!=21)
+		{
+		iNotify->QueryComplete(KErrNotFound);
+		return;
+		}
+	aNameBuf=_S("DummyService");
+	iNotify->QueryComplete(KErrNone);
+	}
+
+void CDatagramServResolver::RegisterService(const TDesC & aNameBuf,TInt32 aPortNum)
+//
+// Register a new service with the net database
+//
+	{
+
+	if(aNameBuf!=_L("Simpson") || aPortNum!=500)
+		{
+		iNotify->QueryComplete(KErrNotFound);
+		return;
+		}
+	iNotify->QueryComplete(KErrNone);
+	}
+
+void CDatagramServResolver::RemoveService(const TDesC & aNameBuf,TInt32 aPortNum)
+//
+// remove a service registered with the database
+//
+	{
+
+	if(aNameBuf!=_L("Colt") || aPortNum!=45)
+		{
+		iNotify->QueryComplete(KErrNotFound);
+		return;
+		}
+	iNotify->QueryComplete(KErrNone);
+	}
+
+
+TInt CDatagramServResolver::SecurityCheck(MProvdSecurityChecker* /*aChecker*/)
+/**
+Perform a security policy check on the client process (default implementation).
+*/
+	{
+	return KErrNone;
+	}
+//---------------------------------------------------------------------------------------------------------
+
+CDNSQueryProcessor::CDNSQueryProcessor()
+                   :CActive(0)
+{
+    iDnsNotifier    = NULL;
+    iCompleteResult = KErrNotSupported;
+
+    //-- initialize seed for random delay generator
+    TTime currTime;
+    currTime.UniversalTime();
+    iRndSeed = currTime.Int64();
+}
+
+CDNSQueryProcessor::~CDNSQueryProcessor()
+{
+    Cancel();
+    iDelayTimer.Close();
+}
+
+CDNSQueryProcessor* CDNSQueryProcessor::NewL()
+{
+    CDNSQueryProcessor* self = new(ELeave) CDNSQueryProcessor;
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+
+    return self;
+}
+
+void CDNSQueryProcessor::ConstructL(void)
+{
+    User::LeaveIfError(iDelayTimer.CreateLocal());
+    CActiveScheduler::Add(this);
+}
+
+void CDNSQueryProcessor::DoCancel()
+{
+    iDelayTimer.Cancel();
+}
+
+void CDNSQueryProcessor::RunL()
+{
+  //-- complete esock's request
+  if(iDnsNotifier)
+    iDnsNotifier->QueryComplete(iCompleteResult);
+}
+
+/**
+* cancels pending request and completes with aResultCode
+*
+* @param    aResultCode completion code, which will be passed to the Esock
+*/
+void  CDNSQueryProcessor::CompleteImmediately(TInt aResultCode)
+{
+    iCompleteResult = aResultCode;
+    CompleteImmediately();
+}
+
+/**
+* cancels pending request and completes with code iCompleteResult
+*/
+void  CDNSQueryProcessor::CompleteImmediately()
+{
+    Cancel();
+
+    SetActive();
+
+    TRequestStatus* pStat = &iStatus;
+    User::RequestComplete(pStat, iCompleteResult);
+}
+
+/**
+* set up timer for a random delay between KMinDelay and KMaxDelay
+* Used to similate queries processing
+*/
+void CDNSQueryProcessor::SetQryProcessDelay()
+{
+    const TInt KMinDelay = 200000; //-- minimal delay, 200 ms
+    const TInt KMaxDelay = 600000; //-- maximal delay, 600 ms
+
+    iDelayTimer.Cancel();
+    iDelayTimer.After(iStatus, KMinDelay+(Math::Rand(iRndSeed) % (KMaxDelay-KMinDelay)));
+}
+
+
+/**
+* process query. Checks query type and calls appropriate query processor function.
+* @param    aQry       ref. to the query data
+* @param    aResBuf    descriptor representing query response data. Will be initialized here.
+* @param    aCounter   queries counter. It is 0 for "Query" call and increased each "QueryGetNext" call
+*/
+void CDNSQueryProcessor::ProcessQuery(const TDnsQuery& aQry, TDes8& aResBuf, TInt aCounter)
+{
+
+    if(aCounter < 0)
+    {//-- invalid parameter
+     CompleteImmediately(KErrCorrupt);
+     return;
+    }
+
+    if(aCounter == 0)
+    {//-- this is the "Query" call, not "QueryGetNext()", store query type for future use
+     iCurrQryType = aQry.Type();
+    }
+
+    switch(iCurrQryType)
+    {
+
+        case KDnsRRTypeA:
+            //-- process query of A type, treating aResBuf as a reference to TDnsRespABuf
+             if((TUint)aResBuf.MaxSize() < sizeof(TDnsRespABuf))
+             {  //-- there is no room in aResBuf to place there TDnsRespSRV structure
+                CompleteImmediately(KErrNoMemory);
+             }
+             else
+             {
+                aResBuf.SetLength(sizeof(TDnsRespA));
+                //-- use placement new operator to construct object of our class in the chunk of memory
+                //-- in aResBuf (which is already allocated by server)
+                TDnsRespA *pRespA = new((TAny*)aResBuf.Ptr())TDnsRespA;
+                QryProcessA(aQry, *pRespA, aCounter);   //-- process query and complete request.
+             }
+        break;
+
+        case KDnsRRTypeSRV:
+             //-- process query of SRV type, treating aResBuf as a reference to TDnsRespSRVBuf
+             if((TUint)aResBuf.MaxSize() < sizeof(TDnsRespSRVBuf))
+             {  //-- there is no room in aResBuf to place there TDnsRespSRV structure
+                CompleteImmediately(KErrNoMemory);
+             }
+             else
+             {
+                aResBuf.SetLength(sizeof(TDnsRespSRV));
+                //-- use placement new operator to construct object of our class in the chunk of memory
+                //-- in aResBuf (which is already allocated by server)
+                //-- aResBuf shall be considered as a TPckgBuf<TDnsRespSRV>, we will also need to set a length of the aResBuf descriptor
+				TDnsRespSRV    *pRespSRV = new((TAny*)aResBuf.Ptr())TDnsRespSRV;
+                QryProcessSRV(aQry, *pRespSRV, aCounter);//-- process query and complete request.
+
+
+             }
+
+        break;
+
+
+        case KDnsRRTypePTR:
+            //-- process query of PTR type, treating aResBuf as a reference to TDnsRespPTRBuf
+             if((TUint)aResBuf.MaxSize() < sizeof(TDnsRespPTRBuf))
+             {  //-- there is no room in aResBuf to place there TDnsRespPTRBuf structure
+                CompleteImmediately(KErrNoMemory);
+             }
+             else
+             {
+                aResBuf.SetLength(sizeof(TDnsRespPTR));
+
+                TDnsRespPTR    *pRespPTR = new((TAny*)aResBuf.Ptr())TDnsRespPTR;
+                QryProcessPTR(aQry, *pRespPTR, aCounter);//-- process query and complete request.
+
+             }
+        break;
+
+        case KDnsRRTypeNAPTR:
+            //-- process query of NAPTR type, treating aResBuf as a reference to TDnsRespNAPTRBuf
+             if((TUint)aResBuf.MaxSize() < sizeof(TDnsRespNAPTRBuf))
+             {  //-- there is no room in aResBuf to place there TDnsRespNAPTRBuf structure
+                CompleteImmediately(KErrNoMemory);
+             }
+             else
+             {
+                aResBuf.SetLength(sizeof(TDnsRespNAPTR));
+
+                TDnsRespNAPTR    *pRespNAPTR = new((TAny*)aResBuf.Ptr())TDnsRespNAPTR;
+                QryProcessNAPTR(aQry, *pRespNAPTR, aCounter);//-- process query and complete request.
+             }
+        break;
+
+        case KDnsRRTypeMX:
+            //-- process query of MX type, treating aResBuf as a reference to TDnsRespMXBuf
+             if((TUint)aResBuf.MaxSize() < sizeof(TDnsRespMXBuf))
+             {  //-- there is no room in aResBuf to place there TDnsRespMXBuf structure
+                CompleteImmediately(KErrNoMemory);
+             }
+             else
+             {
+                aResBuf.SetLength(sizeof(TDnsRespMX));
+
+                TDnsRespMX    *pRespMX  = new((TAny*)aResBuf.Ptr())TDnsRespMX;
+                QryProcessMX(aQry, *pRespMX, aCounter);//-- process query and complete request.
+             }
+        break;
+
+
+        case KDnsRRTypeAAAA:
+            //-- process query of AAAA type, treating aResBuf as a reference to TDnsRespAAAABuf
+             if((TUint)aResBuf.MaxSize() < sizeof(TDnsRespAAAABuf))
+             {  //-- there is no room in aResBuf to place there TDnsRespMXBuf structure
+                CompleteImmediately(KErrNoMemory);
+             }
+             else
+             {
+                aResBuf.SetLength(sizeof(TDnsRespAAAA));
+
+                TDnsRespAAAA    *pRespAAAA = new((TAny*)aResBuf.Ptr())TDnsRespAAAA;
+                QryProcessAAAA(aQry, *pRespAAAA, aCounter);//-- process query and complete request.
+             }
+        break;
+
+
+        default:
+            //-- Query of unknown type
+            CompleteImmediately(KErrNotSupported);
+        break;
+    } // switch
+
+}
+
+/**
+* process A query. Checks query data and forges query result.
+* @param aQry       ref. to the A query data
+* @param aQryResult ref. to the destination query result buffer.
+* @param aCounter   - queries counter. It is 0 for "Query" call and increased each "QueryGetNext" call
+*/
+void CDNSQueryProcessor::QryProcessA(const TDnsQuery& aQry, TDnsRespA& aQryResult, TInt aCounter)
+{
+    TInetAddr   addr;
+
+    switch(aCounter)
+    {
+        //-- query counter is 0, so it is "Query" call
+        case 0:
+
+            //-- check query data, it shall be set properly in the test case that calls RHostResolver::Query(...)
+            if( aQry.Class() != KDnsRRClassIN  ||  //-- Query class shall be IN
+                aQry.Type()  != KDnsRRTypeA    ||  //-- Query type shall be KDnsRRTypeA
+                aQry.Data().CompareF(_L8("http://www.sample.net/")) != 0
+              )
+            {
+                CompleteImmediately(KErrCorrupt);
+                return;
+            }
+
+            //-- resolve domain name, forge "A" query result that will be checked on the client side.
+            addr.Input(_L("192.168.40.4"));
+
+            aQryResult.SetHostAddress(addr);
+            aQryResult.SetRRTtl(0x121212);
+
+            SetCompletionCode(KErrNone);
+
+            //-- simulate processing random delay and complete the request later
+            SetQryProcessDelay();
+            SetActive();
+
+        break;
+
+        //-- query counter is 1, so it is the first "QueryGetNext" call.
+        case 1:
+
+            //-- resolve domain name, forge "A" query result that will be checked on the client side.
+            addr.Input(_L("177.123.221.251"));
+
+            aQryResult.SetHostAddress(addr);
+            aQryResult.SetRRTtl(0x112233);
+
+            SetCompletionCode(KErrNone);
+
+            //-- simulate processing random delay and complete the request later
+            SetQryProcessDelay();
+            SetActive();
+
+        break;
+
+
+        default:
+            //-- query counter is greater than 0, let's not support more than one "QueryGetNext" call
+            CompleteImmediately(KErrNotFound);
+        break;
+
+    }
+
+}
+
+/**
+* process SRV query. Checks query data and forges query result.
+* @param aQry       ref. to the SRV query data
+* @param aQryResult ref. to the destination query result buffer.
+* @param aCounter   - queries counter. It is 0 for "Query" call and increased each "QueryGetNext" call
+*/
+void  CDNSQueryProcessor::QryProcessSRV   (const TDnsQuery& aQry, TDnsRespSRV& aQryResult, TInt aCounter)
+{
+
+    switch(aCounter)
+    {
+        case 0: //-- query counter is 0, so it is "Query" call
+
+            //-- check query data, it shall be set properly in the test case that calls RHostResolver::Query(...)
+            //-- see also RFC 2782
+
+            if(aQry.Class() != KDnsRRClassIN || //-- Query class shall be IN
+               aQry.Type() != KDnsRRTypeSRV  || //-- Query type shall be KDnsRRTypeSRV
+               aQry.Data().CompareF(_L8("_ldap._tcp.example.com")) != 0)
+            {
+                CompleteImmediately(KErrCorrupt);
+                return;
+            }
+
+            //-- forge a SRV query result that will be checked on the client side.
+            aQryResult.SetRRTtl(0x123456);
+
+            aQryResult.SetPriority(384);              //-- priority
+            aQryResult.SetWeight(784);                //-- weight
+            aQryResult.SetPort(123);                  //-- port
+            aQryResult.SetTarget(_L8("old-slow-box"));//-- target
+
+            SetCompletionCode(KErrNone);
+
+            //-- simulate processing random delay and complete the request later
+            SetQryProcessDelay();
+            SetActive();
+        break;
+
+        case 1:
+            //-- query counter is 1, so it is the first "QueryGetNext" call.
+            //-- Forge a "SRV" query next result that will be checked on the client side.
+            aQryResult.SetRRTtl(0x123765);
+
+            aQryResult.SetPriority(236);              //-- priority
+            aQryResult.SetWeight(962);                //-- weight
+            aQryResult.SetPort(125);                  //-- port
+            aQryResult.SetTarget(_L8("new-fast-box"));//-- target
+
+            SetCompletionCode(KErrNone);
+
+            //-- simulate processing random delay and complete the request later
+            SetQryProcessDelay();
+            SetActive();
+       break;
+
+        default:
+            //-- query counter is greater than 0, let's not support more than one "QueryGetNext" call
+            CompleteImmediately(KErrNotFound);
+        break;
+    }// switch
+}
+
+/**
+* process PTR query. Checks query data and forges query result.
+* @param aQry       ref. to the PTR query data
+* @param aQryResult ref. to the destination query result buffer.
+* @param aCounter   - queries counter. It is 0 for "Query" call and increased each "QueryGetNext" call
+*/
+void  CDNSQueryProcessor::QryProcessPTR   (const TDnsQuery& aQry, TDnsRespPTR& aQryResult, TInt aCounter)
+{
+    switch(aCounter)
+    {
+        case 0: //-- query counter is 0, so it is "Query" call
+           {
+
+            //-- check query data, it shall be set properly in the test case that calls RHostResolver::Query(...)
+            if(aQry.Class() != KDnsRRClassIN || //-- Query class shall be IN
+               aQry.Type() != KDnsRRTypePTR)    //-- Query type shall be KDnsRRTypePTR
+            {
+                CompleteImmediately(KErrCorrupt);
+                return;
+            }
+
+            //-- check  Inet Address passes by test from client side
+            const TInetAddr& inetAddr = (const TInetAddr&)aQry.Data();
+
+            TInetAddr expInetAddr;
+            expInetAddr.Input(_L("192.111.22.77"));
+
+            if(! inetAddr.CmpAddr(expInetAddr))
+            {
+                CompleteImmediately(KErrCorrupt);
+                return;
+            }
+
+            //-- resolve address, forge "PTR" query result that will be checked on the client side.
+            aQryResult.SetHostName(_L8("http://www.CDatagramHostResolver_QryProcessPTR.response/"));
+            aQryResult.SetRRTtl(0x223441);
+
+            SetCompletionCode(KErrNone);
+
+            //-- simulate processing random delay and complete the request later
+            SetQryProcessDelay();
+            SetActive();
+           }
+        break;
+
+        default:
+            //-- query counter is greater than 0, let's not support more than one "QueryGetNext" call
+            CompleteImmediately(KErrNotFound);
+        break;
+
+    }
+
+}
+
+/**
+* process NAPTR query. Checks query data and forges query result.
+* @param aQry       ref. to the NAPTR query data
+* @param aQryResult ref. to the destination query result buffer.
+* @param aCounter   - queries counter. It is 0 for "Query" call and increased each "QueryGetNext" call
+*/
+void  CDNSQueryProcessor::QryProcessNAPTR (const TDnsQuery& aQry, TDnsRespNAPTR& aQryResult, TInt aCounter)
+{
+    switch(aCounter)
+    {
+        case 0: //-- query counter is 0, so it is "Query" call
+           {
+
+            //-- check query data, it shall be set properly in the test case that calls RHostResolver::Query(...)
+            if(aQry.Class() != KDnsRRClassIN    ||  //-- Query class shall be IN
+               aQry.Type() != KDnsRRTypeNAPTR   ||  //-- Query type shall be KDnsRRTypeNAPTR
+               aQry.Data().CompareF(_L8("http://www.foo_bar.ru/")) != 0)
+            {
+                CompleteImmediately(KErrCorrupt);
+                return;
+            }
+
+
+            //-- forge "NAPTR" query result that will be checked on the client side.
+            aQryResult.SetRRTtl(0x2673411);
+            aQryResult.SetOrder(123);
+            aQryResult.SetPref(99);
+
+            aQryResult.SetFlags(_L8("SAUP"));
+            aQryResult.SetService(_L8("http+I2R"));
+            aQryResult.SetRegexp(_L8("!£%^^&($%£$~~## !!!!!"));
+            aQryResult.SetReplacement(_L8("www.next-name.it"));
+
+            SetCompletionCode(KErrNone);
+
+            //-- simulate processing random delay and complete the request later
+            SetQryProcessDelay();
+            SetActive();
+           }
+        break;
+
+        default:
+            //-- query counter is greater than 0, let's not support more than one "QueryGetNext" call
+            CompleteImmediately(KErrNotFound);
+        break;
+
+    }
+
+}
+
+/**
+* process MX query. Checks query data and forges query result.
+* @param aQry       ref. to the MX query data
+* @param aQryResult ref. to the destination query result buffer.
+* @param aCounter   - queries counter. It is 0 for "Query" call and increased each "QueryGetNext" call
+*/
+void  CDNSQueryProcessor::QryProcessMX    (const TDnsQuery& aQry, TDnsRespMX& aQryResult, TInt aCounter)
+{
+    switch(aCounter)
+    {
+        case 0: //-- query counter is 0, so it is "Query" call
+           {
+            //-- check query data, it shall be set properly in the test case that calls RHostResolver::Query(...)
+
+            if(aQry.Class() != KDnsRRClassIN || //-- Query class shall be IN
+               aQry.Type() != KDnsRRTypeMX   || //-- Query type shall be KDnsRRTypeMX
+               aQry.Data().CompareF(_L8("http://www.gooooooogle.ru/")) != 0)
+            {
+                CompleteImmediately(KErrCorrupt);
+                return;
+            }
+
+
+            //-- forge "MX" query result that will be checked on the client side.
+            aQryResult.SetRRTtl(0xdead);
+
+            aQryResult.SetPref(345);
+            aQryResult.SetHostName(_L8("c.example.org"));
+
+            SetCompletionCode(KErrNone);
+
+            //-- simulate processing random delay and complete the request later
+            SetQryProcessDelay();
+            SetActive();
+           }
+        break;
+
+        default:
+            //-- query counter is greater than 0, let's not support more than one "QueryGetNext" call
+            CompleteImmediately(KErrNotFound);
+        break;
+
+    }
+
+}
+
+/**
+* process AAAA query. Checks query data and forges query result.
+* @param aQry       ref. to the AAAA query data
+* @param aQryResult ref. to the destination query result buffer.
+* @param aCounter   - queries counter. It is 0 for "Query" call and increased each "QueryGetNext" call
+*/
+void  CDNSQueryProcessor::QryProcessAAAA(const TDnsQuery& aQry, TDnsRespAAAA& aQryResult, TInt aCounter)
+{
+    TInetAddr   addr;
+
+    switch(aCounter)
+    {
+        case 0: //-- query counter is 0, so it is "Query" call
+           {
+
+            //-- check query data, it shall be set properly in the test case that calls RHostResolver::Query(...)
+            if(aQry.Class() != KDnsRRClassIN ||
+               aQry.Type() != KDnsRRTypeAAAA ||
+               aQry.Data().CompareF(_L8("http://www.sample_AAAA.net/")) != 0)
+            {
+                CompleteImmediately(KErrCorrupt);
+                return;
+            }
+
+            //-- forge "AAAA" query result that will be checked on the client side.
+
+            //-- resolve domain name, forge "A" query result that will be checked on the client side.
+            addr.Input(_L("2001:618:400:6a:0:0:0:abc"));
+            aQryResult.SetHostAddress(addr);
+            aQryResult.SetRRTtl(0xbeef);
+
+            SetCompletionCode(KErrNone);
+
+            //-- simulate processing random delay and complete the request later
+            SetQryProcessDelay();
+            SetActive();
+           }
+        break;
+
+        default:
+            //-- query counter is greater than 0, let's not support more than one "QueryGetNext" call
+            CompleteImmediately(KErrNotFound);
+        break;
+
+    }
+
+}
+
+
+//---------------------------------------------------------------------------------------------------------
+
+void CDatagramNetDataBase::Query(TDes8& aBuffer)
+//
+// Ctor
+//
+	{
+	aBuffer.Capitalize();
+	iNotify->QueryComplete(KErrNone);
+	}
+
+void CDatagramNetDataBase::Add(TDes8& aBuffer)
+//
+// Ctor
+//
+	{
+
+	// Query not completed because its cancelled by the test code
+	if(aBuffer==_L8("Rabbit"))
+		iCount=10;
+	else
+		iNotify->QueryComplete(KErrNotSupported);
+	}
+
+void CDatagramNetDataBase::Remove(TDes8& aBuffer)
+//
+// Ctor
+//
+	{
+
+
+	if(aBuffer==_L8("Rabbit") && iCount==20)
+		iNotify->QueryComplete(KErrNone);
+	else
+		iNotify->QueryComplete(KErrNotFound);
+	}
+
+void CDatagramNetDataBase::CancelCurrentOperation()
+//
+//
+//
+	{
+
+	if(iCount==10)
+		iCount=20;
+	}
+
+CDatagramNetDataBase* CDatagramNetDataBase::NewL()
+//
+// Ctor
+//
+	{
+	return new(ELeave)CDatagramNetDataBase;
+	}
+
+CDatagramNetDataBase::CDatagramNetDataBase()
+//
+// Ctor
+//
+	{
+	__DECLARE_NAME(_S("CDatagramNetDataBase"));
+	}
+
+
+TInt CDatagramNetDataBase::SecurityCheck(MProvdSecurityChecker* /*aChecker*/)
+/**
+Perform a security policy check on the client process (default implementation).
+*/
+	{
+	return KErrNone;
+	}
+
+//---------------------------------------------------------------------------------------------------------
+
+CInterfaceProtocol::CInterfaceProtocol(TServerProtocolDesc* aProtoDesc):CDummyProtocol(aProtoDesc)
+	{
+	iInterfaces.SetOffset(_FOFF(CIfHolder, iLink));
+	}
+
+CInterfaceProtocol::~CInterfaceProtocol()
+//
+// Dtor
+//
+	{
+
+	__ASSERT_DEBUG(iInterfaces.IsEmpty(), Panic(EInterfaceNotDeleted));
+	}
+
+TInt CInterfaceProtocol::GetOption(TUint level,TUint name,TDes8 &anOption,CProtocolBase* /*aSourceProtocol*/)
+//
+// Extra options
+//
+	{
+
+	if(level==KNifOptLevel)
+		{
+		TInt ret;
+
+		if(name==KNifOptGetNifIfUser)
+			{
+			TNifIfUser ifuser;
+			ifuser() = this;
+			anOption.Copy(ifuser);
+			return KErrNone;
+			}
+		else if(name==1)
+			{
+			TRAP(ret, StartAutoInterfaceL();)
+			return ret;
+			}
+		else if(name==2)
+			{
+			if(iInterfaceName.Length())
+				Nif::Stop(iInterfaceName);
+			return KErrNone;
+			}
+		else if(name==3)
+			{
+			TRAP(ret, Nif::StartL(iInterfaceName);)
+			return ret;
+			}
+		else if(name==4)
+			{
+			TNifProgress* p = (TNifProgress*)anOption.Ptr();
+			anOption.SetLength(sizeof(TNifProgress));
+		    TRAP(ret, Nif::ProgressL(*p, iInterfaceName);)
+			return ret;
+			}
+		else if(name==5)
+			{
+			if(iInterfaces.IsEmpty())
+				return KErrNotFound;
+		    Nif::Stop(iInterfaces.First(), iInterfaces.First()->iIf);
+			return KErrNone;
+			}
+		else if(name==6)
+			{
+			if(iInterfaces.IsEmpty())
+				return KErrNotFound;
+			TNifProgress* p = (TNifProgress*)anOption.Ptr();
+			anOption.SetLength(sizeof(TNifProgress));
+		    TRAP(ret, Nif::ProgressL(*p, iInterfaces.First(), iInterfaces.First()->iIf);)
+			return ret;
+			}
+		}
+	return KErrNotSupported;
+	}
+
+void CInterfaceProtocol::StartAutoInterfaceL()
+	{
+
+	// Create holder
+	CIfHolder* h;
+	h = new (ELeave) CIfHolder(*this);
+	CleanupStack::PushL(h);
+	Nif::BindL(*this, h, iInterfaceName);
+	CleanupStack::Pop();
+	}
+
+void CInterfaceProtocol::IfUserBindFailure(TInt, TAny* aId)
+	{
+
+	// Find the interface which went down
+	TDblQueIter<CIfHolder> iter(iInterfaces);
+	CIfHolder* h = 0;
+	while((h=iter++)!=0)
+		{
+		if(aId==h)
+			{
+			delete h;
+			break;
+			}
+		}
+	__ASSERT_ALWAYS(h, Panic(EIdAndNoHolder));
+	}
+
+void CInterfaceProtocol::IfUserNewInterfaceL(CNifIfBase* aIf, TAny* aId)
+	{
+
+	// If Id try to find it
+	CIfHolder* h;
+	if(aId)
+		{
+		TDblQueIter<CIfHolder> iter(iInterfaces);
+		while((h=iter++)!=0)
+			{
+			if(aId==h)
+				break;
+			}
+		__ASSERT_ALWAYS(h, Panic(EIdAndNoHolder));
+		if (h==0)
+			{ // will never get in here as will have panic-ed above
+			h = (CIfHolder*)0xABCD; // keep lint happy
+			}
+		}
+	else // create a new holder
+		h = new (ELeave) CIfHolder(*this);
+
+    h->iIf=aIf;
+	CleanupStack::PushL(h);
+	aIf->BindL(this);
+	CleanupStack::Pop();
+	}
+
+void CInterfaceProtocol::IfUserInterfaceDown(TInt aError, CNifIfBase* aIf)
+	{
+
+	if (aError == KErrLinkConfigChanged)
+		{
+		return;
+		}
+
+	// Interface has gone down so delete it from our records
+	TDblQueIter<CIfHolder> iter(iInterfaces);
+	CIfHolder* h = 0;
+	while((h=iter++)!=0)
+		{
+		if(aIf==h->iIf)
+			{
+			delete h;
+			break;
+			}
+		}
+	__ASSERT_ALWAYS(h, Panic(EIdAndNoHolder));
+	}
+
+CProtocolBase* CInterfaceProtocol::IfUserProtocol()
+	{
+	return this;
+	}
+
+void CInterfaceProtocol::IfUserOpenNetworkLayer()
+	{
+	iInterfaceCount++;
+	Open();
+	}
+
+void CInterfaceProtocol::IfUserCloseNetworkLayer()
+	{
+	iInterfaceCount--;
+	Close();
+	}
+
+TBool CInterfaceProtocol::IfUserIsNetworkLayerActive()
+	{
+	return (RefCount()-iInterfaceCount>0);
+	}
+
+void CInterfaceProtocol::Close()
+	{
+	if(RefCount()-iInterfaceCount<=0)
+      {
+		Nif::NetworkLayerClosed(*this);
+      }
+	CProtocolBase::Close();
+	}
+
+CIfHolder::CIfHolder(CInterfaceProtocol& aProt)
+	{
+	aProt.iInterfaces.AddLast(*this);
+	}
+
+CIfHolder::~CIfHolder()
+	{
+	iLink.Deque();
+	}
+
+