zeroconf/server/src/cresponsehandler.cpp
changeset 14 da856f45b798
equal deleted inserted replaced
12:78fbd574edf4 14:da856f45b798
       
     1 // Copyright (c) 2008-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 // cresponsehandler.cpp
       
    15 // 
       
    16 //
       
    17 /**
       
    18 @file
       
    19 @internalTechnology
       
    20 */
       
    21 
       
    22 //System include 
       
    23 #include <mdns/ccacheentry.h>
       
    24 
       
    25 //User include 
       
    26 #include "cresponsehandler.h"
       
    27 __FLOG_STMT(_LIT8(KComponent,"MDNSServer");)
       
    28 /**
       
    29 Two phase constructor
       
    30 @param aMessageHandler a reference to messagehandler
       
    31 */
       
    32 CResponseHandler* CResponseHandler::NewL(CMessageHandler& aMessageHandler)
       
    33 	{
       
    34 	CResponseHandler* self = new(ELeave) CResponseHandler(aMessageHandler);
       
    35     CleanupStack::PushL(self);
       
    36     self->ConstructL();
       
    37     CleanupStack::Pop();
       
    38     return self;
       
    39 	}
       
    40 
       
    41 /**
       
    42 Destructor
       
    43 */
       
    44 CResponseHandler::~CResponseHandler()
       
    45 	{
       
    46 	__FLOG(_L8("CResponseHandler::~CResponseHandler - Entry"));
       
    47 	iNotifyPtrName.Close();
       
    48 	__FLOG(_L8("CResponseHandler::~CResponseHandler - Exit"));
       
    49 	__FLOG_CLOSE;
       
    50 	}
       
    51 
       
    52 /**
       
    53 Handles any resopnse packet recieved from the mdns port
       
    54 @param response packet
       
    55 @return void
       
    56 */
       
    57 void CResponseHandler::HandleIncomingPacketL(CDnsMessage& aMessage, const TSockAddr& /*aAddr*/)
       
    58 	{
       
    59 	__FLOG(_L8("CResponseHandler::HandleIncomingPacketL - Entry"));
       
    60 	iNotifyPtrName.Close();
       
    61 	// process the answer section, and add to the host and service caches
       
    62 	TInt aCount(aMessage.Header().AnswerCount());
       
    63 	const RPointerArray<CDnsResourceData>& answers = aMessage.Answers();
       
    64 	for (TInt i = 0; i < aCount; ++i)
       
    65 		{
       
    66 		HandlePacketAnswersL(answers[i]);	
       
    67 		}
       
    68 	aCount = aMessage.Header().AdditionalRCount();
       
    69 	const RPointerArray<CDnsResourceData>& additional = aMessage.Additional();
       
    70 	for (TInt i = 0; i < aCount; ++i)
       
    71 		{
       
    72         if(additional[i]!=NULL)            
       
    73 		HandlePacketAnswersL(additional[i]);	
       
    74 		}
       
    75     aCount = aMessage.Header().AuthorityNSCount();
       
    76     const RPointerArray<CDnsResourceData>& authoritative = aMessage.Authorities();
       
    77     for (TInt i = 0; i < aCount; ++i)
       
    78         {
       
    79         if(authoritative[i]!=NULL)
       
    80         HandlePacketAnswersL(authoritative[i]);    
       
    81         }
       
    82 	
       
    83 	if(iNotifyPtrName.Count() > 0 )
       
    84 	    {
       
    85 	    MessageHandler().NotifyNewServiceL(iNotifyPtrName);
       
    86 	    for(TInt i=0 ; i<iNotifyPtrName.Count() ; i++)
       
    87 	        {
       
    88 	        iNotifyPtrName[i].Close();
       
    89 	        }
       
    90 	    iNotifyPtrName.Close();
       
    91 	    }
       
    92 	__FLOG(_L8("CResponseHandler::HandleIncomingPacketL - Exit"));
       
    93 	}
       
    94 
       
    95 /*
       
    96 Constructor
       
    97 */
       
    98 CResponseHandler::CResponseHandler(CMessageHandler& aMessageHandler):CBaseHandler(aMessageHandler)
       
    99 	{
       
   100 	
       
   101 	}
       
   102 	
       
   103 /**
       
   104 Two phasae constructor
       
   105 */
       
   106 void CResponseHandler::ConstructL()
       
   107 	{
       
   108 	__FLOG_OPEN(KMDNSSubsystem, KComponent);
       
   109 	__FLOG(_L8("CResponseHandler::ConstructL - Entry Exit"));
       
   110 	}
       
   111 /*
       
   112  * Based on the type of query response recieved from the network.
       
   113  * it will route the record to particular interface.
       
   114  * @param aResourceData record recieved from the network.
       
   115  */
       
   116 void CResponseHandler::HandlePacketAnswersL(CDnsResourceData* aResourceData)
       
   117 	{
       
   118 	__FLOG(_L8("CResponseHandler::HandlePacketAnswersL - Entry"));
       
   119 	switch(aResourceData->Type())
       
   120 		{
       
   121 			case EDnsType_A:
       
   122 				{
       
   123 				HandleAddrAnswersL(aResourceData);
       
   124 				break;	
       
   125 				}
       
   126 				
       
   127 			case EDnsType_PTR:
       
   128 				{
       
   129 				HandlePTRAnswersL(aResourceData);
       
   130 				break;	
       
   131 				}
       
   132 				
       
   133 			case EDnsType_TXT:
       
   134 				{
       
   135 				HandleTXTAnswersL(aResourceData);
       
   136 				break;	
       
   137 				}
       
   138 				
       
   139 			case EDnsType_AAAA:
       
   140 				{
       
   141 				HandleAAAAAnswersL(aResourceData);
       
   142 				//MessageHandler().DnsCache().Insert();
       
   143 				break;	
       
   144 				}
       
   145 
       
   146 			case EDnsType_SRV:
       
   147 				{
       
   148 				HandleSRVAnswersL(aResourceData);
       
   149 				break;	
       
   150 				}
       
   151 		}
       
   152 	__FLOG(_L8("CResponseHandler::HandlePacketAnswersL - Exit"));
       
   153 	}
       
   154 
       
   155 /**
       
   156 This handles any address content in the answer section .
       
   157 If the cache already contains a address entry with the same name .This will notify the server to change the name.
       
   158 If the cache doesnt contain the entry it will just add this entry in to it.
       
   159 @param aResourceData Contains the answers and nspackets recieved from the mdns port
       
   160 @param aEntry Reference to entry to which record should be added so as to add the same to cache later.
       
   161 @return void 
       
   162 */	
       
   163 void CResponseHandler::HandleAddrAnswersL(CDnsResourceData* aResourceData)
       
   164 	{
       
   165 	__FLOG(_L8("CResponseHandler::HandleAddrAnswersL - Entry"));
       
   166 	CRdTypeA* addrRecord = static_cast<CRdTypeA*>(aResourceData);
       
   167 	CleanupStack::PushL(addrRecord);
       
   168 	TBufC8<100> domainName(addrRecord->Name());
       
   169 	RPointerArray<CCacheEntry> aCacheArray;
       
   170 	TBool isUpdated = EFalse;
       
   171 	TRAPD(error,MessageHandler().DnsCache().FindServiceL(aCacheArray,domainName,EDnsType_A));
       
   172 	if(error == KErrNone && 0 != aCacheArray.Count())
       
   173 		{
       
   174 		const CRdTypeA* addrRecordCEntry = (aCacheArray[0])->AddressRecord();
       
   175 		if(addrRecordCEntry != NULL && addrRecordCEntry->Name().Compare(domainName) == 0)
       
   176 			{
       
   177 			if(aCacheArray[0]->IsAuthoritative())
       
   178 				{
       
   179 				if(addrRecordCEntry->Address() != addrRecord->Address() && addrRecord->IsFlushBitSet())
       
   180 					{
       
   181 					MessageHandler().DnsCache().UpdateCacheL(*addrRecord,EFalse,0);
       
   182 					isUpdated = ETrue;
       
   183 					}
       
   184 				}
       
   185 			else
       
   186 				{
       
   187 				isUpdated = ETrue;
       
   188 				MessageHandler().DnsCache().UpdateCacheL(*addrRecord,EFalse,0);
       
   189 				}
       
   190 							
       
   191 			}
       
   192 			
       
   193 		}
       
   194 		
       
   195 	if (! isUpdated&& 0 != aResourceData->Ttl())
       
   196 		{
       
   197 		// we didn't find it, add a new entry.
       
   198 		MessageHandler().DnsCache().UpdateCacheL(*addrRecord,EFalse,0);
       
   199 		}
       
   200 	aCacheArray.ResetAndDestroy();	
       
   201 	aCacheArray.Close();	
       
   202 	CleanupStack::Pop();//addrRecord
       
   203 	__FLOG(_L8("CResponseHandler::HandleAddrAnswersL - Exit"));
       
   204 	}
       
   205 
       
   206 /*
       
   207  * Handles any PTR records in the answer section.
       
   208  * 1.Updates the cache if not present .
       
   209  * 2.Notitfies the client about the new service availability if registered for it.
       
   210  * @param aResourceData ptr record recieved from the network. 
       
   211  */
       
   212  
       
   213 void CResponseHandler::HandlePTRAnswersL(CDnsResourceData* aResourceData)
       
   214 	{
       
   215 	__FLOG(_L8("CResponseHandler::HandlePTRAnswersL - Entry"));
       
   216 	CRdTypePtr* ptrEntry = static_cast<CRdTypePtr*>(aResourceData);
       
   217 	CleanupStack::PushL(ptrEntry);
       
   218 	TBufC8<100> name(ptrEntry->Name());
       
   219 	RPointerArray<CCacheEntry> aCacheArray;
       
   220 	MessageHandler().DnsCache().FindServiceL(aCacheArray,name,EDnsType_PTR);
       
   221 	TBool isUpdated = EFalse;
       
   222 	for (TInt i =0 ; i< aCacheArray.Count(); i++)
       
   223 		{
       
   224 		if(NULL != aCacheArray[i])
       
   225 			{
       
   226 			const CRdTypePtr* ptrRecord = aCacheArray[i]->PtrRecord();
       
   227 			if(ptrRecord->DomainName().CompareF(ptrEntry->DomainName()) == 0)
       
   228 				{
       
   229 				MessageHandler().DnsCache().UpdateCacheL(*ptrEntry,EFalse,0);
       
   230 				isUpdated = ETrue;
       
   231 				if(aResourceData->Ttl() == 0)
       
   232 				    {
       
   233 				    if(ptrEntry->DomainName().Find(ptrEntry->Name()) != KErrNotFound)
       
   234                         {
       
   235                         RBuf8 temp;
       
   236                         temp.CreateL(ptrEntry->DomainName());
       
   237                         if(iNotifyPtrName.Find(temp) == KErrNotFound)
       
   238                             {
       
   239                             iNotifyPtrName.AppendL(temp);
       
   240                             }
       
   241                         else
       
   242                             {
       
   243                             temp.Close();
       
   244                             }
       
   245                         }
       
   246 				    CRdTypeSrv* srvRecord = static_cast <CRdTypeSrv*>( aCacheArray[i]->ServiceRecord());
       
   247 				    if(srvRecord != NULL)
       
   248 				        {
       
   249 				        srvRecord->SetTtl(0);
       
   250 				        MessageHandler().DnsCache().UpdateCacheL(*srvRecord,EFalse,0);
       
   251 				        }
       
   252 				    CRdTypeTxt* txtRecord = static_cast <CRdTypeTxt*> (aCacheArray[i]->TxtRecord());
       
   253                     if(txtRecord != NULL)
       
   254                         {
       
   255                         txtRecord->SetTtl(0);
       
   256                         MessageHandler().DnsCache().UpdateCacheL(*txtRecord,EFalse,0);
       
   257                         }
       
   258 				    }
       
   259 				
       
   260 				break;	
       
   261 				}
       
   262 			}
       
   263 		}
       
   264 	if(!isUpdated && 0 != aResourceData->Ttl())
       
   265 		{
       
   266 		MessageHandler().DnsCache().UpdateCacheL(*ptrEntry,EFalse,0);	
       
   267 		//Notify the  client about new service
       
   268 		if(ptrEntry->DomainName().Find(ptrEntry->Name()) != KErrNotFound)
       
   269 		    {
       
   270 		    RBuf8 temp;
       
   271 		    temp.CreateL(ptrEntry->DomainName());
       
   272 		    if(iNotifyPtrName.Find(temp) == KErrNotFound)
       
   273                 {
       
   274                 iNotifyPtrName.AppendL(temp);
       
   275                 }
       
   276             else
       
   277                 {
       
   278                 temp.Close();
       
   279                 }
       
   280 		    }
       
   281         }
       
   282 	aCacheArray.ResetAndDestroy();	
       
   283 	aCacheArray.Close();
       
   284 	CleanupStack::Pop(ptrEntry);
       
   285 	__FLOG(_L8("CResponseHandler::HandlePTRAnswersL - Exit"));
       
   286 	}
       
   287 
       
   288 /*
       
   289  * Handles any TXT records in the answer section.
       
   290  * 1.Updates the cache if not present .
       
   291  * @param aResourceData ptr record recieved from the network. 
       
   292  */
       
   293 void CResponseHandler::HandleTXTAnswersL(CDnsResourceData* aResourceData)
       
   294 	{
       
   295 	__FLOG(_L8("CResponseHandler::HandleTXTAnswersL - Entry"));
       
   296 	CRdTypeTxt* txtEntry = static_cast<CRdTypeTxt*>(aResourceData);
       
   297 	CleanupStack::PushL(txtEntry);
       
   298 	RPointerArray<CCacheEntry> aCacheArray;
       
   299 	TBool isUpdated = EFalse;
       
   300 	TRAPD(error,MessageHandler().DnsCache().FindServiceL(aCacheArray,txtEntry->Name(),EDnsType_TXT));
       
   301 	if(error == KErrNone && 0 != aCacheArray.Count() && NULL != aCacheArray[0]->TxtRecord())
       
   302 		{
       
   303 		const CRdTypeTxt* txtRecord = aCacheArray[0]->TxtRecord();
       
   304 		if(NULL != txtRecord && txtRecord->Name().CompareF(txtEntry->Name()) == 0)
       
   305 			{
       
   306 			if(aCacheArray[0]->IsAuthoritative())
       
   307 				{
       
   308 				isUpdated = ETrue;
       
   309 				MessageHandler().DnsCache().UpdateCacheL(*txtEntry,ETrue,0);	
       
   310 				}
       
   311 			else 
       
   312 				{
       
   313 				isUpdated = ETrue;
       
   314 				MessageHandler().DnsCache().UpdateCacheL(*txtEntry,EFalse,0);		
       
   315 				}
       
   316 					
       
   317 			}
       
   318 		}
       
   319 	if(!isUpdated && aResourceData->Ttl() != 0 )
       
   320 		{
       
   321 		MessageHandler().DnsCache().UpdateCacheL(*txtEntry,EFalse,0);
       
   322 		}
       
   323 	RBuf8 temp;
       
   324     temp.CreateL(txtEntry->Name());
       
   325     if(iNotifyPtrName.Find(temp) == KErrNotFound)
       
   326         {
       
   327         iNotifyPtrName.AppendL(temp);
       
   328         }
       
   329     else
       
   330         {
       
   331         temp.Close();
       
   332         }
       
   333 	aCacheArray.ResetAndDestroy();	
       
   334 	aCacheArray.Close();
       
   335 	CleanupStack::Pop();//txtEntry*/
       
   336 	__FLOG(_L8("CResponseHandler::HandleTXTAnswersL - Exit"));
       
   337 	}
       
   338 	
       
   339 void CResponseHandler::HandleAAAAAnswersL(CDnsResourceData* /*aResourceData*/)
       
   340 	{
       
   341 		
       
   342 	}
       
   343 
       
   344 /*
       
   345  * Handles any SRV records in the answer section.
       
   346  * 1.Updates the cache if not present .
       
   347  * @param aResourceData ptr record recieved from the network. 
       
   348  */
       
   349 void CResponseHandler::HandleSRVAnswersL(CDnsResourceData* aResourceData)
       
   350 	{
       
   351 	__FLOG(_L8("CResponseHandler::HandleSRVAnswersL - Entry"));
       
   352 	CRdTypeSrv* srvEntry = static_cast<CRdTypeSrv*>(aResourceData);
       
   353 	CleanupStack::PushL(srvEntry);
       
   354 	RPointerArray<CCacheEntry> cacheArray;
       
   355 	TBool isUpdated = EFalse;
       
   356 	TRAPD(error,MessageHandler().DnsCache().FindServiceL(cacheArray,srvEntry->Name(),EDnsType_SRV));
       
   357 	if(KErrNone == error && cacheArray.Count() != 0 && NULL != cacheArray[0]->ServiceRecord())
       
   358 		{
       
   359 	const CRdTypeSrv* srvRecord = cacheArray[0]->ServiceRecord();
       
   360 	/*if(aResourceData->Ttl() == 0)
       
   361         {
       
   362         if(srvEntry->Name().Find(srvEntry->Target()) != KErrNotFound)
       
   363             {
       
   364             RBuf8 temp;
       
   365             temp.CreateL(srvEntry->Name());
       
   366             if(iNotifyPtrName.Find(temp) == KErrNotFound)
       
   367                 {
       
   368                 iNotifyPtrName.AppendL(temp);
       
   369                 }
       
   370             else
       
   371                 {
       
   372                 temp.Close();
       
   373                 }
       
   374             }
       
   375         CRdTypeSrv* srvRecord = static_cast <CRdTypeSrv*>( cacheArray[i]->ServiceRecord());
       
   376         if(srvRecord != NULL)
       
   377             {
       
   378             srvRecord->SetTtl(0);
       
   379             MessageHandler().DnsCache().UpdateCacheL(*srvRecord,EFalse,0);
       
   380             }
       
   381         CRdTypeTxt* txtRecord = static_cast <CRdTypeTxt*> (aCacheArray[i]->TxtRecord());
       
   382         if(txtRecord != NULL)
       
   383             {
       
   384             txtRecord->SetTtl(0);
       
   385             MessageHandler().DnsCache().UpdateCacheL(*txtRecord,EFalse,0);
       
   386             }
       
   387         }*/
       
   388 		
       
   389 		if(srvRecord->Name().CompareF(srvEntry->Name()) == 0 && srvEntry->IsFlushBitSet())
       
   390 			{
       
   391 			if(cacheArray[0]->IsAuthoritative())
       
   392 				{
       
   393 				isUpdated = ETrue;
       
   394 				MessageHandler().DnsCache().UpdateCacheL(*srvEntry,ETrue,0);
       
   395 				}
       
   396 			else 
       
   397 				{
       
   398 				isUpdated = ETrue;
       
   399 				MessageHandler().DnsCache().UpdateCacheL(*srvEntry,EFalse,0);	
       
   400 				}
       
   401 			}
       
   402 			
       
   403 		}
       
   404 	RBuf8 temp;
       
   405     temp.CreateL(srvEntry->Name());
       
   406     if(iNotifyPtrName.Find(temp) == KErrNotFound)
       
   407         {
       
   408         iNotifyPtrName.AppendL(temp);
       
   409         }
       
   410     else
       
   411         {
       
   412         temp.Close();
       
   413         }
       
   414 	if(!isUpdated && srvEntry->Ttl() != 0)
       
   415 		{
       
   416 		MessageHandler().DnsCache().UpdateCacheL(*srvEntry,EFalse,0);
       
   417 		}
       
   418 	cacheArray.ResetAndDestroy();
       
   419 	cacheArray.Close();
       
   420 	CleanupStack::Pop();//srvEntry	
       
   421 	__FLOG(_L8("CResponseHandler::HandleSRVAnswersL - Exit"));
       
   422 	}	
       
   423