--- 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);
}
/**