diff -r bb2423252ea3 -r c1029e558ef5 tcpiputils/dnd/src/dns_sock.cpp --- a/tcpiputils/dnd/src/dns_sock.cpp Wed Sep 15 13:53:10 2010 +0300 +++ b/tcpiputils/dnd/src/dns_sock.cpp Wed Oct 13 16:17:27 2010 +0300 @@ -115,7 +115,7 @@ // Process socket errors TInt HandleError(TInt aReason, const TInetAddr *aServer = NULL); // Close and deactivate the UDP socket for DNS traffic - void DeactivateSocket(TInt aReason); + TBool DeactivateSocket(TInt aReason); // Handle receive compeleted, keep receiver active void RunReader(const TMsgBuf &aMsg, const TInetAddr &aFrom); // Handle send completed, keep sender active (if work to do) @@ -130,6 +130,13 @@ inline void ResetErrorCount() { iErrorCount = 0;} // A link chain used by the CDnsSocket to keep track of multiple writers CDnsSocketWriter *iNext; +#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY + RConnection iAttachedConn; //< The connection on which the DNS socket may be opened on +#endif + + // Network ID associated with the writer; + TInt iNetworkIdofWriter; + inline void SetDeferredDelete() { iDeferredDelete = ETrue; } private: void RunL(); @@ -140,9 +147,7 @@ CDnsSocket &iMaster; //< The connection to the CDnsSocket owning this RSocket iSocket; //< The DNS socket -#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY - RConnection iAttachedConn; //< The connection on which the DNS socket may be opened on -#endif + TUint iDeactivateCount; //< Count number of deactivations (needed in reply processing) TUint iErrorCount; //< Count number of consecutive errors in RunL (read and write) TUint iListen; //< = 1, if socket is listening TCP socket, waiting on accept. @@ -159,6 +164,7 @@ TRequestQueue iWaitQueue; //< Requests waiting for a reply TDnsRequest *iSending; //< The request currently being sent, if non-NULL CDnsSocketReader *iReader; //< The reader object + TBool iDeferredDelete; }; void TDnsRequest::Cancel() @@ -193,9 +199,10 @@ TPtr8 iBuf; //< The current receive buffer }; -CDnsSocketWriter::CDnsSocketWriter(CDnsSocket &aMaster) : CActive(0), iMaster(aMaster) +CDnsSocketWriter::CDnsSocketWriter(CDnsSocket &aMaster) : CActive(0), iMaster(aMaster), iDeferredDelete(EFalse) { LOG(Log::Printf(_L("CDnsSocketWriter[%u]::CDnsSocketWriter([%u])"), this, &aMaster)); + iNetworkIdofWriter = -1; CActiveScheduler::Add(this); TTime seed; @@ -337,6 +344,12 @@ rq->iQueueLink.SetWriter(NULL); rq->Abort(iMaster, KErrCancel); } + if (iDeferredDelete) + { + LOG(Log::Printf(_L("CDnsSocketWriter[%u]::RunReader() deleting itself due to deferred delete"), this)); + delete this; + return; + } } } else @@ -558,13 +571,13 @@ return (mark != iDeactivateCount); } -void CDnsSocketWriter::DeactivateSocket(TInt aReason) +TBool CDnsSocketWriter::DeactivateSocket(TInt aReason) { LOG(Log::Printf(_L("CDnsSocketWriter[%u]::DeactivateSocket() Entry"), this)); if (!iOpened ) { LOG(Log::Printf(_L("CDnsSocketWriter[%u]::DeactivateSocket() return without action"), this)); - return; // Nothing to do if not open + return ETrue; // Nothing to do if not open } // Grab current set of requests away, so that // potentially newly entered requests won't @@ -603,7 +616,13 @@ rq->iQueueLink.SetWriter(0); rq->Abort(iMaster, aReason); } - LOG(Log::Printf(_L("CDnsSocketWriter[%u]::DeactivateSocket() complete"), this)); + if (iRunReader) + { + LOG(Log::Printf(_L("CDnsSocketWriter[%u]::DeactivateSocket() complete and defer delete"), this)); + return EFalse; + } + LOG(Log::Printf(_L("CDnsSocketWriter[%u]::DeactivateSocket() complete and allow delete"), this)); + return ETrue; } // @@ -810,7 +829,8 @@ LOG(Log::Printf(_L("CDnsSocketWriter[%u]::CanUseConnection() currentInfo.NetId = %d "), this, currentInfo.iNetId)); LOG(Log::Printf(_L("CDnsSocketWriter[%u]::CanUseConnection() iMaster.iNetworkId = %d "), this, iMaster.iNetworkId)); - if(currentInfo.iNetId == iMaster.iNetworkId) + //if(currentInfo.iNetId == iMaster.iNetworkId) + if(currentInfo.iNetId == this->iNetworkIdofWriter) { foundConnection = ETrue; break; @@ -932,7 +952,7 @@ iWriter.ResetErrorCount(); iWriter.RunReader(TMsgBuf::Cast(iBuf), iFrom); } - LOG(Log::Printf(_L("<-- CDnsSocketReader[%u]::RunL() -exit- iStatus=%d"), this, iStatus.Int())); + LOG(Log::Printf(_L("<-- CDnsSocketReader[%u]::RunL() -exit-"), this)); } void CDnsSocketReader::DoCancel() @@ -983,26 +1003,91 @@ // // Leaves, if socket cannot be activated */ -void CDnsSocket::ActivateSocketL(TUint aNetworkId) +CDnsSocketWriter * CDnsSocket::ActivateSocketL(TUint aNetworkId) { LOG(Log::Printf(_L("CDnsSocket[%u]::ActivateSocketL([NetId = %d])"), this, aNetworkId)); - - if (iConnected && IsOpened()) - { - LOG(Log::Printf(_L("CDnsSocket[%u]::ActivateSocketL([NetId = %d]) return without action"), this, aNetworkId)); - return; // Already connected, nothing to do - } - - User::LeaveIfError(iSS.Connect()); - iConnected = 1; - iNetworkId = aNetworkId; - - const TInt ret = iWriter->ActivateSocket(); - if (ret != KErrNone) - { - DeactivateSocket(ret); - User::Leave(ret); - } + if(!iConnected) + { + LOG(Log::Printf(_L("CDnsSocket::ActivateSocketL([NetId = %d]) connecting socket server"),aNetworkId)); + User::LeaveIfError(iSS.Connect()); + iConnected = 1; + } + // use default in case of default network ID + if(aNetworkId == 0) + { + LOG(Log::Printf(_L("CDnsSocket::ActivateSocketL([NetId = %d]) using default writer"),aNetworkId)); + if(iWriter->IsOpened()) + { + return iWriter; + } + else + { + const TInt ret = iWriter->ActivateSocket(); + if(ret != KErrNone) + { + DeactivateSocket(ret); + User::Leave(ret); + } + else + { + return iWriter; + } + } + + } + else + { + LOG(Log::Printf(_L("CDnsSocket::ActivateSocketL([NetId = %d]) Looking for"),aNetworkId)); + // Find the appropriate writer for the network Id + CDnsSocketWriter *loopWriter = iWriter; + while (1) + { + if(loopWriter->iNetworkIdofWriter == aNetworkId) + { + LOG(Log::Printf(_L("CDnsSocket::ActivateSocketL([NetId = %d]) found"),aNetworkId)); + if(loopWriter->IsOpened()) + { + return loopWriter; + } + else + { + const TInt ret = loopWriter->ActivateSocket(); + if(ret != KErrNone) + { + DeactivateSocket(ret); + User::Leave(ret); + } + else + { + return loopWriter; + } + } + } + if(loopWriter->iNext == NULL) + { + break; + } + else + { + loopWriter = loopWriter->iNext; + } + } + LOG(Log::Printf(_L("CDnsSocket::ActivateSocketL([NetId = %d]) Creating new"),aNetworkId)); + // create a new writer + loopWriter->iNext = CDnsSocketWriter::NewL(*this, -1); + loopWriter->iNext->iNetworkIdofWriter = aNetworkId; + const TInt ret = loopWriter->iNext->ActivateSocket(); + if(ret != KErrNone) + { + DeactivateSocket(ret); + User::Leave(ret); + } + else + { + return loopWriter->iNext; + } + } + return NULL; } /** @@ -1027,6 +1112,7 @@ aBind.OutputWithScope(tmp); Log::Printf(_L("CDnsSocket[%u]::ActivateSocketL([%S#%d])"), this, &tmp, aBind.Port()); #endif + LOG(Log::Printf(_L("CDnsSocket::ActivateSocketL with address bind"))); iWriter->SetBind(aBind); ActivateSocketL(); } @@ -1106,12 +1192,21 @@ iWriter->iNext = NULL; iWriter->DeactivateSocket(aReason); + LOG(Log::Printf(_L("CDnsSocket::DeactivateSocket Deativatuing other writers"))); while (writer) { CDnsSocketWriter *tmp = writer; writer = tmp->iNext; - tmp->DeactivateSocket(aReason); + LOG(Log::Printf(_L("CDnsSocket::DeactivateSocket calling deactivate socket for writer"))); + TBool allowedToDelete = tmp->DeactivateSocket(aReason); + if (allowedToDelete) + { delete tmp; + } + else + { + tmp->SetDeferredDelete(); + } } // Oops... Should not close if re-activated ---FIX! if (iListening) @@ -1170,17 +1265,27 @@ // @li >= 0, // 16 bits of this value is used as id. */ -void CDnsSocket::Queue(TDnsRequest &aRequest, const TInt aId) +void CDnsSocket::Queue(TDnsRequest &aRequest, CDnsSocketWriter * aWriter, const TInt aId) { - iWriter->Queue(aRequest, aId); + if(aWriter == NULL) + { + // use default + iWriter->Queue(aRequest, aId); + } + else + { + aWriter->Queue(aRequest, aId); + } } // Queue a request for sending with a specific socket // -TInt CDnsSocket::Queue(TDnsRequest &aRequest, const RSocket &aSocket, const TInt aId) +// Though the DNS socket writer instance was passed as part of this function, but not being used as this +// function matches the socket to find the appropriate writer instance +TInt CDnsSocket::Queue(TDnsRequest &aRequest, const RSocket &aSocket, CDnsSocketWriter */* aWriter*/, const TInt aId) { - for (CDnsSocketWriter *writer = iWriter; writer != NULL; writer = writer->iNext) + for (CDnsSocketWriter *writer = iWriter; writer != NULL; writer = writer->iNext) { if (&aSocket == &writer->Socket()) { @@ -1189,6 +1294,7 @@ return KErrNone; } } + return KErrNotFound; } @@ -1204,7 +1310,7 @@ // // @return KErrNone, if queued successfully, or error code if failed. */ -TInt CDnsSocket::Queue(TDnsRequest &aRequest, const TInetAddr &aServer, const TInt aId, const TInt aTTL) +TInt CDnsSocket::Queue(TDnsRequest &aRequest, const TInetAddr &aServer, CDnsSocketWriter * /*aWriter*/, const TInt aId, const TInt aTTL) { // // Locate or create connected Socket reader/writer instance @@ -1248,17 +1354,11 @@ // If a request is not currently queued, this does an implicit // Queue. (a new id is generated). // -// Exceptionally, the request assigns new ID when an incomplete query name -// is iterated to apply multiple domain suffices on -// the interface being used for sending requests -// // @param aRequest the request to be resent. -// @param aRetryWithSuffix flag set to identify retry requests -// on incomplete query names. Defaulted to FALSE */ -void CDnsSocket::ReSend(TDnsRequest &aRequest, TBool aRetryWithSuffix) +void CDnsSocket::ReSend(TDnsRequest &aRequest, CDnsSocketWriter * aWriter) { - Queue(aRequest, (!aRetryWithSuffix && aRequest.IsQueued()) ? aRequest.Id() : -1); + Queue(aRequest, aWriter, aRequest.IsQueued() ? aRequest.Id() : -1); } /**