⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcptransport.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                goto PacketReadyToSend;
            } else {
                TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-TCP -- reading SMB TCP failed!! closing connection")));
                hr = E_FAIL;
                goto Done;
            }
        }

        //
        // Special case keep alives -- there is no reason to wake up the Cracker
        //   for these.  (keep alive is opeation 0x85)
        if(pHeader[0] == 0x85) {
            TRACEMSG(ZONE_TCPIP, (TEXT("SMBSRV-TCPRECV: its a keepalive... dont do anything")));
            continue;
        } else if (pHeader[0] != 0x00) { //who knows what this is... close up shop
            TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-TCPRECV: got a unexpected packet header (%d)"), pHeader[0]));
            hr = E_FAIL;
            goto Done;
        }

        //
        // Prepare to read the real packet
        pHeader[0] = 0;
        dwHeader = ntohl(dwHeader);  

        if(dwHeader > sizeof(pNewPacket->InSMB)) {
             TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-TCPRECV: this packet is too large (%d) for our buffers!!  -- drop connection"), dwHeader));
             hr = E_OUTOFMEMORY;
             goto Done;
        }

        //
        // Read one SMB packet (wait up to 'g_uiTCPTimeoutInSeconds' seconds for this)
        if(dwHeader != (DWORD)timed_recv(sSock, (char *)(pNewPacket->InSMB), dwHeader, 0, g_uiTCPTimeoutInSeconds, &fTimedOut)) {
            TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-TCP -- reading SMB TCP packet of %d bytes timed out!! -- closing connection"), dwHeader));
            hr = E_FAIL;
            goto Done;
        }

        //
        // Set packet fields that are specific to 'normal' packets only
        IFDBG(pNewPacket->PerfStartTimer());
        pNewPacket->uiPacketType = SMB_NORMAL_PACKET;
        pNewPacket->pInSMB = (SMB_HEADER *)pNewPacket->InSMB;
        pNewPacket->uiInSize = dwHeader;



        PacketReadyToSend:
            //
            // Give the cracker a reference (will be dec'ed by QueueTCPPacketForSend)
            IncrementConnectionCounter(pMyConnection);

            pNewPacket->pToken = (void *)pMyConnection;
            pNewPacket->pOutSMB = NULL;
            pNewPacket->uiOutSize = 0;
            pNewPacket->pfnQueueFunction = QueueTCPPacketForSend;
            pNewPacket->pfnCopyTranportToken = CopyTCPTransportToken;
            pNewPacket->pfnDeleteTransportToken = DeleteTCPTransportToken;
            //pNewPacket->pfnGetSocketName = TCP_GetSocketName;
            pNewPacket->ulConnectionID = ConnectionID;
            pNewPacket->dwDelayBeforeSending = 0;
#ifdef DEBUG
            pNewPacket->uiPacketNumber = InterlockedIncrement(&SMB_Globals::g_PacketID);
