Committing ZeroConf for 10.1 to the FCL.
// 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:
// cmdnsconsistencymgr.cpp
//
//
/**
@file
@internalTechnology
*/
//User include
#include "cmdnscacheconsistencymgr.h"
#include "cmdnscachemanager.h"
#include "cmessagehandler.h"
__FLOG_STMT(_LIT8(KComponent,"MDNSServer");)
const TUint32 KMinActivityCount = 5;//TODO: to Define correct Min Work Count
/*
* Two phase constructor
* @param aActiveCacheMgmtEnabled
* @param aMessageHandler reference to message handler.
*/
CMDNSCacheConsistencyMgr* CMDNSCacheConsistencyMgr::NewL(TBool aActiveCacheMgmtEnabled,CMessageHandler& aMessageHandler)
{
CMDNSCacheConsistencyMgr* self = CMDNSCacheConsistencyMgr::NewLC(aActiveCacheMgmtEnabled,aMessageHandler);
CleanupStack::Pop(self);
return self;
}
/*
* Two phase constructor
* @param aActiveCacheMgmtEnabled
* @param aMessageHandler reference to message handler.
*/
CMDNSCacheConsistencyMgr* CMDNSCacheConsistencyMgr::NewLC(TBool aActiveCacheMgmtEnabled,CMessageHandler& aMessageHandler)
{
CMDNSCacheConsistencyMgr* self = new (ELeave)CMDNSCacheConsistencyMgr(aActiveCacheMgmtEnabled,aMessageHandler);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
/*
* Constructor.
*/
CMDNSCacheConsistencyMgr::CMDNSCacheConsistencyMgr(TBool aActiveCacheMgmtEnabled,CMessageHandler& aMessageHandler)
:CActive(EPriorityStandard),iMessageHandler(aMessageHandler)
{
iActiveCacheMgmtEnabled=aActiveCacheMgmtEnabled;
iWalkInterval= KDefaultCheckInterval;
CActiveScheduler::Add(this);
}
//Destructor
CMDNSCacheConsistencyMgr::~CMDNSCacheConsistencyMgr()
{
__FLOG(_L8("CMDNSCacheConsistencyMgr::~CMDNSCacheConsistencyMgr - Entry"));
iTimer.Close();
__FLOG(_L8("CMDNSCacheConsistencyMgr::~CMDNSCacheConsistencyMgr - Exit"));
__FLOG_CLOSE;
}
/*
* Two phase constructor
*/
void CMDNSCacheConsistencyMgr::ConstructL()
{
__FLOG_OPEN(KMDNSSubsystem, KComponent);
__FLOG(_L8("CMDNSCacheConsistencyMgr::ConstructL - Entry"));
User::LeaveIfError(iTimer.CreateLocal());
__FLOG(_L8("CMDNSCacheConsistencyMgr::ConstructL - Exit"));
}
/*
* Function to stop running the consistemcy manager .
* Cancels all the asynchronous request.
*/
void CMDNSCacheConsistencyMgr::Stop()
{
__FLOG(_L8("CMDNSCacheConsistencyMgr::Stop - Entry"));
Cancel();
__FLOG(_L8("CMDNSCacheConsistencyMgr::Stop - Exit"));
}
/*
* Starts the consistency Manager
* @param aWalkInterval specifies the walk interval in seconds.
*/
void CMDNSCacheConsistencyMgr::Start(TUint aWalkInterval)
{
__FLOG(_L8("CMDNSCacheConsistencyMgr::Start - Entry"));
iWalkInterval = aWalkInterval;
TUint Interval= iWalkInterval*1000000;
//Converted to Microseconds
iTimer.After(iStatus,Interval);
SetActive();
__FLOG(_L8("CMDNSCacheConsistencyMgr::Start - Exit"));
}
/*
* Delay between two Walk thourgh .
* Starts a time to complete the request after an interval mentioned in the iWalkinterval.
* @param aStatus reference to status variable.
*/
void CMDNSCacheConsistencyMgr::Delay(TRequestStatus& aStatus)
{
__FLOG(_L8("CMDNSCacheConsistencyMgr::Delay - Entry"));
TUint Interval= iWalkInterval*1000000;
//Converted to Microseconds
iTimer.After(aStatus,Interval);
SetActive();
__FLOG(_L8("CMDNSCacheConsistencyMgr::Delay - Exit"));
}
/*
* Iterates the cache on each hit
* and sets a delay for the nexthit.
*/
void CMDNSCacheConsistencyMgr::RunL()
{
__FLOG(_L8("CMDNSCacheConsistencyMgr::RunL - Entry"));
IterateCacheL();
Delay(iStatus);
__FLOG(_L8("CMDNSCacheConsistencyMgr::RunL - Exit"));
}
/*
* Handles any leave at RunL
*
*/
TInt CMDNSCacheConsistencyMgr::RunError(TInt aError)
{
__FLOG(_L8("CMDNSCacheConsistencyMgr::RunError - Entry"));
User::LeaveIfError(aError);
return aError;
__FLOG(_L8("CMDNSCacheConsistencyMgr::RunError - Exit"));
}
/*
* Cancels any asynchoronous request.
*/
void CMDNSCacheConsistencyMgr::DoCancel()
{
__FLOG(_L8("CMDNSCacheConsistencyMgr::DoCancel - Entry"));
iTimer.Cancel();
__FLOG(_L8("CMDNSCacheConsistencyMgr::DoCancel - Exit"));
}
/*
* Walk through the cache .Does two function
* 1. Publish any authoritative entries.
* 2. Query for the enteries if not authoritative.
*/
void CMDNSCacheConsistencyMgr::IterateCacheL()
{
__FLOG(_L8("CMDNSCacheConsistencyMgr::IterateCacheL - Entry"));
TBool iterateReset(ETrue);
TBool cacheUpToDate(ETrue);
TInt count = iMessageHandler.DnsCache().NumberOfEntries();
TInt index(0);
for(index=0; index<count;index++)
{
//Fetch the next entry whose ttl has completely expired or 80%
//of ttl has expired
CCacheEntry* entry = iMessageHandler.DnsCache().NextStaleEntry(iActiveCacheMgmtEnabled,iterateReset);
//Reset the iterate flag
iterateReset = EFalse;
__FLOG(_L8("CMDNSCacheConsistencyMgr::IterateCacheL - 1"));
if(entry)
{
if(entry->EntryExpired())
{
if(entry->IsAuthoritative())
{
//Republish the record
//Goodbye packet is sent while the session for publish is closed
CDnsMessage * announcement = CDnsMessage::NewL(0,EFalse);
CleanupStack::PushL(announcement);
if(entry->PtrRecord())
{
entry->PtrRecord()->SetTtl(120);
announcement->AppendAnswerL(entry->PtrRecord()->CloneL());
iMessageHandler.DnsCache().UpdateCacheL(*(entry->PtrRecord()),ETrue,entry->SessionId());
__FLOG(_L8("CMDNSCacheConsistencyMgr::IterateCacheL - 2"));
}
if(entry->ServiceRecord())
{
entry->ServiceRecord()->SetTtl(120);
announcement->AppendAnswerL(entry->ServiceRecord()->CloneL());
iMessageHandler.DnsCache().UpdateCacheL(*(entry->ServiceRecord()),ETrue,entry->SessionId());
__FLOG(_L8("CMDNSCacheConsistencyMgr::IterateCacheL - 3"));
}
if(entry->TxtRecord())
{
entry->TxtRecord()->SetTtl(120);
announcement->AppendAnswerL(entry->TxtRecord()->CloneL());
iMessageHandler.DnsCache().UpdateCacheL(*(entry->TxtRecord()),ETrue,entry->SessionId());
__FLOG(_L8("CMDNSCacheConsistencyMgr::IterateCacheL - 4"));
}
if(entry->AddressRecord())
{
entry->AddressRecord()->SetTtl(120);
announcement->AppendAnswerL(entry->AddressRecord()->CloneL());
iMessageHandler.DnsCache().UpdateCacheL(*(entry->AddressRecord()),ETrue,0);
__FLOG(_L8("CMDNSCacheConsistencyMgr::IterateCacheL - 5"));
}
__FLOG(_L8("CMDNSCacheConsistencyMgr::IterateCacheL - 6"));
iMessageHandler.SendQueryL(announcement,*this);
__FLOG(_L8("CMDNSCacheConsistencyMgr::IterateCacheL - 7"));
CleanupStack::Pop();//announcement
}
else
{
if(!entry->IsAuthoritative())
{
DeleteEntry(entry);
//Query(entry);
}
}
}
cacheUpToDate = EFalse;
}
delete entry;
}
__FLOG(_L8("CMDNSCacheConsistencyMgr::IterateCacheL - Exit"));
}
/*
* Delete the particular entry from the cache.
* @param aEntry cacheentry to be delete.
*/
void CMDNSCacheConsistencyMgr::DeleteEntry(CCacheEntry* aEntry)
{
__FLOG(_L8("CMDNSCacheConsistencyMgr::DeleteEntry - Entry"));
RBuf8 key;
//Extract the key & delete
if(aEntry->AddressRecord())
{
key.CreateL(GetHostName(aEntry));
TInt delError = iMessageHandler.DnsCache().DeleteEntryL(key);//TODO: handle error
}
key.Close();
key.CreateL(GetServiceName(aEntry));
TInt error = iMessageHandler.DnsCache().DeleteEntryL(key);
//Handle error
key.Close();
__FLOG(_L8("CMDNSCacheConsistencyMgr::DeleteEntry - Exit"));
}
/*
* Create a CDnsMessage object to be sent to the network using aEntry.
*
*/
void CMDNSCacheConsistencyMgr::Query(CCacheEntry* aEntry)
{
__FLOG(_L8("CMDNSCacheConsistencyMgr::Query - Entry"));
//Construct DNS Message
CDnsMessage* message = CDnsMessage::NewL(0,ETrue);
CleanupStack::PushL(message);
//Form the Query/Question part of the message
CDnsQuestion* question = CDnsQuestion::NewL();
CleanupStack::PushL(question);
question->SetNameL(GetServiceName(aEntry));
question->SetClass(EDnsClass_IN);
question->SetType(EDnsQType_Any);
//Append the Query to the Message
message->AppendQueryL(question);
if(aEntry->AddressRecord())
message->AppendAnswerL(aEntry->AddressRecord()->CloneL());
if(aEntry->ServiceRecord())
message->AppendAnswerL(aEntry->ServiceRecord()->CloneL());
if(aEntry->TxtRecord())
message->AppendAnswerL(aEntry->TxtRecord()->CloneL());
if(aEntry->PtrRecord())
message->AppendAnswerL(aEntry->PtrRecord()->CloneL());
//Send the query
iMessageHandler.SendQueryL(message,*this);
CleanupStack::Pop();//question
CleanupStack::Pop();//message
__FLOG(_L8("CMDNSCacheConsistencyMgr::Query - Exit"));
}
/*
* @return the hostname for the particular record.
*/
const TDesC8& CMDNSCacheConsistencyMgr::GetHostName(CCacheEntry* aEntry)
{
__FLOG(_L8("CMDNSCacheConsistencyMgr::GetHostName - Entry Exit"));
return aEntry->AddressRecord()->Name();
}
/*
* @param aEntry for which service name is required.
* @return Domain name for the particular service.
*/
const TDesC8& CMDNSCacheConsistencyMgr::GetServiceName(CCacheEntry* aEntry)
{
__FLOG(_L8("CMDNSCacheConsistencyMgr::GetServiceName - Entry"));
if(aEntry->ServiceRecord())
{
return aEntry->ServiceRecord()->Name();
}
else if (aEntry->TxtRecord())
{
return aEntry->TxtRecord()->Name();
}
else if(aEntry->PtrRecord())
{
return aEntry->PtrRecord()->DomainName();
}
else if(aEntry->AddressRecord())
{
return aEntry->AddressRecord()->Name();
}
__FLOG(_L8("CMDNSCacheConsistencyMgr::GetServiceName - Exit"));
}
/*
* Notified for any queries sent .
*/
void CMDNSCacheConsistencyMgr::OnPacketSendL(TInt /*aError*/)
{
__FLOG(_L8("CMDNSCacheConsistencyMgr::OnPacketSendL - Entry"));
//Do nothing
}