ANSC_STATUS AnscLpccoTcpBwoRemove ( ANSC_HANDLE hThisObject, ANSC_HANDLE hSocket ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_LPCCO_TCP_OBJECT pMyObject = (PANSC_LPCCO_TCP_OBJECT )hThisObject; PANSC_DAEMON_SERVER_TCP_OBJECT pDaemonServer = (PANSC_DAEMON_SERVER_TCP_OBJECT)pMyObject->hDaemonServer; PANSC_BROKER_SERVER_TCP_OBJECT pBrokerServer = (PANSC_BROKER_SERVER_TCP_OBJECT)pMyObject->hBrokerServer; PANSC_TIMER_DESCRIPTOR_OBJECT pConnTimerObj = (PANSC_TIMER_DESCRIPTOR_OBJECT )pMyObject->hConnTimerObj; PANSC_BROKER_SOCKET_TCP_OBJECT pBrokerSocket = (PANSC_BROKER_SOCKET_TCP_OBJECT)hSocket; PANSC_BUFFER_DESCRIPTOR pBufferDesp = (PANSC_BUFFER_DESCRIPTOR )pBrokerSocket->GetBufferContext((ANSC_HANDLE)pBrokerSocket); PANSC_LPC_PARTY_ADDR pPartyAddr = (PANSC_LPC_PARTY_ADDR )pBrokerSocket->GetClientContext((ANSC_HANDLE)pBrokerSocket); pBrokerSocket->SetClientContext((ANSC_HANDLE)pBrokerSocket, (ANSC_HANDLE)NULL ); pBrokerSocket->SetBufferContext((ANSC_HANDLE)pBrokerSocket, NULL, 0, (ANSC_HANDLE)NULL); if ( pBufferDesp ) { AnscFreeBdo((ANSC_HANDLE)pBufferDesp); } if ( pPartyAddr ) { pPartyAddr->Timestamp = AnscGetTickInSeconds(); pPartyAddr->PartyState &= ~ANSC_LPC_PARTY_STATE_connectedOut; pPartyAddr->PartySocket = (ANSC_HANDLE)NULL; /* * We shouldn't return until the reference count of 'pPartyAddr' reaches zero. Because if * we do, the socket may be deleted while there's still active task is trying to send * message to this party. For example: if LPC manager is issuing a LOCO call to all LPC * parties while one party is trying disconnect, a race condition is formed. */ while ( pPartyAddr->ActiveCalls > 0 ) { AnscSleep(20); } if ( !(pPartyAddr->PartyState & ANSC_LPC_PARTY_STATE_connectedIn ) && !(pPartyAddr->PartyState & ANSC_LPC_PARTY_STATE_connectedOut) ) { if ( pMyObject->bActive ) { pConnTimerObj->Stop ((ANSC_HANDLE)pConnTimerObj); pConnTimerObj->SetInterval((ANSC_HANDLE)pConnTimerObj, ANSC_LPCCO_DEF_CONN_TIMEOUT); pConnTimerObj->Start ((ANSC_HANDLE)pConnTimerObj); } } } return ANSC_STATUS_SUCCESS; }
BOOL HttpApoPubwoAccept ( ANSC_HANDLE hThisObject, ANSC_HANDLE hSocket, PANSC_HANDLE phClientContext ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PHTTP_ADVANCED_PROXY_OBJECT pMyObject = (PHTTP_ADVANCED_PROXY_OBJECT )hThisObject; PHTTP_ADVANCED_PROXY_PROPERTY pProperty = (PHTTP_ADVANCED_PROXY_PROPERTY )&pMyObject->Property; PANSC_SIMPLE_PROXY_TCP_OBJECT pSimpleProxy = (PANSC_SIMPLE_PROXY_TCP_OBJECT )pMyObject->hSimpleProxy; PHTTP_WAM_INTERFACE pWamIf = (PHTTP_WAM_INTERFACE )pMyObject->hWamIf; PHTTP_SBC_INTERFACE pSbcIf = (PHTTP_SBC_INTERFACE )pMyObject->hSbcIf; PHTTP_CBC_INTERFACE pCbcIf = (PHTTP_CBC_INTERFACE )pMyObject->hCbcIf; PHTTP_PBC_INTERFACE pPbcIf = (PHTTP_PBC_INTERFACE )pMyObject->hPbcIf; PANSC_BROKER_SOCKET_TCP_OBJECT pServerSocket = (PANSC_BROKER_SOCKET_TCP_OBJECT)hSocket; PHTTP_PSO_VER2_OBJECT pPsoVer2 = NULL; PHTTP_TRANS_RECORD_OBJECT pTransRecord = NULL; PANSC_BUFFER_DESCRIPTOR pBufferDesp = NULL; AnscTrace ( "PubwoAccept creates a new server connection to %d.%d.%d.%d / TCP %d\n", pServerSocket->PeerAddress.Dot[0], pServerSocket->PeerAddress.Dot[1], pServerSocket->PeerAddress.Dot[2], pServerSocket->PeerAddress.Dot[3], pServerSocket->PeerPort ); pBufferDesp = (PANSC_BUFFER_DESCRIPTOR)AnscAllocateBdo ( HTTP_APO_MAX_MESSAGE_SIZE, 0, 0 ); if ( pBufferDesp ) { pServerSocket->SetBufferContext ( (ANSC_HANDLE)pServerSocket, AnscBdoGetEndOfBlock(pBufferDesp), AnscBdoGetLeftSize (pBufferDesp), (ANSC_HANDLE)pBufferDesp ); } return TRUE; }
BOOL AnscLpccoTcpBwoAccept ( ANSC_HANDLE hThisObject, ANSC_HANDLE hSocket, PANSC_HANDLE phClientContext ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_LPCCO_TCP_OBJECT pMyObject = (PANSC_LPCCO_TCP_OBJECT )hThisObject; PANSC_DAEMON_SERVER_TCP_OBJECT pDaemonServer = (PANSC_DAEMON_SERVER_TCP_OBJECT)pMyObject->hDaemonServer; PANSC_BROKER_SERVER_TCP_OBJECT pBrokerServer = (PANSC_BROKER_SERVER_TCP_OBJECT)pMyObject->hBrokerServer; PANSC_BROKER_SOCKET_TCP_OBJECT pBrokerSocket = (PANSC_BROKER_SOCKET_TCP_OBJECT)hSocket; PANSC_BUFFER_DESCRIPTOR pBufferDesp = NULL; pBufferDesp = (PANSC_BUFFER_DESCRIPTOR)AnscAllocateBdo ( ANSC_LPC_DEF_MESSAGE_SIZE, 0, 0 ); if ( pBufferDesp ) { pBrokerSocket->SetBufferContext ( (ANSC_HANDLE)pBrokerSocket, AnscBdoGetEndOfBlock(pBufferDesp), AnscBdoGetLeftSize (pBufferDesp), (ANSC_HANDLE)pBufferDesp ); } return TRUE; }
ANSC_STATUS HttpApoPubwoNotify ( ANSC_HANDLE hThisObject, ANSC_HANDLE hSocket, ULONG ulEvent, ANSC_HANDLE hReserved ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PHTTP_ADVANCED_PROXY_OBJECT pMyObject = (PHTTP_ADVANCED_PROXY_OBJECT )hThisObject; PHTTP_ADVANCED_PROXY_PROPERTY pProperty = (PHTTP_ADVANCED_PROXY_PROPERTY )&pMyObject->Property; PANSC_SIMPLE_PROXY_TCP_OBJECT pSimpleProxy = (PANSC_SIMPLE_PROXY_TCP_OBJECT )pMyObject->hSimpleProxy; PANSC_BROKER_SOCKET_TCP_OBJECT pServerSocket = (PANSC_BROKER_SOCKET_TCP_OBJECT)hSocket; PANSC_BUFFER_DESCRIPTOR pBufferDesp = (PANSC_BUFFER_DESCRIPTOR )pServerSocket->GetBufferContext((ANSC_HANDLE)pServerSocket); PHTTP_PSO_VER2_OBJECT pPsoVer2 = NULL; PHTTP_TRANS_RECORD_OBJECT pTransRecord = NULL; AnscTrace ( "Event = %d is indicated on server connection of %d.%d.%d.%d / TCP %d\n", ulEvent, pServerSocket->PeerAddress.Dot[0], pServerSocket->PeerAddress.Dot[1], pServerSocket->PeerAddress.Dot[2], pServerSocket->PeerAddress.Dot[3], pServerSocket->PeerPort ); switch ( ulEvent ) { case ANSC_SPTOWO_EVENT_SOCKET_ERROR : pServerSocket->ToClean((ANSC_HANDLE)pServerSocket, TRUE, HTTP_APO_SOCKET_TTC); break; case ANSC_SPTOWO_EVENT_SOCKET_CLOSED : AnscAcquireLock(&pMyObject->SyncLock); pPsoVer2 = (PHTTP_PSO_VER2_OBJECT)pServerSocket->GetClientContext((ANSC_HANDLE)pServerSocket); if ( pPsoVer2 ) { pPsoVer2->AcquireAccess((ANSC_HANDLE)pPsoVer2); pTransRecord = (PHTTP_TRANS_RECORD_OBJECT)pPsoVer2->AskTroBySocket ( (ANSC_HANDLE)pPsoVer2, (ANSC_HANDLE)pServerSocket ); pPsoVer2->ReleaseAccess((ANSC_HANDLE)pPsoVer2); } else { AnscReleaseLock(&pMyObject->SyncLock); pServerSocket->Finish((ANSC_HANDLE)pServerSocket); return ANSC_STATUS_SUCCESS; } if ( !pTransRecord ) { AnscReleaseLock(&pMyObject->SyncLock); pServerSocket->Finish((ANSC_HANDLE)pServerSocket); return ANSC_STATUS_SUCCESS; } AnscReleaseLock(&pMyObject->SyncLock); pBufferDesp->BlockSize += pServerSocket->RecvPacketSize; returnStatus = pServerSocket->SetBufferContext ( (ANSC_HANDLE)pServerSocket, NULL, 0, (ANSC_HANDLE)NULL ); returnStatus = pTransRecord->FinishedByServer ( (ANSC_HANDLE)pTransRecord, AnscBdoGetBlock (pBufferDesp), AnscBdoGetBlockSize(pBufferDesp), (ANSC_HANDLE)pBufferDesp ); pTransRecord->ReleaseAccess((ANSC_HANDLE)pTransRecord); pServerSocket->Finish((ANSC_HANDLE)pServerSocket); break; case ANSC_SPTOWO_EVENT_RESOURCES : break; case ANSC_SPTOWO_EVENT_TIME_OUT : break; default : break; } return ANSC_STATUS_SUCCESS; }
ANSC_STATUS HttpApoPubwoProcessSync ( ANSC_HANDLE hThisObject, ANSC_HANDLE hSocket, PVOID buffer, ULONG ulSize, ANSC_HANDLE hQueryContext ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PHTTP_ADVANCED_PROXY_OBJECT pMyObject = (PHTTP_ADVANCED_PROXY_OBJECT )hThisObject; PHTTP_ADVANCED_PROXY_PROPERTY pProperty = (PHTTP_ADVANCED_PROXY_PROPERTY )&pMyObject->Property; PANSC_SIMPLE_PROXY_TCP_OBJECT pSimpleProxy = (PANSC_SIMPLE_PROXY_TCP_OBJECT )pMyObject->hSimpleProxy; PANSC_BROKER_SOCKET_TCP_OBJECT pServerSocket = (PANSC_BROKER_SOCKET_TCP_OBJECT)hSocket; PANSC_DAEMON_SOCKET_TCP_OBJECT pClientSocket = (PANSC_DAEMON_SOCKET_TCP_OBJECT)NULL; PANSC_BUFFER_DESCRIPTOR pBufferDesp = (PANSC_BUFFER_DESCRIPTOR )pServerSocket->GetBufferContext((ANSC_HANDLE)pServerSocket); PHTTP_PSO_VER2_OBJECT pPsoVer2 = NULL; PHTTP_TRANS_RECORD_OBJECT pTransRecord = NULL; ULONG ulTroQmode = (ULONG)hQueryContext; BOOL bFinishSocket = FALSE; AnscAcquireLock(&pMyObject->SyncLock); pPsoVer2 = (PHTTP_PSO_VER2_OBJECT)pServerSocket->GetClientContext((ANSC_HANDLE)pServerSocket); if ( pPsoVer2 ) { pPsoVer2->AcquireAccess((ANSC_HANDLE)pPsoVer2); pTransRecord = (PHTTP_TRANS_RECORD_OBJECT)pPsoVer2->AskTroBySocket ( (ANSC_HANDLE)pPsoVer2, (ANSC_HANDLE)pServerSocket ); pPsoVer2->ReleaseAccess((ANSC_HANDLE)pPsoVer2); } else { AnscReleaseLock(&pMyObject->SyncLock); pServerSocket->Finish((ANSC_HANDLE)pServerSocket); return ANSC_STATUS_SUCCESS; } if ( !pTransRecord ) { AnscReleaseLock(&pMyObject->SyncLock); pServerSocket->Finish((ANSC_HANDLE)pServerSocket); return ANSC_STATUS_SUCCESS; } AnscReleaseLock(&pMyObject->SyncLock); switch ( ulTroQmode ) { case HTTP_TRO_QMODE_FORWARD : pClientSocket = (PANSC_DAEMON_SOCKET_TCP_OBJECT)pTransRecord->GetClientSocket((ANSC_HANDLE)pTransRecord); if ( !pClientSocket) { bFinishSocket = TRUE; returnStatus = ANSC_STATUS_INTERNAL_ERROR; break; } else { returnStatus = pClientSocket->Send ( (ANSC_HANDLE)pClientSocket, buffer, ulSize, (ANSC_HANDLE)NULL ); } pBufferDesp->BlockSize = 0; break; case HTTP_TRO_QMODE_PROCESS : pServerSocket->SetBufferContext ( (ANSC_HANDLE)pServerSocket, NULL, 0, (ANSC_HANDLE)NULL ); returnStatus = pTransRecord->RecvFromServer ( (ANSC_HANDLE)pTransRecord, buffer, ulSize, (ANSC_HANDLE)pBufferDesp ); if ( pTransRecord->GetTransState((ANSC_HANDLE)pTransRecord) == HTTP_TRO_STATE_FINISHED ) { bFinishSocket = TRUE; break; } break; default : returnStatus = ANSC_STATUS_UNAPPLICABLE; break; } pTransRecord->ReleaseAccess((ANSC_HANDLE)pTransRecord); if ( bFinishSocket ) { pServerSocket->Finish((ANSC_HANDLE)pServerSocket); } return returnStatus; }
ANSC_STATUS HttpApoPubwoRemove ( ANSC_HANDLE hThisObject, ANSC_HANDLE hSocket ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PHTTP_ADVANCED_PROXY_OBJECT pMyObject = (PHTTP_ADVANCED_PROXY_OBJECT )hThisObject; PHTTP_ADVANCED_PROXY_PROPERTY pProperty = (PHTTP_ADVANCED_PROXY_PROPERTY )&pMyObject->Property; PANSC_SIMPLE_PROXY_TCP_OBJECT pSimpleProxy = (PANSC_SIMPLE_PROXY_TCP_OBJECT )pMyObject->hSimpleProxy; PANSC_BROKER_SOCKET_TCP_OBJECT pServerSocket = (PANSC_BROKER_SOCKET_TCP_OBJECT)hSocket; PANSC_DAEMON_SOCKET_TCP_OBJECT pClientSocket = (PANSC_DAEMON_SOCKET_TCP_OBJECT)NULL; PANSC_BUFFER_DESCRIPTOR pBufferDesp = (PANSC_BUFFER_DESCRIPTOR )pServerSocket->GetBufferContext((ANSC_HANDLE)pServerSocket); PHTTP_PSO_VER2_OBJECT pPsoVer2 = NULL; PHTTP_TRANS_RECORD_OBJECT pTransRecord = NULL; BOOL bRemovePso = FALSE; AnscTrace ( "PubwoRemove removes the server connection of %d.%d.%d.%d / TCP %d\n", pServerSocket->PeerAddress.Dot[0], pServerSocket->PeerAddress.Dot[1], pServerSocket->PeerAddress.Dot[2], pServerSocket->PeerAddress.Dot[3], pServerSocket->PeerPort ); AnscAcquireLock(&pMyObject->SyncLock); pPsoVer2 = (PHTTP_PSO_VER2_OBJECT)pServerSocket->GetClientContext((ANSC_HANDLE)pServerSocket); if ( pPsoVer2 ) { pPsoVer2->AcquireAccess((ANSC_HANDLE)pPsoVer2); pTransRecord = (PHTTP_TRANS_RECORD_OBJECT)pPsoVer2->AskTroBySocket ( (ANSC_HANDLE)pPsoVer2, (ANSC_HANDLE)pServerSocket ); } /* * Just a couple regular clean-up tasks to do: * * (1) dis-associate the trans record object from the server socket * (2) clean the foreign buffer associated with the server socket * (3) dis-associate the trans record object from the client socket * * Note that we CANNOT clean the foreign buffer associated with the client socket because the * access to that buffer is NOT synchornized between the prv_recv() and pub_recv routines. It * SHOULD be done in the prv_remove() function. */ pServerSocket->SetClientContext((ANSC_HANDLE)pServerSocket, (ANSC_HANDLE)NULL); pServerSocket->SetBufferContext((ANSC_HANDLE)pServerSocket, NULL, 0, (ANSC_HANDLE)NULL); if ( pBufferDesp ) { AnscFreeBdo((ANSC_HANDLE)pBufferDesp); } if ( pTransRecord ) { pTransRecord->SetServerSocket((ANSC_HANDLE)pTransRecord, (ANSC_HANDLE)NULL ); pTransRecord->SetTransState ((ANSC_HANDLE)pTransRecord, HTTP_TRO_STATE_FINISHED); pTransRecord->ReleaseAccess ((ANSC_HANDLE)pTransRecord); } /* * The idea of pipeline the client requests over a single client session is great, however, we * may run into a situation where wrongly-implemented clients are waiting forever for server to * close the connection. To prevent that, we should close the session if no outstanding trans- * action needs to be completed. */ if ( pPsoVer2 ) { pTransRecord = (PHTTP_TRANS_RECORD_OBJECT)pPsoVer2->GetLastTro((ANSC_HANDLE)pPsoVer2); if ( pTransRecord ) { if ( (pTransRecord->GetTransState((ANSC_HANDLE)pTransRecord) == HTTP_TRO_STATE_FINISHED) && (pTransRecord->bCloseConnection == TRUE ) ) { bRemovePso = TRUE; pClientSocket = (PANSC_DAEMON_SOCKET_TCP_OBJECT)pPsoVer2->GetClientSocket((ANSC_HANDLE)pPsoVer2); if ( pClientSocket ) { pClientSocket->SetClientContext((ANSC_HANDLE)pClientSocket, (ANSC_HANDLE)NULL ); pClientSocket->ToClean ((ANSC_HANDLE)pClientSocket, FALSE, HTTP_APO_SOCKET_TTC); } } pTransRecord->ReleaseAccess((ANSC_HANDLE)pTransRecord); } pPsoVer2->ReleaseAccess((ANSC_HANDLE)pPsoVer2); } AnscReleaseLock(&pMyObject->SyncLock); /* * If you're wondering why we have to explicitly close the connection here, why not wait until * triggered by the clients-side actions, here's why: the stupid desktop browsers (i.e., Micro- * soft IE browsers) will not take any action but waiting for the connection to be closed. */ if ( bRemovePso ) { pPsoVer2->DelAllTros((ANSC_HANDLE)pPsoVer2); pPsoVer2->Close ((ANSC_HANDLE)pPsoVer2); pPsoVer2->Return ((ANSC_HANDLE)pPsoVer2); } return ANSC_STATUS_SUCCESS; }
ULONG AnscLpccoTcpBwoQuery ( ANSC_HANDLE hThisObject, ANSC_HANDLE hSocket, PVOID buffer, ULONG ulSize, PANSC_HANDLE phQueryContext ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_LPCCO_TCP_OBJECT pMyObject = (PANSC_LPCCO_TCP_OBJECT )hThisObject; PANSC_DAEMON_SERVER_TCP_OBJECT pDaemonServer = (PANSC_DAEMON_SERVER_TCP_OBJECT)pMyObject->hDaemonServer; PANSC_BROKER_SERVER_TCP_OBJECT pBrokerServer = (PANSC_BROKER_SERVER_TCP_OBJECT)pMyObject->hBrokerServer; PANSC_BROKER_SOCKET_TCP_OBJECT pBrokerSocket = (PANSC_BROKER_SOCKET_TCP_OBJECT)hSocket; PANSC_BUFFER_DESCRIPTOR pBufferDesp = (PANSC_BUFFER_DESCRIPTOR )pBrokerSocket->GetBufferContext((ANSC_HANDLE)pBrokerSocket); PANSC_BUFFER_DESCRIPTOR pNewBdo = (PANSC_BUFFER_DESCRIPTOR )NULL; PIMCP_HEADER pImcpHeader = (PIMCP_HEADER )NULL; ULONG ulMsgSize = (ULONG )0; ULONG ulCopySize = (ULONG )0; ULONG ulLeftSize = (ULONG )0; ULONG i = 0; if ( !pBufferDesp ) { return ANSC_BSTOWO_PMODE_FINISH; } else { pBufferDesp->BlockSize += ulSize; } if ( AnscBdoGetUsableSize(pBufferDesp) <= sizeof(IMCP_HEADER) ) { pNewBdo = (PANSC_BUFFER_DESCRIPTOR)AnscAllocateBdo ( ANSC_LPC_DEF_MESSAGE_SIZE, 0, AnscBdoGetBlockSize(pBufferDesp) ); if ( !pNewBdo ) { return ANSC_BSTOWO_PMODE_FINISH; } else { ulCopySize = AnscBdoGetBlockSize(pBufferDesp); returnStatus = AnscBdoCopyFrom ( (ANSC_HANDLE)pBufferDesp, AnscBdoGetBlock(pNewBdo), &ulCopySize, 0 ); pBrokerSocket->SetBufferContext ( (ANSC_HANDLE)pBrokerSocket, AnscBdoGetEndOfBlock(pNewBdo), AnscBdoGetLeftSize (pNewBdo), (ANSC_HANDLE)pNewBdo ); } AnscFreeBdo((ANSC_HANDLE)pBufferDesp); return ANSC_BSTOWO_PMODE_COLLECT; } else if ( AnscBdoGetBlockSize(pBufferDesp) < sizeof(IMCP_HEADER) ) { /* * We need to rollback the block size of the buffer descriptor before we return 'Collect'. * Next time when this Query() function is called, the 'ulSize' parameter will be set to * the total size of un-processed data, not the size of the newly received data. */ pBufferDesp->BlockSize -= ulSize; return ANSC_BSTOWO_PMODE_COLLECT; } else { pImcpHeader = (PIMCP_HEADER)AnscBdoGetBlock(pBufferDesp); ulMsgSize = (ULONG )ImcpGetMsgSize (pImcpHeader); } if ( ulMsgSize == AnscBdoGetBlockSize(pBufferDesp) ) { pNewBdo = (PANSC_BUFFER_DESCRIPTOR)AnscAllocateBdo ( ANSC_LPC_DEF_MESSAGE_SIZE, 0, 0 ); if ( !pNewBdo ) { return ANSC_BSTOWO_PMODE_FINISH; } else { pBrokerSocket->SetBufferContext ( (ANSC_HANDLE)pBrokerSocket, AnscBdoGetEndOfBlock(pNewBdo), AnscBdoGetLeftSize (pNewBdo), (ANSC_HANDLE)pNewBdo ); } returnStatus = pMyObject->Recv ( (ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pBrokerSocket, (ANSC_HANDLE)pBufferDesp ); return ANSC_BSTOWO_PMODE_DISCARD; } else if ( ulMsgSize < AnscBdoGetBlockSize(pBufferDesp) ) { pNewBdo = (PANSC_BUFFER_DESCRIPTOR)AnscAllocateBdo ( ulMsgSize, 0, ulMsgSize ); if ( !pNewBdo ) { return ANSC_BSTOWO_PMODE_FINISH; } else { ulCopySize = ulMsgSize; returnStatus = AnscBdoCopyFrom ( (ANSC_HANDLE)pBufferDesp, AnscBdoGetBlock(pNewBdo), &ulCopySize, 0 ); } returnStatus = pMyObject->Recv ( (ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pBrokerSocket, (ANSC_HANDLE)pNewBdo ); /* * As Lina discovered, we cannot simply reset the 'BlockSize' to zero and make another * Query() call. If we do and the returned mode is COLLECT, the socket object would be * confused because the data processed in this call is still remembered and its size will * be covered in the next Query() call. We need to follow the steps as listed below to * ensure the packet data in the previous call is cleaned: * * - Set the 'BlockSize' to whatever data left after processing. * - Advance 'Offset' field by the message size. * - Reset the buffer context of the socket object. * - Calling Query() again with 'ulSize' set to zero. */ ulLeftSize = AnscBdoGetBlockSize(pBufferDesp) - ulMsgSize; pBufferDesp->Offset += ulMsgSize; pBufferDesp->BlockSize -= ulMsgSize; pBrokerSocket->SetBufferContext ( (ANSC_HANDLE)pBrokerSocket, AnscBdoGetEndOfBlock(pBufferDesp), AnscBdoGetLeftSize (pBufferDesp), (ANSC_HANDLE)pBufferDesp ); return pMyObject->BwoQuery ( (ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pBrokerSocket, AnscBdoGetEndOfBlock(pBufferDesp), /*AnscBdoGetBlock(pBufferDesp),*/ 0, /*ulLeftSize, */ phQueryContext ); } else if ( ulMsgSize <= AnscBdoGetUsableSize(pBufferDesp) ) { /* * We need to rollback the block size of the buffer descriptor before we return 'Collect'. * Next time when this Query() function is called, the 'ulSize' parameter will be set to * the total size of un-processed data, not the size of the newly received data. */ pBufferDesp->BlockSize -= ulSize; return ANSC_BSTOWO_PMODE_COLLECT; } else { pNewBdo = (PANSC_BUFFER_DESCRIPTOR)AnscAllocateBdo ( ulMsgSize, 0, AnscBdoGetBlockSize(pBufferDesp) ); if ( !pNewBdo ) { return ANSC_BSTOWO_PMODE_FINISH; } else { ulCopySize = AnscBdoGetBlockSize(pBufferDesp); returnStatus = AnscBdoCopyFrom ( (ANSC_HANDLE)pBufferDesp, AnscBdoGetBlock(pNewBdo), &ulCopySize, 0 ); pBrokerSocket->SetBufferContext ( (ANSC_HANDLE)pBrokerSocket, AnscBdoGetEndOfBlock(pNewBdo), AnscBdoGetLeftSize (pNewBdo), (ANSC_HANDLE)pNewBdo ); } AnscFreeBdo((ANSC_HANDLE)pBufferDesp); return ANSC_BSTOWO_PMODE_COLLECT; } return ANSC_BSTOWO_PMODE_DISCARD; }