#endif


            TRACEMSG(ZONE_TCPIP, (TEXT("SMBSRV-TCPRECV:Got a TCP packet! (%d bytes--id %d)"), dwHeader, pNewPacket->uiPacketNumber));

            //hand off the packet to the SMB cracker
            if(FAILED(CrackPacket(pNewPacket))) {
                //this should *NEVER* happen... Crack should handle its own errors
                //  and when there is one it should return back an error code to the client
                TRACEMSG(ZONE_TCPIP, (TEXT("SMBSRV-TCPRECV: UNEXPECTED ERROR IN CRACK()!")));
                ASSERT(FALSE);
                hr = E_UNEXPECTED;
                goto Done;
            } else {
                pNewPacket = NULL;
            }
    }

    hr = S_OK;
    Done:

        if(pNewPacket) {
            SMB_Globals::g_SMB_Pool.Free(pNewPacket);
            pNewPacket = NULL;
        }

        if(FAILED(hr)) {
            closesocket(pMyConnection->sock);
            pMyConnection->sock = INVALID_SOCKET;
        }

        //
        // Push a packet into the cracker that kills off anything we might
        //   have opened
        if(TRUE == Cracker::g_fIsRunning) {
            //
            // Give the cracker a reference (will be dec'ed by QueueTCPPacketForSend)
            IncrementConnectionCounter(pMyConnection);

            //
            // Get some memory out of our free pool
            ASSERT(NULL == pNewPacket);
            if(NULL == (pNewPacket = SMB_Globals::g_SMB_Pool.Alloc())) {
                hr = E_OUTOFMEMORY;
                goto Done;
            }

            if(NULL != pNewPacket) {
                memset(pNewPacket, 0, sizeof(SMB_PACKET));
                pNewPacket->uiPacketType = SMB_CONNECTION_DROPPED;
                pNewPacket->ulConnectionID = ConnectionID;
                pNewPacket->pToken = (void *)pMyConnection;
                pNewPacket->pfnQueueFunction = QueueTCPPacketForSend;
                pNewPacket->pfnCopyTranportToken = CopyTCPTransportToken;
                pNewPacket->pfnDeleteTransportToken = DeleteTCPTransportToken;
                //pNewPacket->pfnGetSocketName = TCP_GetSocketName;
                pNewPacket->dwDelayBeforeSending = 0;

        #ifdef DEBUG
                pNewPacket->uiPacketNumber = InterlockedIncrement(&SMB_Globals::g_PacketID);
        #endif

                TRACEMSG(ZONE_TCPIP, (TEXT("SMBSRV-TCPRECV: sending out connection dropped for %d"), ConnectionID));

                //
                // Hand off the packet to the SMB cracker
                if(FAILED(CrackPacket(pNewPacket))) {
                    //this should *NEVER* happen... Crack should handle its own errors
                    //  and when there is one it should return back an error code to the client
                    TRACEMSG(ZONE_TCPIP, (TEXT("SMBSRV-NBRECV: UNEXPECTED ERROR IN CRACK()!")));
                    ASSERT(FALSE);
                    hr = E_UNEXPECTED;
                    goto Exit;
                } else {
                    pNewPacket = NULL;
                }
            }
        } else {
            TRACEMSG(ZONE_TCPIP, (TEXT("SMBSRV-TCPRECV: cracker thread is dead -- just exiting")));
            ASSERT(FALSE);
        }

    Exit:

        if(pNewPacket) {
            SMB_Globals::g_SMB_Pool.Free(pNewPacket);
            pNewPacket = NULL;
        }

        //
        // Dec our threads ref to the connection
        DecrementConnectionCounter(pMyConnection); 

        //
        // Give back our id
        if(0xFFFF != sConnectionID) {
           if(FAILED(g_ConnectionID.RemoveID(sConnectionID))) {
                ASSERT(FALSE);
           }
        }

        TRACEMSG(ZONE_TCPIP, (TEXT("SMBSRV-TCPRECV:Exiting thread!")));   
        TRACEMSG(ZONE_TCPIP, (L"SMBSRV: Removed TCP Connection -- Total Connections: %d", InterlockedDecrement(&TCP_TRANSPORT::g_lAliveSockets)));         
        return 0;
}


HRESULT TCP_TerminateSession(ULONG ulConnectionID)
{
    CCritSection csLock(&TCP_TRANSPORT::g_csLockTCPTransportGlobals);
    ce::list<CONNECTION_HOLDER *, TCP_CONNECTION_HLDR_ALLOC>::iterator itConn;
    HRESULT hr = E_FAIL;

    csLock.Lock();
    for(itConn = g_ConnectionList.begin(); itConn != g_ConnectionList.end(); ++itConn) {
        CONNECTION_HOLDER *pConn = (*itConn);
        CCritSection csConnLock(&pConn->csSockLock);

        csConnLock.Lock();
        if(ulConnectionID == pConn->ulConnectionID) {
            TRACEMSG(ZONE_TCPIP, (L"SMBSRV: TCPTRANS -- terminating connection %d", ulConnectionID));
            closesocket(pConn->sock);
            hr = S_OK;
            goto Done;
        }
    }

    Done:
        return hr;
}


HRESULT TCP_GetSocketName(SMB_PACKET *pPacket, struct sockaddr *pSockAddr, int *pNameLen)
{
    CONNECTION_HOLDER *pMyConnection = NULL;
    HRESULT hr = E_FAIL;

    //
    // Make sure they (the cracker) have given us memory!
    if(NULL == pPacket || NULL == pPacket->pToken) {
        ASSERT(FALSE); //internal error -- this should NEVER happen
        return E_UNEXPECTED;
    }
    pMyConnection = (CONNECTION_HOLDER *)pPacket->pToken;

    //
    // If the connection has dropped delete memory
    if(SMB_CONNECTION_DROPPED == pPacket->uiPacketType) {
        TRACEMSG(ZONE_TCPIP, (L"TCPIP: connection dropped packet -- deleting memory"));
        hr = S_OK;
        goto Done;
    }

    if(0 != getsockname(pMyConnection->sock, pSockAddr, pNameLen)) {
        ASSERT(FALSE);
        hr = E_FAIL;
    }

    Done:
        return hr;
}



