datacommsserver/esockserver/ssock/SS_SES.CPP
changeset 0 dfb7c4ff071f
child 9 77effd21b2c9
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 1997-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 //
       
    15 
       
    16 #include <ss_std.h>
       
    17 #include <comms-infras/sockmes.h>
       
    18 #include <ss_glob.h>
       
    19 #include "ss_msgs.h"
       
    20 #include <nifman.h>
       
    21 #include <comms-infras/ss_log.h>
       
    22 #include <comms-infras/ss_roles.h>
       
    23 #include "ss_subconn.h"
       
    24 #include <ss_sock.h>
       
    25 #include "SS_rslv.H"
       
    26 #include "SS_conn.H"
       
    27 #include "ss_connectionsession.h"
       
    28 #include <comms-infras/ss_api_ext.h>
       
    29 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    30 #include <es_sock_internal.h>
       
    31 #endif
       
    32 
       
    33 #include "ss_apiext_messages.h"
       
    34 #include <comms-infras/ss_tiermanagerutils.h>
       
    35 
       
    36 #include <comms-infras/ss_nodemessages_internal_esock.h>
       
    37 
       
    38 #include <comms-infras/esockdebugmessages.h>
       
    39 #ifdef SYMBIAN_ZERO_COPY_NETWORKING
       
    40 #include <comms-infras/commsbufpondop.h>
       
    41 #include <comms-infras/commsbufponddbg.h>
       
    42 #else
       
    43 #include <es_mbman.h>
       
    44 #endif // SYMBIAN_ZERO_COPY_NETWORKING
       
    45 #ifdef _DEBUG
       
    46 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
       
    47 // (if it could happen through user error then you should give it an explicit, documented, category + code)
       
    48 _LIT(KSpecAssert_ESockSSockS_SES, "ESockSSockS_SES.");
       
    49 #endif
       
    50 
       
    51 #define MSG_PRM(prmIndex)		(prmIndex)
       
    52 
       
    53 using namespace NetInterfaces;
       
    54 using namespace ESock;
       
    55 //using namespace Elements;
       
    56 using namespace Messages;
       
    57 using namespace Den;
       
    58 using namespace CommsFW;
       
    59 
       
    60 class RNullableMessage : public RMessage2
       
    61 	{
       
    62 public:
       
    63 	void NullHandle() const
       
    64 		{
       
    65 		// Although this casting away of const looks awful it's in keeping with the ability to Complete() const
       
    66 		// messages - perhaps iHandle should have been mutable?
       
    67 		const_cast<RNullableMessage&>(*this).iHandle = 0;
       
    68 		}
       
    69 	};
       
    70 
       
    71 /**
       
    72 Constructor
       
    73 */
       
    74 CSockSession::CSockSession(TUidType aUid, TSessionUniqueId aSessionUniqueId)
       
    75 :	CWorkerSession(aUid, aSessionUniqueId)
       
    76 	{
       
    77 	LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CSockSession(%08x):\tConstructor"), this) );
       
    78 	SocketServer::NewSession();
       
    79 	}
       
    80 
       
    81 /*static*/ CSockSession* CSockSession::NewL(TProcessId aProcessId, TUidType aUid, TSessionUniqueId aSessionUniqueId)
       
    82 	{
       
    83 
       
    84 	CSockSession* self = new (ELeave) CSockSession(aUid, aSessionUniqueId);
       
    85 	CleanupStack::PushL(self);
       
    86 	self->ConstructL(aProcessId);
       
    87 	CleanupStack::Pop(self);
       
    88 	return self;
       
    89 	}
       
    90 
       
    91 void CSockSession::ConstructL(TProcessId aProcessId)
       
    92 	{
       
    93 #ifdef SYMBIAN_TRACE_ENABLE
       
    94 	// Document the owner of the session
       
    95 	TLogTextBuf buf;
       
    96 	buf.Format(_L8("CSockSession %08x:\tConstructL()"), this);
       
    97 	RProcess cliProc;
       
    98 	if (cliProc.Open(aProcessId) == KErrNone)
       
    99 		{
       
   100 		TName cliName = cliProc.Name();
       
   101 		TInt index = cliName.LocateReverse('[');
       
   102 		if (index >= 1)
       
   103 			{
       
   104 			cliName.SetLength(index);
       
   105 			}
       
   106 		TUint processId = cliProc.Id();
       
   107 		iProcessName.Copy(cliName);
       
   108 		buf.AppendFormatIgnoreOverflow(_L8(" pid=%x \"%S\""), processId, &iProcessName);
       
   109 		// Remove the "...[nnn]nnn" clutter from the name stored in the session
       
   110 		// (unless the name happens to begin with "[").
       
   111 		cliProc.Close();
       
   112 		}
       
   113 	LOG(ESockLog::Printf(KESockServerTag, buf) );
       
   114 #endif
       
   115 	CWorkerSession::ConstructL(aProcessId);
       
   116 	}
       
   117 
       
   118 /**
       
   119 Destroy
       
   120 */
       
   121 CSockSession::~CSockSession()
       
   122 	{
       
   123 	LOG( ESockLog::Printf(KESockServerTag, _L8("~CSockSession(%08x):\t\"%S\""), this, &iProcessName) );
       
   124 
       
   125 	if(iOptimalDealer)
       
   126 		{
       
   127 		iOptimalDealer->RemoveEligiblePid(iProcess.Id());
       
   128 		}
       
   129 
       
   130 	SocketServer::SessionClosing();
       
   131 	}
       
   132 
       
   133 CSockManData* CSockSession::SockManGlobals() const
       
   134     {
       
   135     return WorkerThread().SockManGlobals();
       
   136     }
       
   137 
       
   138 TInt CSockSession::CheckPolicy(const TSecurityPolicy& aPolicy, const char *aDiagnostic)
       
   139 /**
       
   140 Check the security policy of a process.
       
   141 Called from a socket or resolver provider to check whether the process conforms to the security policy passed as
       
   142 argument.
       
   143 @see MProvdSecurityChecker
       
   144 */
       
   145 	{
       
   146 	return aPolicy.CheckPolicy(iProcess, aDiagnostic) ? KErrNone : KErrPermissionDenied;
       
   147 	}
       
   148 
       
   149 
       
   150 /**
       
   151  Handle messages for this server. In a few cases the messages will be dealt with accordingly,
       
   152  but in most cases they will be 1) forwarded to seperate player or 2) be handled by ProcessMessageL
       
   153  if the Player is co-resident in this thread.
       
   154  @param aMessage Standard IPC request from client side
       
   155 */
       
   156 void CSockSession::ServiceL(const RMessage2& aMessage)
       
   157 	{
       
   158 	LOG(
       
   159 		TBuf8<64> messName;
       
   160 		ESockLog::IPCMessName((TSockMess) aMessage.Function(), messName);
       
   161 		ESockLog::Printf(KESockServerTag, _L8("CSockSession(%08x):\tServiceL, Message(%08x) [%S] \"%S\" int3=%08x"),
       
   162 				this, aMessage.Handle(), &messName, &iProcessName, SubSessionFromHandle(aMessage.Int3(), TCFSubSessInfo(TCFSubSessInfo::EAny)));
       
   163 		);
       
   164 
       
   165 	const CWorkerThread& owner=WorkerThread();
       
   166 	const CPitBoss& pitBoss = owner.PitBoss();
       
   167 
       
   168 	if(pitBoss.TestImmediateShutdownPresent())
       
   169 		{
       
   170 		User::Leave(KErrServerTerminated);
       
   171 		}
       
   172 
       
   173 	iComplete=ETrue; 		// Whether to complete RMessage2 immediately
       
   174 	iReturn=KErrNone;		// Default return value if completing RMessage2 here
       
   175     iOurMessage = &aMessage;
       
   176 
       
   177 	CWorkerSubSession* ss = NULL;
       
   178 
       
   179 	TWorkerId worker=TWorkerThreadPublicInfo::ENullWorkerId;
       
   180 	const TInt function = aMessage.Function();
       
   181 
       
   182 #if defined(_DEBUG_SOCKET_FUNCTIONS)
       
   183 	if(function != ESSDbgControl && iDebugParking.iNumOutstanding > 0)
       
   184 		{
       
   185 		// Weakness here; if it's a session request then the 4th arg may be random stack junk. Major mitigation is that almost certainly they're in UDEB which gives near-certainty
       
   186 		// of it being the stack fill pattern (eg 0xCCCCCCCC) so a collision is very unlikely to be seen (and only in the few cases where debug parking is employed). To improve this
       
   187 		// need to test whether it's a sub-session operation; reorganising the IPC list will help this
       
   188 		if(iDebugParking.iSubSessHandle == 0 || iDebugParking.iSubSessHandle == aMessage.Int3())
       
   189 			{
       
   190 			User::LeaveIfError(Dealer()->ParkRequest(this, aMessage, CCommonDealer::EDebugParking));
       
   191 			--iDebugParking.iNumOutstanding;
       
   192 			DontCompleteCurrentRequest();
       
   193 			return;
       
   194 			}
       
   195 		}
       
   196 #endif
       
   197 	switch(function)
       
   198         {
       
   199     /* Cases handled without a player */
       
   200     case ESSRequestOptimalDealer:
       
   201      	RequestOptimalDealerL();
       
   202     	break;
       
   203 
       
   204 	case ESSInstallExtension:
       
   205 		LOG(ESockLog::Printf(_L8("WARNING: unsupported function ESSInstallExtension called, CSockSession(%08x)"), this));
       
   206 		SetReturn(KErrNotSupported);
       
   207 		break;
       
   208 
       
   209     case ESSExclusiveMode:
       
   210 		LOG(ESockLog::Printf(_L8("WARNING: unsupported function ESSExclusiveMode called, CSockSession(%08x)"), this));
       
   211 		SetReturn(KErrNone);
       
   212         break;
       
   213 
       
   214     case ESSClearExclusiveMode:
       
   215 		LOG(ESockLog::Printf(_L8("WARNING: unsupported function ESSClearExclusiveMode called, CSockSession(%08x)"), this));
       
   216 		SetReturn(KErrNone);
       
   217         break;
       
   218 
       
   219  	case ESSNumProtocols:
       
   220 		NumProtocolsL();
       
   221 		break;
       
   222 
       
   223 	case ESSProtocolInfo:
       
   224 		ProtocolInfoL();
       
   225 		break;
       
   226 
       
   227 	case ESSProtocolInfoByName:
       
   228 		ProtocolInfoByNameL();
       
   229 		break;
       
   230 
       
   231     /* Cases for a Player to deal with, protocol level */
       
   232 	case ESSProtocolStart:
       
   233 	case ESSProtocolStop:
       
   234 	case ESoCreate:
       
   235 	case ESRCreate:
       
   236 		if(pitBoss.GetWorkerForProtocol(aMessage.Int0(),aMessage.Int1(),aMessage.Int2(), worker))
       
   237 			{
       
   238 			ForwardMessageL(aMessage, TPlayerForwardRequestMsg::NormalCreationFlag(), worker);
       
   239 			}
       
   240 		else
       
   241 			{
       
   242 			ParkIfIndeterminateRequest(aMessage, KErrBadName);
       
   243 			}
       
   244 		break;
       
   245 
       
   246 	case ESoCreateWithConnection:
       
   247 		{
       
   248 		TPckgBuf<TSockOpen> argPkg;
       
   249 		SafeMessage().ReadL(MSG_PRM(0),argPkg);
       
   250 		ss = CConnectionFromHandle(argPkg().iHandle);
       
   251 		if(!ss)
       
   252 		    {
       
   253 		    PanicClient(ESockBadHandle);
       
   254 		    }
       
   255 		else
       
   256 			{
       
   257 			// Forward the message to the connection's (control) thread. It's best placed to decide which of its data threads it really belongs in
       
   258 			ForwardMessageL(aMessage, TPlayerForwardRequestMsg::NormalCreationFlag(), ss->Player().WorkerId());
       
   259 			}
       
   260 		}
       
   261 		break;
       
   262 	case ESoCreateWithSubConnection:
       
   263 		{
       
   264 	    TPckgBuf<TSockOpen> argPkg;
       
   265 	    SafeMessage().ReadL(MSG_PRM(0),argPkg);
       
   266 	    ss = CSubConnectionFromHandle(argPkg().iHandle);
       
   267 	    if (!ss)
       
   268 		    {
       
   269 		    PanicClient(ESockBadHandle);
       
   270 		    }
       
   271 		else
       
   272 			{
       
   273 			// Forward the message to the subconnection's (control) thread. It's best placed to decide which of its data threads it really belongs in
       
   274 			ForwardMessageL(aMessage, TPlayerForwardRequestMsg::NormalCreationFlag(), ss->Player().WorkerId());
       
   275 			}
       
   276 		break;
       
   277 		}
       
   278 	case EHRCreateWithConnection:
       
   279 	case EHRCreate:
       
   280 	case ENDCreate:
       
   281 		if(pitBoss.GetWorkerForProtocol(aMessage.Int0(), KUndefinedSockType, aMessage.Int1(), worker))
       
   282 			{
       
   283 			ForwardMessageL(aMessage, TPlayerForwardRequestMsg::NormalCreationFlag(), worker);
       
   284 			}
       
   285 		else
       
   286 			{
       
   287 			ParkIfIndeterminateRequest(aMessage, KErrBadName);
       
   288 			}
       
   289 		break;
       
   290 
       
   291 	case ESoCreateNull:
       
   292 		// Attempt to pass to co-resident player
       
   293 		if(owner.Player())
       
   294 			{
       
   295 			worker = WorkerId();
       
   296 			}
       
   297 		else
       
   298 			{ // No co-resident player, pass to NullSocket handling player known to PitBoss
       
   299 			VERIFY(pitBoss.GetWorkerForNullSocket(worker));
       
   300 			}
       
   301 		ForwardMessageL(aMessage, TPlayerForwardRequestMsg::NormalCreationFlag(), worker);
       
   302 		break;
       
   303 
       
   304 	case ECNCreate:
       
   305         ForwardTierRequestL(aMessage);
       
   306 		break;
       
   307 
       
   308 	// Connection Messages
       
   309 	case ECNCreateWithName:
       
   310 		{
       
   311 		// The cloned connection must be created on the same [control] Player that owns the original
       
   312 		TName name;
       
   313 		aMessage.ReadL(0, name);
       
   314 		User::LeaveIfError(CSockSubSession::FetchSubSessionFromName(name, TCFSubSessInfo(TCFSubSessInfo::EConnection), owner, ss));
       
   315 		ForwardMessageL(aMessage, *ss);	// can't be indeterminate request; already created the clone source
       
   316 		break;
       
   317 		}
       
   318 
       
   319     /* All else (cases for a Player to deal with, subsession level) */
       
   320 
       
   321 // socket messages
       
   322 
       
   323 	case ESoClose:
       
   324 		CloseSubSessionL(aMessage, TCFSubSessInfo(TCFSubSessInfo::ESocket));
       
   325 		break;
       
   326 
       
   327 	case ESoConnect:
       
   328 	case ESoShutdown:
       
   329 	case ESoSendToNoLength:
       
   330 	case ESoSendNoLength:
       
   331 	case ESoSendTo:
       
   332 	case ESoSend:
       
   333 	case ESoWrite:
       
   334 	case ESoRecvFromNoLength:
       
   335 	case ESoRecvNoLength:
       
   336 	case ESoRecvOneOrMore:
       
   337 	case ESoRecvFrom:
       
   338 	case ESoRecv:
       
   339 	case ESoRead:
       
   340 	case ESoBind:
       
   341 	case ESoAccept:
       
   342 	case ESoListen:
       
   343 	case ESoSetOpt:
       
   344 	case ESoGetOpt:
       
   345 	case ESoIoctl:
       
   346 	case ESoGetDiscData:
       
   347 	case ESoGetLocalName:
       
   348 	case ESoGetRemoteName:
       
   349 	case ESoReference:
       
   350 		ss=CSocketFromHandle(aMessage.Int3());
       
   351 		if (ss)
       
   352 			{
       
   353 			ForwardMessageL(aMessage, *ss);
       
   354 			}
       
   355 		else
       
   356 			{
       
   357 			PanicClient(ESockBadHandle);
       
   358 			}
       
   359 		break;
       
   360 	case ESoCancelRecv:
       
   361 	case ESoCancelSend:
       
   362 	case ESoCancelIoctl:
       
   363 	case ESoCancelConnect:
       
   364 	case ESoCancelAccept:
       
   365 	case ESoCancelAll:
       
   366 		ss=CSocketFromHandle(aMessage.Int3());
       
   367 		if(ss)
       
   368 			{
       
   369 			ForwardMessageL(aMessage, *ss);
       
   370 			}
       
   371 		else
       
   372 			{
       
   373 			LOG(ESockLog::Printf(_L8("CSockSession::ServiceL: BAD ESoCancelAll")));
       
   374 			}
       
   375 		break;
       
   376 
       
   377 	case ESoSocketInfo:
       
   378 		ss=CSocketFromHandle(aMessage.Int3());
       
   379 		if (ss)
       
   380 			{
       
   381 			ForwardMessageL(aMessage, *ss);
       
   382 			}
       
   383 		else
       
   384 			{
       
   385 			SetReturn(KErrBadHandle);
       
   386 			}
       
   387 		break;
       
   388 
       
   389 	case ESoTransfer:
       
   390 		TransferSocketL();
       
   391 		break;
       
   392 
       
   393 // Host resolver message types
       
   394 
       
   395 	case EHRClose:
       
   396 		CloseSubSessionL(aMessage, TCFSubSessInfo(TCFSubSessInfo::EHostResolver));
       
   397 		break;
       
   398 
       
   399 	case EHRCancel:
       
   400 		ss=CHostResolverFromHandle(aMessage.Int3());
       
   401 		if (ss)
       
   402 			{
       
   403 			ForwardMessageL(aMessage, *ss);
       
   404 			}
       
   405 		else
       
   406 			{
       
   407 			LOG( ESockLog::Printf(_L8("CSockSession::ServiceL: BAD EHRCancel")) );
       
   408 			}
       
   409 		break;
       
   410 
       
   411     case EHRGetByName:
       
   412 	case EHRNext:
       
   413 	case EHRGetByAddress:
       
   414 	case EHRGetHostName:
       
   415 	case EHRSetHostName:
       
   416 	case EHrQuery:
       
   417 	case EHrQueryNext:
       
   418 	case EHRSetOpt:
       
   419 		ss=CHostResolverFromHandle(aMessage.Int3());
       
   420 		if (ss)
       
   421 			{
       
   422 			ForwardMessageL(aMessage, *ss);
       
   423 			}
       
   424 		else
       
   425 			{
       
   426 			PanicClient(ESockBadHandle);
       
   427 			}
       
   428 		break;
       
   429 
       
   430 // Service resolver message types
       
   431 
       
   432 	case ESRClose:
       
   433 		CloseSubSessionL(aMessage, TCFSubSessInfo(TCFSubSessInfo::EServiceResolver));
       
   434 		break;
       
   435 
       
   436 	case ESRGetByName:
       
   437 	case ESRGetByNumber:
       
   438 	case ESRRegisterService:
       
   439 	case ESRRemoveService:
       
   440 		ss=CServiceResolverFromHandle(aMessage.Int3());
       
   441 		if (ss)
       
   442 			{
       
   443 			ForwardMessageL(aMessage, *ss);
       
   444 			}
       
   445 		else
       
   446 			{
       
   447 			PanicClient(ESockBadHandle);
       
   448 			}
       
   449 		break;
       
   450 	case ESRCancel:
       
   451 		ss=CServiceResolverFromHandle(aMessage.Int3());
       
   452 		if (ss)
       
   453 			{
       
   454 			ForwardMessageL(aMessage, *ss);
       
   455 			}
       
   456 		else
       
   457 			{
       
   458 			LOG( ESockLog::Printf(_L8("CSockSession::ServiceL: BAD ESRCancel")) );
       
   459 			}
       
   460 		break;
       
   461 
       
   462 // Net database message types
       
   463 
       
   464 	case ENDClose:
       
   465 		CloseSubSessionL(aMessage, TCFSubSessInfo(TCFSubSessInfo::ENetDatabase));
       
   466 		break;
       
   467 
       
   468 	case ENDQuery:
       
   469 	case ENDAdd:
       
   470 	case ENDRemove:
       
   471 		ss=CNetDatabaseFromHandle(aMessage.Int3());
       
   472 		if (ss)
       
   473 			{
       
   474 			ForwardMessageL(aMessage, *ss);
       
   475 			}
       
   476 		else
       
   477 			{
       
   478 			PanicClient(ESockBadHandle);
       
   479 			}
       
   480 		break;
       
   481 	case ENDCancel:
       
   482 		ss=CNetDatabaseFromHandle(aMessage.Int3());
       
   483 		if (ss)
       
   484 			{
       
   485 			ForwardMessageL(aMessage, *ss);
       
   486 			}
       
   487 		else
       
   488 			{
       
   489 			LOG( ESockLog::Printf(_L8("CSockSession::ServiceL: BAD ENDCancel")) );
       
   490 			}
       
   491 		break;
       
   492     case ECNClose:
       
   493 		CloseSubSessionL(aMessage, TCFSubSessInfo(TCFSubSessInfo::EConnection));
       
   494 		break;
       
   495 	case ECNStart:
       
   496 	case ECNSetStartPrefs:
       
   497 	case ECNStop:
       
   498 	case ECNReference:
       
   499 	case ECNProgress:
       
   500 	case ECNProgressNotification:
       
   501 	case ECNCancelProgressNotification:
       
   502 	case ECNLastProgressError:
       
   503 	case ECNServiceChangeNotification:
       
   504 	case ECNCancelServiceChangeNotification:
       
   505 	case ECNGetIntSetting:
       
   506 	case ECNGetBoolSetting:
       
   507 	case ECNGetDes8Setting:
       
   508 	case ECNGetDes16Setting:
       
   509 	case ECNGetLongDesSetting:
       
   510 	case ECNEnumerateConnections:
       
   511 	case ECNGetConnectionInfo:
       
   512 	case ECNIoctl:
       
   513 	case ECNCancelIoctl:
       
   514 	case ECNControl:
       
   515 	case ECNAttach:
       
   516 	case ECNAllInterfaceNotification:
       
   517 	case ECNCancelAllInterfaceNotification:
       
   518 	case ECNCancelAllSubConnectionNotification:
       
   519 	case ECNEnumerateSubConnections:
       
   520 	case ECNAllSubConnectionNotification:
       
   521 	case ECNWaitForIncoming:
       
   522 	case ECNCancelWaitForIncoming:
       
   523 
       
   524 	case ESCPSStop:
       
   525 	case ESCPSProgressNotification:
       
   526 	case ESCPSCancelProgressNotification:
       
   527 	case ESCPSDataTransferred:
       
   528 	case ESCPSDataTransferredCancel:
       
   529 	case ESCPSDataSentNotificationRequest:
       
   530 	case ESCPSDataSentNotificationCancel:
       
   531 	case ESCPSDataReceivedNotificationRequest:
       
   532 	case ESCPSDataReceivedNotificationCancel:
       
   533 	case ESCPSIsSubConnectionActiveRequest:
       
   534 	case ESCPSIsSubConnectionActiveCancel:
       
   535 
       
   536 	case ESCPSGetSubConnectionInfo:
       
   537 		ss=CConnectionFromHandle(aMessage.Int3());
       
   538 		if (ss)
       
   539 			{
       
   540 			ForwardMessageL(aMessage, *ss);
       
   541 			}
       
   542 		else
       
   543 			{
       
   544 			PanicClient(ESockBadHandle);
       
   545 			}
       
   546 		break;
       
   547 
       
   548 	case ESCCreate:
       
   549 	    {
       
   550     	TPckgBuf<TSubConnOpen> argPkg;
       
   551 	    SafeMessage().ReadL(MSG_PRM(0),argPkg);
       
   552 	    ss=CConnectionFromHandle(argPkg().iHandle);
       
   553 	    if (ss)
       
   554 		    {
       
   555 			ForwardMessageL(aMessage, *ss);
       
   556 		    }
       
   557 		else
       
   558 		    {
       
   559 		    PanicClient(ESockBadHandle);
       
   560 			}
       
   561 		break;
       
   562 		}
       
   563 	case ESCClose:
       
   564 		CloseSubSessionL(aMessage, TCFSubSessInfo(TCFSubSessInfo::ESubConnection));
       
   565 		break;
       
   566 
       
   567 	case ESCAddSocket:
       
   568 	case ESCRemoveSocket:
       
   569 	case ESCSetParameters:
       
   570 	case ESCGetParameters:
       
   571 	case ESCGetParametersLength:
       
   572 	case ESCEventNotificationSetup:
       
   573 	case ESCEventNotification:
       
   574 	case ESCEventAllNotifications:
       
   575 	case ESCEventNotificationCancel:
       
   576 	case ESCControl:
       
   577     case ESCStart:
       
   578     case ESCStop:
       
   579 		ss=CSubConnectionFromHandle(aMessage.Int3());
       
   580 		if (ss)
       
   581 		    {
       
   582 			ForwardMessageL(aMessage, *ss);
       
   583 			}
       
   584 		else
       
   585 		    {
       
   586 			PanicClient(ESockBadHandle);
       
   587 		    }
       
   588 		break;
       
   589 
       
   590 // Server debug messages
       
   591 #if defined (_DEBUG_SOCKET_FUNCTIONS)
       
   592 	case ESSDbgMarkHeap:
       
   593 	case ESSDbgCheckHeap:
       
   594 	case ESSDbgMarkEnd:
       
   595 	case ESSDbgFailNext:
       
   596 	case ESSDbgFailNextMbuf:
       
   597 	case ESSDbgSetMbufPoolLimit:
       
   598 	case ESSDbgCheckMbuf:
       
   599 	case ESSDbgMbufFreeSpace:
       
   600 	case ESSDbgMbufTotalSpace:
       
   601 	case ESSDbgCheckFailNext:
       
   602 	    {
       
   603 		if(!pitBoss.ModuleConfigurationComplete())
       
   604 			{
       
   605 			if (Dealer()->ParkRequest(this, aMessage, CCommonDealer::EIndeterminateDuringBoot) != KErrNone)
       
   606 				{
       
   607 				//Something terrible has just happened.
       
   608 				//We could not park the request.
       
   609 				//Since this is a debug call it is probably a good idea to panic here,
       
   610 				//hopefully providing a chance to see what is going wrong.
       
   611 				__ASSERT_DEBUG(0, User::Panic(KSpecAssert_ESockSSockS_SES, 1));
       
   612 				}
       
   613 			else
       
   614 				{
       
   615 				DontCompleteCurrentRequest();
       
   616 				}
       
   617 			}
       
   618 		else
       
   619 			{
       
   620 			SSDbgFunctionL(aMessage);
       
   621 			}
       
   622 		break;
       
   623         }
       
   624 #endif		// _DEBUG_SOCKET_FUNCTIONS
       
   625 
       
   626 	default:
       
   627 		ss = SubSessionFromHandle(aMessage.Int3(), TCFSubSessInfo(TCFSubSessInfo::EAny));
       
   628 
       
   629 		if(ss)
       
   630 			{
       
   631 			ForwardMessageL(aMessage, *ss);
       
   632 			}
       
   633 		else
       
   634 			{
       
   635 			PanicClient(ESockBadHandle);
       
   636 			}
       
   637 		break;
       
   638 	}
       
   639 
       
   640 	// Message handlers can change the state of the iMessage if they want to hold onto the message.
       
   641 	// They can also write a return value to iReturn.
       
   642 	if (iComplete)
       
   643 		{
       
   644 		LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CSockSession(%08x):\tServiceL, Complete message(%08x) with %d."), this, aMessage.Handle(), iReturn) );
       
   645 		aMessage.Complete(iReturn);
       
   646 		}
       
   647 	}
       
   648 
       
   649 #if defined (_DEBUG_SOCKET_FUNCTIONS)
       
   650 void CSockSession::DispatchDebugMessageL(const RMessage2& aMessage)
       
   651 	{
       
   652 	Elements::RResponseMsg responseMsg(aMessage, aMessage.Int0(), 1, 2);
       
   653 
       
   654 	// Construct our message in place
       
   655 	TBuf8<ESockDebug::KMaxIpcMsgLength> msgDst;
       
   656 	ESockDebug::TControlMsg* msg = static_cast<ESockDebug::TControlMsg*>(responseMsg.ReadClientReqMsg(msgDst));
       
   657 	__ASSERT_ALWAYS(msg, Fault(EDebugSupport));
       
   658 
       
   659 	// Self dispatch our message and return any error code
       
   660 	TPckgBuf<TInt> returnValue;
       
   661 	TInt& debugStatus = returnValue();
       
   662 	debugStatus = msg->DispatchL(this);
       
   663 	SafeMessage(aMessage).WriteL(MSG_PRM(0), returnValue);
       
   664 	}
       
   665 
       
   666 
       
   667 #endif // _DEBUG_SOCKET_FUNCTIONS
       
   668 
       
   669 #if defined (_DEBUG_SOCKET_FUNCTIONS)
       
   670 void CSockSession::SSDbgFunctionL(const RMessage2& aMessage)
       
   671 	{
       
   672 	switch(aMessage.Function())
       
   673 		{
       
   674 		case ESSDbgMarkHeap:
       
   675 			__UHEAP_MARK;
       
   676 			break;
       
   677 		case ESSDbgCheckHeap:
       
   678 			__UHEAP_CHECK(aMessage.Int0());
       
   679 			break;
       
   680 		case ESSDbgMarkEnd:
       
   681 			__UHEAP_MARKENDC(aMessage.Int0());
       
   682 			break;
       
   683 		case ESSDbgFailNext:
       
   684         	{
       
   685 			const CWorkerThread& owner=WorkerThread();
       
   686 			CPitBoss& pitBoss = owner.PitBoss();
       
   687 
       
   688 			// We set the fail point for all heaps, rather than just the current Dealer. This could lead to a failure not related
       
   689 			// directly to whatever the client test code is trying to exercise but it all helps find bugs
       
   690 			pitBoss.SetFailNextForAllHeaps(aMessage.Int0());
       
   691 			break;
       
   692     	    }
       
   693 		case ESSDbgCheckFailNext:
       
   694 			{
       
   695 			// Report whether any heap has ended "FailNext" mode set by ESSDbgFailNext, which generally indicates that some code
       
   696 			// under test hasn't explored all allocation points
       
   697 			const CWorkerThread& owner=WorkerThread();
       
   698 			CPitBoss& pitBoss = owner.PitBoss();
       
   699 			SetReturn(pitBoss.TestFailNextForAllHeaps());
       
   700 			break;
       
   701 			}
       
   702 	// MBuf specific allocation fails and checks.
       
   703 		case ESSDbgFailNextMbuf:
       
   704 			{
       
   705 #ifdef SYMBIAN_ZERO_COPY_NETWORKING			
       
   706 			RCommsBufPond pond=TCommsBufPondTLSOp::Get();
       
   707 			if (pond.IsNull())
       
   708 				{
       
   709 				PanicClient(EMbufManagerNotLoaded);
       
   710 				}
       
   711 			else
       
   712 				{
       
   713 				TCommsBufPondDbg pondDbg(pond); 
       
   714 				pondDbg.__DbgSetFailAfter(aMessage.Int0());
       
   715 				}
       
   716 #else
       
   717           	CMBufManager* mbufMan=CMBufManager::Context();
       
   718             if (mbufMan==NULL)
       
   719 				{
       
   720 			    PanicClient(EMbufManagerNotLoaded);
       
   721 		        }
       
   722 		        else
       
   723 	            {
       
   724                 mbufMan->__DbgSetFailAfter(aMessage.Int0());
       
   725                 }			
       
   726 #endif // SYMBIAN_ZERO_COPY_NETWORKING				
       
   727 			break;
       
   728 			}
       
   729 		case ESSDbgSetMbufPoolLimit:
       
   730 			{
       
   731 #ifdef SYMBIAN_ZERO_COPY_NETWORKING				
       
   732 			RCommsBufPond pond=TCommsBufPondTLSOp::Get();
       
   733 			if (pond.IsNull())
       
   734 				{
       
   735 				PanicClient(EMbufManagerNotLoaded);
       
   736 				}
       
   737 			else
       
   738 				{
       
   739 				TCommsBufPondDbg pondDbg(pond); 
       
   740 				pondDbg.__DbgSetPoolLimit(aMessage.Int0());
       
   741 				}
       
   742 #else
       
   743           	CMBufManager* mbufMan=CMBufManager::Context();
       
   744             if (mbufMan==NULL)
       
   745 				{
       
   746 			    PanicClient(EMbufManagerNotLoaded);
       
   747 		        }
       
   748 		    else
       
   749 		    	{
       
   750 		    	mbufMan->__DbgSetPoolLimit(aMessage.Int0());	
       
   751 		    	}
       
   752 		
       
   753 #endif // SYMBIAN_ZERO_COPY_NETWORKING					
       
   754 			break;
       
   755 			}
       
   756 		case ESSDbgCheckMbuf:
       
   757 			{
       
   758 #ifdef 	SYMBIAN_ZERO_COPY_NETWORKING		
       
   759 			RCommsBufPond pond=TCommsBufPondTLSOp::Get();
       
   760 			if (pond.IsNull())
       
   761 				{
       
   762 				PanicClient(EMbufManagerNotLoaded);
       
   763 				}
       
   764 			else
       
   765 				{
       
   766 				TCommsBufPondDbg pondDbg(pond); 								
       
   767 				if (pondDbg.__DbgGetBufTotal()-pondDbg.__DbgGetBufSpace()!=aMessage.Int0())
       
   768 					{
       
   769 					Fault(EBadMbufCheck);						
       
   770 					}
       
   771 				}
       
   772 #else
       
   773           	CMBufManager* mbufMan=CMBufManager::Context();
       
   774             if (mbufMan==NULL)
       
   775 				{
       
   776 			    PanicClient(EMbufManagerNotLoaded);
       
   777 		        }
       
   778 		    else
       
   779 		    	{
       
   780 				if (mbufMan->__DbgGetBufTotal()-mbufMan->__DbgGetBufSpace()!=aMessage.Int0())
       
   781 						Fault(EBadMbufCheck);
       
   782 		    	}		
       
   783 #endif				
       
   784 			break;
       
   785 			}
       
   786 		case ESSDbgMbufFreeSpace:
       
   787 			{
       
   788 #ifdef 	SYMBIAN_ZERO_COPY_NETWORKING				
       
   789 			RCommsBufPond pond=TCommsBufPondTLSOp::Get();
       
   790 			if (pond.IsNull())
       
   791 				{
       
   792 				PanicClient(EMbufManagerNotLoaded);
       
   793 				}
       
   794 			else
       
   795 				{
       
   796 				TPckgBuf<TInt> c;
       
   797 				TInt& space=c();
       
   798 				TCommsBufPondDbg pondDbg(pond); 	
       
   799 				space=pondDbg.__DbgGetBufSpace();
       
   800 				SafeMessage().WriteL(MSG_PRM(0),c);
       
   801 				}
       
   802 #else
       
   803           	CMBufManager* mbufMan=CMBufManager::Context();
       
   804             if (mbufMan==NULL)
       
   805 				{
       
   806 			    PanicClient(EMbufManagerNotLoaded);
       
   807 		        }
       
   808 		    else
       
   809 		    	{
       
   810 				TPckgBuf<TInt> c;
       
   811 				TInt& space=c();
       
   812 				space=mbufMan->__DbgGetBufSpace();
       
   813 				SafeMessage().WriteL(MSG_PRM(0),c);
       
   814 		    	}		
       
   815 #endif				
       
   816 			break;
       
   817 			}
       
   818 		case ESSDbgMbufTotalSpace:
       
   819 			{
       
   820 #ifdef 	SYMBIAN_ZERO_COPY_NETWORKING			
       
   821 			RCommsBufPond pond=TCommsBufPondTLSOp::Get();
       
   822 			if (pond.IsNull())
       
   823 				{
       
   824 				PanicClient(EMbufManagerNotLoaded);
       
   825 				}
       
   826 			else
       
   827 				{
       
   828 				TPckgBuf<TInt> c;
       
   829 				TInt& size=c();
       
   830 				TCommsBufPondDbg pondDbg(pond); 				
       
   831 				size=pondDbg.__DbgGetBufTotal();
       
   832 				SafeMessage().WriteL(MSG_PRM(0),c);
       
   833 				}
       
   834 #else
       
   835           	CMBufManager* mbufMan=CMBufManager::Context();
       
   836             if (mbufMan==NULL)
       
   837 				{
       
   838 			    PanicClient(EMbufManagerNotLoaded);
       
   839 		        }
       
   840 		    else
       
   841 		    	{
       
   842 				TPckgBuf<TInt> c;
       
   843 				TInt& size=c();
       
   844 				size=mbufMan->__DbgGetBufTotal();
       
   845 				SafeMessage().WriteL(MSG_PRM(0),c);
       
   846 		    	}		
       
   847 #endif //	 SYMBIAN_ZERO_COPY_NETWORKING			
       
   848 			}
       
   849 			break;
       
   850 
       
   851 	// Bad message
       
   852 		default:
       
   853 			PanicClient(ESockBadHandle);
       
   854 		}
       
   855 	}
       
   856 #endif
       
   857 // _DEBUG_SOCKET_FUNCTIONS
       
   858 
       
   859 
       
   860 
       
   861 /**
       
   862 Return a CSocket given a client's handle
       
   863 */
       
   864 CSocket* CSockSession::CSocketFromHandle(TUint aHandle)
       
   865     {
       
   866 	return static_cast<CSocket*>(SubSessionFromHandle(aHandle, TCFSubSessInfo(TCFSubSessInfo::ESocket)));
       
   867     }
       
   868 
       
   869 /**
       
   870 Return a Flow and SCPR CommsIds given a socket's handle
       
   871 */
       
   872 TBool CSockSession::FlowAndSCPRFromSocketHandle(TUint aHandle, Messages::TNodeId& aFlow, Messages::TNodeId& aSCPR)
       
   873     {
       
   874     SubSessions().Lock();
       
   875 
       
   876     TInt found = EFalse;
       
   877 
       
   878 	CSocket* sock = static_cast<CSocket*>(iSubSessions.At(aHandle, TCFSubSessInfo(TCFSubSessInfo::ESocket)));
       
   879 	if (sock)
       
   880     	{
       
   881     	found = sock->GetFlowAndSCPR(aFlow, aSCPR);
       
   882     	}
       
   883 		
       
   884 	SubSessions().Unlock();
       
   885 
       
   886 	return found;
       
   887     }
       
   888 
       
   889 /**
       
   890 Find a CNameResolver from a clients handle
       
   891 */
       
   892 CHostResolver* CSockSession::CHostResolverFromHandle(TUint aHandle)
       
   893     {
       
   894 	return static_cast<CHostResolver*>(SubSessionFromHandle(aHandle, TCFSubSessInfo(TCFSubSessInfo::EHostResolver)));
       
   895     }
       
   896 
       
   897 /**
       
   898 Find a CServiceresolver from a clients handle
       
   899 */
       
   900 CServiceResolver* CSockSession::CServiceResolverFromHandle(TUint aHandle)
       
   901     {
       
   902 	return static_cast<CServiceResolver*>(SubSessionFromHandle(aHandle, TCFSubSessInfo(TCFSubSessInfo::EServiceResolver)));
       
   903     }
       
   904 
       
   905 /**
       
   906 Find a CNetDatabase from a handle
       
   907 */
       
   908 CNetDatabase* CSockSession::CNetDatabaseFromHandle(TUint aHandle)
       
   909     {
       
   910 	return static_cast<CNetDatabase*>(SubSessionFromHandle(aHandle, TCFSubSessInfo(TCFSubSessInfo::ENetDatabase)));
       
   911     }
       
   912 
       
   913 /**
       
   914 Find a CConnection from a handle
       
   915 */
       
   916 ESock::CConnection* CSockSession::CConnectionFromHandle(TUint aHandle)
       
   917     {
       
   918 	return static_cast<ESock::CConnection*>(SubSessionFromHandle(aHandle, TCFSubSessInfo(TCFSubSessInfo::EConnection)));
       
   919     }
       
   920 
       
   921 /**
       
   922 find a CSubConnection from a handle
       
   923 
       
   924 */
       
   925 CSubConnection* CSockSession::CSubConnectionFromHandle(TUint aHandle)
       
   926     {
       
   927 	return static_cast<CSubConnection*>(SubSessionFromHandle(aHandle, TCFSubSessInfo(TCFSubSessInfo::ESubConnection)));
       
   928     }
       
   929 
       
   930 void CSockSession::CloseSubSessionL(const RMessage2& aMessage, TSubSessInfo aType)
       
   931 	{
       
   932 	CWorkerSubSession* subSess = NULL;
       
   933 	
       
   934 		{
       
   935 		SubSessions().Lock();
       
   936 
       
   937 		subSess = iSubSessions.At(aMessage.Int3(), aType);
       
   938 		LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CSockSession(%08x):\tCloseSubSession(%08x, %d) - subSess %08x"), this, aMessage.Int3(), aType.iType, subSess));
       
   939 		if(subSess)
       
   940 			{
       
   941 			VERIFY_RESULT(iSubSessions.Remove(aMessage.Int3()), subSess);
       
   942 			}
       
   943 		
       
   944 		SubSessions().Unlock();
       
   945 		}
       
   946 
       
   947 	if(subSess)
       
   948 		{
       
   949 		ForwardMessageL(aMessage, *subSess);
       
   950 		}
       
   951 	else
       
   952 		{
       
   953 		SetReturn(KErrBadHandle);	// Close() is always safe
       
   954 		}
       
   955 	}
       
   956 
       
   957 
       
   958 /**
       
   959 Search for an optimal dealer. If one is found set the iOptimalDealer member, register
       
   960 the requesting PID on the optimal dealer and return the dealer server name to the client.
       
   961 */
       
   962 void CSockSession::RequestOptimalDealerL()
       
   963 	{
       
   964 	/* Wont accept this if we're shutting down or if we've
       
   965 	already requested optimal dealer (successfully) before */
       
   966 	if(SocketServer::IsShuttingDown())
       
   967 		{
       
   968 		User::Leave(KErrServerTerminated);
       
   969 		}
       
   970 	else if(iOptimalDealer)
       
   971 		{
       
   972 		PanicClient(EConnectingAlready);
       
   973 		}
       
   974 	else // Ok, find optimal dealer and register it with session, tell nice client...
       
   975 		{
       
   976 		TSessionPref pref;
       
   977 		TPckg<TSessionPref> package(pref);
       
   978 		SafeMessage().ReadL(MSG_PRM(0), package);
       
   979 		if(PitBoss().FindOptimalDealer(pref, iOptimalDealer))
       
   980 			{
       
   981 			// Add PID to table of authorised clients.
       
   982 			iOptimalDealer->AddEligiblePidL(iProcess.Id());
       
   983 			SafeMessage().WriteL(MSG_PRM(1), iOptimalDealer->ServerName());
       
   984 			SetReturn(KErrNone);
       
   985 			LOG(ESockLog::Printf(KESockSessDetailTag, _L("CSockSession(%08x):\tRequestOptimalDealerL %S for 0x%X"), this, &iOptimalDealer->ServerName(), static_cast<TUint>(iEligiblePid)) );
       
   986 			}
       
   987 		else
       
   988 			{
       
   989 			LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CSockSession(%08x):\tRequestOptimalDealerL KErrNotFound"), this) );
       
   990 			iOptimalDealer=NULL;
       
   991 			// Optimal Dealer requests don't get parked during boot - there's a risk of creating a hard-to-debug startup deadlock
       
   992 			// which outweighs the performance benefit 
       
   993 			SetReturn(KErrNotFound);
       
   994 			}
       
   995 		}
       
   996 	}
       
   997 
       
   998 /**
       
   999 Determine the owning Player and forward the TransferSocket message to it.
       
  1000 */
       
  1001 void CSockSession::TransferSocketL()
       
  1002 	{
       
  1003 	TName name;
       
  1004 	SafeMessage().ReadL(MSG_PRM(0), name);
       
  1005 	CWorkerSubSession* socket;
       
  1006 	TInt err = CSocket::FetchSubSessionFromName(name, TCFSubSessInfo(TCFSubSessInfo::ESocket), WorkerThread(), socket);
       
  1007 	if(err == KErrNone)
       
  1008 		{
       
  1009 		ForwardMessageL(*iOurMessage, *socket);
       
  1010 		}
       
  1011 	User::Leave(KErrNotFound);	// name bad or Player exited
       
  1012 	}
       
  1013 
       
  1014 /**
       
  1015 Handle a request for the number of loaded protocols.
       
  1016 */
       
  1017 void CSockSession::NumProtocolsL(void)
       
  1018 	{
       
  1019 	if(!PitBoss().ModuleConfigurationComplete())
       
  1020 		{
       
  1021 		ParkIfIndeterminateRequest(Message(), KErrNone);
       
  1022 		}
       
  1023 	else
       
  1024 		{
       
  1025 		TUint num=PitBoss().GetNumProtocols();
       
  1026 		TPtrC8 d((TUint8 *)&num,sizeof(num));
       
  1027 		if (SafeMessage().Write(MSG_PRM(0),d) != KErrNone)
       
  1028 		    {
       
  1029 		    DontCompleteCurrentRequest();
       
  1030 		    }
       
  1031 		}
       
  1032 	}
       
  1033 
       
  1034 /**
       
  1035 Get info for a protocol by index.
       
  1036 */
       
  1037 void CSockSession::ProtocolInfoL(void)
       
  1038 	{
       
  1039 	TWorkerId worker;
       
  1040 	if(!PitBoss().GetWorkerForProtocol(Message().Int1(), worker))
       
  1041 		{
       
  1042 		ParkIfIndeterminateRequest(Message(), KErrNotFound);
       
  1043 		}
       
  1044 	else
       
  1045 		{
       
  1046 		ForwardMessageL(Message(), TPlayerForwardRequestMsg::UnusedParam(), worker);
       
  1047 		}
       
  1048 	}
       
  1049 
       
  1050 /**
       
  1051 Get protocol info by name.
       
  1052 */
       
  1053 void CSockSession::ProtocolInfoByNameL( )
       
  1054 	{
       
  1055 	TProtocolName name;
       
  1056 	SafeMessage().ReadL(MSG_PRM(1),name);
       
  1057 
       
  1058 	TWorkerId worker;
       
  1059 	if(!PitBoss().GetWorkerForProtocolByName(name, worker))
       
  1060 		{
       
  1061 		ParkIfIndeterminateRequest(Message(), KErrNotFound);
       
  1062 		}
       
  1063 	else
       
  1064 		{
       
  1065 		ForwardMessageL(Message(), TPlayerForwardRequestMsg::UnusedParam(), worker);
       
  1066 		}
       
  1067 	}
       
  1068 
       
  1069 /**
       
  1070 Panic the client.
       
  1071 */
       
  1072 void CSockSession::PanicClient(TESockPanic aPanic)
       
  1073 	{
       
  1074 	SafeMessage().PanicClient(KESockClientPanic, (TInt) aPanic);
       
  1075 	DontCompleteCurrentRequest();
       
  1076 	}
       
  1077 
       
  1078 
       
  1079 #ifdef SYMBIAN_NETWORKING_PERFMETRICS
       
  1080 void CSockSession::IncludePerformanceData(TInt aDeltaClientRxBytes, TInt aDeltaClientRxBuffBytes, TInt aDeltaClientTxBytes)
       
  1081 	{
       
  1082 	SockManGlobals()->IncludePerformanceData(aDeltaClientRxBytes, aDeltaClientRxBuffBytes, aDeltaClientTxBytes);
       
  1083 	}
       
  1084 #endif
       
  1085 
       
  1086 /**
       
  1087 Constructor
       
  1088 */
       
  1089 CSockSubSession::CSockSubSession(CSockSession* aSession, CPlayer* aPlayer, const Den::TSubSessionUniqueId aSubSessionUniqueId)
       
  1090 :	CWorkerSubSession(aSession, aPlayer, aSubSessionUniqueId)
       
  1091 	{
       
  1092 	}
       
  1093 
       
  1094 void CSockSubSession::ConstructL(CProtocolBase* aProtocol)
       
  1095 	{
       
  1096 	CWorkerSubSession::ConstructL();
       
  1097 	if(aProtocol)
       
  1098 		{
       
  1099 		CSockSessionProxy* sp = static_cast<CSockSessionProxy*>(SessionProxy());
       
  1100 		sp->AddProtocolL(aProtocol);
       
  1101 		}
       
  1102 	}
       
  1103 
       
  1104 CSockSession* CSockSubSession::Session()
       
  1105 	{
       
  1106 	return static_cast<CSockSession*>(Den::CWorkerSubSession::Session());
       
  1107 	}
       
  1108 
       
  1109 const CSockSession* CSockSubSession::Session() const
       
  1110 	{
       
  1111 	return static_cast<const CSockSession*>(Den::CWorkerSubSession::Session());
       
  1112 	}
       
  1113 
       
  1114 void CSockSubSession::DeleteMe()
       
  1115 	{
       
  1116 	LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CSockSubSession %08x:\tDeleteMe() - iSubSessionUniqueId %08X, iType %d, iSession %08x"), this, iSubSessionUniqueId, Type().iType, iSession) );
       
  1117 
       
  1118 	switch(Type().iType)
       
  1119 		{
       
  1120 		case TCFSubSessInfo::ESocket:
       
  1121 			static_cast<CSocket*>(this)->InitiateDestruction();
       
  1122 			break;
       
  1123 		case TCFSubSessInfo::EHostResolver:
       
  1124 			static_cast<CHostResolver*>(this)->InitiateDestruction();
       
  1125 			break;
       
  1126 		case TCFSubSessInfo::EServiceResolver:
       
  1127 			{
       
  1128 			// Remove the subsession from the session's subsession list.
       
  1129 		    if(iSession)
       
  1130 				{
       
  1131 				iSession->SubSessions().Lock();
       
  1132 
       
  1133 				CSubSessionIx::TSubSessionHandle handle;
       
  1134 				if(iSession->SubSessions().Find(this, handle) == KErrNone)
       
  1135 					{
       
  1136 					iSession->PitBoss().RemoveSubSession(handle, iSession);
       
  1137 					}
       
  1138 				
       
  1139 				iSession->SubSessions().Unlock();
       
  1140 				}
       
  1141 
       
  1142 			delete this;
       
  1143 			}
       
  1144 			break;
       
  1145 		case TCFSubSessInfo::ENetDatabase:
       
  1146 			{
       
  1147 			// Remove the subsession from the session's subsession list.
       
  1148 		    if(iSession)
       
  1149 				{
       
  1150 				iSession->SubSessions().Lock();
       
  1151 
       
  1152 				CSubSessionIx::TSubSessionHandle handle;
       
  1153 				if(iSession->SubSessions().Find(this, handle) == KErrNone)
       
  1154 					{
       
  1155 					iSession->PitBoss().RemoveSubSession(handle, iSession);
       
  1156 					}
       
  1157 				
       
  1158 				iSession->SubSessions().Unlock();
       
  1159 				}
       
  1160 
       
  1161 			delete this;
       
  1162 			}
       
  1163 			break;
       
  1164 		case TCFSubSessInfo::EConnection:
       
  1165 			//Mimic the client sending ECNClose (without RMessage2)
       
  1166 			{
       
  1167 			const TNodeId& c = static_cast<CConnection&>(*this).Id();
       
  1168 			RClientInterface::OpenPostMessageClose(TNodeCtxId(ECNClose, c), TNodeCtxId(ECNClose, c), ESock::TCFInternalEsock::TSubSess(ECNClose,RMessage2()).CRef());
       
  1169 			}
       
  1170 			break;
       
  1171 		case TCFSubSessInfo::ESubConnection:
       
  1172 			//Mimic the client sending ESCClose (without RMessage2)
       
  1173 			{
       
  1174 			const TNodeId& sc = static_cast<CSubConnection&>(*this).Id();
       
  1175 			RClientInterface::OpenPostMessageClose(sc, TNodeCtxId(ESCClose, sc), ESock::TCFInternalEsock::TSubSess(ESCClose,RMessage2()).CRef());
       
  1176 			}
       
  1177 			break;
       
  1178 		default:
       
  1179 			//Please support your new subsession type
       
  1180 			__ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockSSockS_SES, 2));
       
  1181 		}
       
  1182 
       
  1183 	}
       
  1184 
       
  1185 CSockSubSession::~CSockSubSession()
       
  1186 	{
       
  1187 	LOG(ESockLog::Printf(KESockServerTag, _L8("CSockSubSession(%08x):\t~CSockSubSession Session(%08x)"), this, iSession) );
       
  1188 	
       
  1189 	// A subsession has a session proxy unless OOM prevented it
       
  1190 	if(SessionProxy())
       
  1191 		{
       
  1192 		SessionProxy()->NotifySubSessionDestroyed();
       
  1193 		}
       
  1194 	}
       
  1195 
       
  1196 //Default implementation - must be specialised if used
       
  1197 void CSockSubSession::CommsApiExtBindIfaceL(const RMessage2& /*aMessage*/)
       
  1198 	{
       
  1199 	User::Leave(KErrNotSupported);
       
  1200 	}
       
  1201 
       
  1202 //Default implementation - must be specialised if used
       
  1203 void CSockSubSession::CommsApiExtIfaceSendReceiveL(const RMessage2& /*aMessage*/)
       
  1204 	{
       
  1205 	User::Leave(KErrNotSupported);
       
  1206 	}
       
  1207 
       
  1208 //Default implementation - must be specialised if used
       
  1209 void CSockSubSession::CloseExtensionInterface(const RMessage2& /*aMessage*/)
       
  1210 	{
       
  1211 	}
       
  1212 
       
  1213 //Default implementation - must be specialised if used
       
  1214 void CSockSubSession::CancelAndCloseAllClientExtIfaces()
       
  1215 	{
       
  1216 	}
       
  1217 
       
  1218 /** Client request to forwarded to the thread of the tier manager for the given tier. Possibilities:
       
  1219 (1) Mapping of tier to worker thread already known; can forward directly
       
  1220 (2) Mapping unknown & mappings loaded; fail request
       
  1221 (3) Mapping unknown & mappings not yet loaded; park request and request tier resolver to load mappings
       
  1222 (4) Tier resolver not yet located (ie during boot); request parked as indeterminate
       
  1223 
       
  1224 Because only the main thread is guaranteed to have a binding to the tier resolver, the request for
       
  1225 mappings is always made by it, ie a secondary Dealer sends the request to load mappings to it. After
       
  1226 adding the mappings the main thread then messages all other workers to tell them to unpark any requests
       
  1227 awaiting the tier mappings.
       
  1228 
       
  1229 The last thing added is the dummy "tiers loaded" flag, which serves to indicate to Dealers that resolution
       
  1230 is complete.
       
  1231 */
       
  1232 void CSockSession::ForwardTierRequestL(const RMessage2& aMessage)
       
  1233 	{
       
  1234     TWorkerId worker;
       
  1235     TUint family = aMessage.Int0();
       
  1236     TUint protocol = aMessage.Int2();
       
  1237     TUid tierUid = TierManagerUtils::MapTierIdsL(TUid::Uid(family), protocol);
       
  1238     CPitBoss& pitBoss = PitBoss();
       
  1239 	if(pitBoss.GetWorkerForTier(tierUid.iUid, worker))
       
  1240 		{
       
  1241 		//ForwardMessageL(aMessage, reinterpret_cast<CSockSubSession*>(tierUid.iUid), worker);
       
  1242 		ForwardMessageL(aMessage, TPlayerForwardRequestMsg::NormalCreationFlag(), worker); 
       
  1243 		}
       
  1244 	else
       
  1245 		{
       
  1246 		// No mapping found; either it's a bad id or we've yet to load mappings
       
  1247 		TInt err = KErrNone;
       
  1248 		if(PitBoss().TierMappingsLoaded())
       
  1249 			{
       
  1250 			err = KErrBadName;
       
  1251 			}
       
  1252 		else
       
  1253 			{
       
  1254 			err = Dealer()->ParkRequest(this, aMessage, CCommonDealer::EAwaitingTierToWorkerMapping);
       
  1255 			}
       
  1256 		if(err == KErrNone)
       
  1257 			{
       
  1258 			if(WorkerId() != TWorkerThreadPublicInfo::EMainThread)
       
  1259 				{
       
  1260 				TWorkerLoadTierMappings msg;
       
  1261 				WorkerThread().PostMessage(TWorkerThreadPublicInfo::EMainThread, msg);
       
  1262 				}
       
  1263 			else
       
  1264 				{
       
  1265 				PitBoss().RequestLoadTierMapping();
       
  1266 				}
       
  1267 			}
       
  1268 		if(err == KErrNone)
       
  1269 			{
       
  1270 			DontCompleteCurrentRequest();
       
  1271 			}
       
  1272 		else
       
  1273 			{
       
  1274 			SetReturn(err);
       
  1275 			}
       
  1276 		}
       
  1277 	}
       
  1278 
       
  1279 CWorkerThread& CSockSession::WorkerThread() const
       
  1280 	{
       
  1281 	return static_cast<CWorkerThread&>(CWorkerSession::WorkerThread());
       
  1282 	}
       
  1283 
       
  1284 
       
  1285 CPitBoss& CSockSession::PitBoss() const
       
  1286 	{
       
  1287 	return static_cast<CPitBoss&>(CWorkerSession::PitBoss());
       
  1288 	}
       
  1289 
       
  1290 void CSockSession::Disconnect(const RMessage2& aMessage)
       
  1291 	{
       
  1292 	LOG(ESockLog::Printf(KESockSessDetailTag, _L8("CSockSession(%08x):\tDisconnect \"%S\""), this, &iProcessName) );
       
  1293 	CWorkerSession::Disconnect(aMessage);
       
  1294 	}