// 
//  This function is the transport specific callback for transmitting 
//   packets -- in the event an unrecoverable error occurs, we will
//   just shut down the socket -- this is okay because it will
//   cause all other transmissions to that socket to fail (there
//   could be more in the cracker queue waiting to be sent) -- eventually
//   the refcnt for the connection will reach 0 and will be terminated
HRESULT 
TCP_TRANSPORT::QueueTCPPacketForSend(SMB_PACKET *pPacket, BOOL fDestruct)
{
    HRESULT hr = S_OK;
    DWORD dwSendSize;
    //char *pDWPtr = NULL;
    CONNECTION_HOLDER *pMyConnection = NULL;

    //
    // Make sure they (the cracker) have given us memory!
    if(NULL == pPacket || NULL == pPacket->pToken) {
        ASSERT(FALSE); //internal error -- this should NEVER happen
        return E_UNEXPECTED;
    }
    pMyConnection = (CONNECTION_HOLDER *)pPacket->pToken;

    EnterCriticalSection(&pMyConnection->csSockLock); //serialize writes!!
    TRACEMSG(ZONE_TCPIP, (TEXT("SMBSRV-TCP -- sending response for packet: %d on socket %d"), pPacket->uiPacketNumber, pMyConnection->sock));  


    //
    // If the packet isnt normal just return (dont send data)
    if(SMB_NORMAL_PACKET != pPacket->uiPacketType) {
        TRACEMSG(ZONE_TCPIP, (L"TCPIP: connection dropped/timed out packet -- deleting memory"));
        hr = S_OK;
        goto Done;
    }


    ASSERT(pPacket->uiOutSize <= SMB_Globals::MAX_PACKET_SIZE); 

    dwSendSize = htonl(pPacket->uiOutSize);
    //pDWPtr = (CHAR *)&dwSendSize;
    //pDWPtr[0] = 0;

    if(TRUE == g_fStopped) {
        TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-TCP -- we have shut down.. dont send the packet")));    
        hr = E_FAIL;
        goto Done;
    }

    WSABUF myBufs[2];
    myBufs[0].len = sizeof(DWORD);
    myBufs[0].buf = (CHAR *)&dwSendSize;
    myBufs[1].len = pPacket->uiOutSize;
    myBufs[1].buf = (CHAR *)pPacket->pOutSMB;

    if(FAILED(writeAll_BlockedOverLapped(pMyConnection->sock, pMyConnection->hOverlappedHandle, myBufs, 2))) {
        TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-TCP -- sending SMB header  over TCP failed!! closing connection")));
        closesocket(pMyConnection->sock);
        pMyConnection->sock = INVALID_SOCKET;
        hr = E_FAIL;
        goto Done;
    }

    /*if(FAILED(writeAll(pMyConnection->sock, (CHAR *)&dwSendSize, 4))) {
        TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-TCP -- sending SMB header  over TCP failed!! closing connection")));
        closesocket(pMyConnection->sock);
        pMyConnection->sock = INVALID_SOCKET;
        hr = E_FAIL;
        goto Done;
    }
    if(FAILED(writeAll(pMyConnection->sock, (char *)pPacket->pOutSMB, pPacket->uiOutSize))) {
        TRACEMSG(ZONE_ERROR, (TEXT("SMBSRV-TCP -- sending SMB over TCP failed!! closing connection")));
        closesocket(pMyConnection->sock);
        pMyConnection->sock = INVALID_SOCKET;
        hr = E_FAIL;
        goto Done;
    }*/

    Done:

#ifdef DEBUG
        if(SMB_NORMAL_PACKET == pPacket->uiPacketType && pPacket->pInSMB) {
            UCHAR SMB = pPacket->pInSMB->Command;
            pPacket->PerfStopTimer(SMB);
            DWORD dwProcessing = pPacket->TimeProcessing();
            CCritSection csLock(&Cracker::g_csPerfLock); 
            csLock.Lock();
                DOUBLE dwNew = (Cracker::g_dblPerfAvePacketTime[SMB] * Cracker::g_dwPerfPacketsProcessed[SMB]);
                Cracker::g_dwPerfPacketsProcessed[SMB] ++;
                dwNew += dwProcessing;
                dwNew /= Cracker::g_dwPerfPacketsProcessed[SMB];
                Cracker::g_dblPerfAvePacketTime[SMB] = dwNew; 
            csLock.UnLock(); 
        }
#endif

        if(TRUE == fDestruct) {

            SMB_Globals::g_SMB_Pool.Free(pPacket);
        }
        LeaveCriticalSection(&pMyConnection->csSockLock);

        if(TRUE == fDestruct) {
            DecrementConnectionCounter(pMyConnection);
        }
        return hr;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -