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

📄 scsman.cxx

📁 Windows CE 6.0 Server 源码
💻 CXX
📖 第 1 页 / 共 5 页
字号:
			if ((ul_wins_report[i] == INADDR_NONE) || (ul_wins_report[i] == ul_addr))
				fFound = TRUE;
			else {
				for (int j = 0 ; j < i ; ++j) {
					if (ul_wins_report[j] == ul_wins_report[i]) {
						fFound = TRUE;
						break;
					}
				}
			}

			if (! fFound) {
				sin.sin_addr.S_un.S_addr = ul_wins_report[i];
				ipPeerAddr = sin.sin_addr;

				if ((iPass == 0) && ping (ul_wins_report[i])) {
#if defined (SC_VERBOSE)
					scerror_DebugOut (VERBOSE_MASK_SESSION, L"Connecting to %s as %d.%d.%d.%d (WINS lookup, ping)\n", lpszHostName,
								sin.sin_addr.S_un.S_un_b.s_b1, sin.sin_addr.S_un.S_un_b.s_b2, sin.sin_addr.S_un.S_un_b.s_b3, sin.sin_addr.S_un.S_un_b.s_b4);
#endif

					return connect (s, (sockaddr *)&sin, sizeof(sin)) == 0;
				}

				if ((iPass == 1) || (! gMachine->uiPingPort)) {
#if defined (SC_VERBOSE)
					scerror_DebugOut (VERBOSE_MASK_SESSION, L"Connecting to %s as %d.%d.%d.%d (WINS lookup)\n", lpszHostName,
								sin.sin_addr.S_un.S_un_b.s_b1, sin.sin_addr.S_un.S_un_b.s_b2, sin.sin_addr.S_un.S_un_b.s_b3, sin.sin_addr.S_un.S_un_b.s_b4);
#endif
					if (connect (s, (sockaddr *)&sin, sizeof(sin)) == 0)
						return TRUE;
				}
			}
		}

		if (! gMachine->uiPingPort)
			break;
	}

	return FALSE;
}
//
//	Reading thread: establish the connection and start recv'ing
//	Writing thread: control timely establishment of connection and then
//	monitor situation and send stuff.
//
//	Finally, writing thread brings down reading thread, decrements thread
//	pair count and exits.
//
void ScSession::ServiceThreadR (void) {
#if defined (SC_VERBOSE)
	scerror_DebugOut (VERBOSE_MASK_SESSION, L"Started receive thread for %s\n", lpszHostName);
#endif

	if (fSessionState != SCSESSION_STATE_CONNECTING)
		return;

	InitConnection ();

	if (s == INVALID_SOCKET) {
#if defined (SC_VERBOSE)
		scerror_DebugOut (VERBOSE_MASK_SESSION, L"Creating socket connection for %s\n", lpszHostName);
#endif
		//
		//	Create socket.
		//

		s = socket (AF_INET, SOCK_STREAM, 0);

		if ((s == INVALID_SOCKET) || (! Connect ())) {
#if defined (SC_VERBOSE)
			if (s == INVALID_SOCKET)
				scerror_DebugOut (VERBOSE_MASK_SESSION, L"Can't open a socket for %s\n", lpszHostName);
			else
				scerror_DebugOut (VERBOSE_MASK_SESSION, L"Can't connect to %s\n", lpszHostName);
#endif
			gMem->Lock ();
			FailConnection ();
			SetEvent (hEvent);
			CloseHandle (hServiceThreadR);
			hServiceThreadR = NULL;
			gMem->Unlock ();
			return;
		}

		gMem->Lock ();
		OkConnection (SCSESSION_STATE_CONNECTED_CLIENT);
		gMem->Unlock ();

		//
		//	Send establish connection packet
		//
		if ((! SendECP(FALSE)) || (! RecvECP())) {
			gMem->Lock ();
			FailConnection ();
			SetEvent (hEvent);
			CloseHandle (hServiceThreadR);
			hServiceThreadR = NULL;
			gMem->Unlock ();
			return;
		}

		//
		//	Get ack.
		//
		if ((! SendCPP()) || (! RecvCPP())) {
			gMem->Lock ();
			FailConnection ();
			SetEvent (hEvent);
			CloseHandle (hServiceThreadR);
			hServiceThreadR = NULL;
			gMem->Unlock ();
			return;
		}
	} else {
		gMem->Lock ();
		OkConnection (SCSESSION_STATE_CONNECTED_SERVER);
		gMem->Unlock ();

		//
		//	Receive establishing connection packet.
		//
		if ((! RecvECP()) || (! SendECP(FALSE))) {
			gMem->Lock ();
			FailConnection ();
			SetEvent (hEvent);
			CloseHandle (hServiceThreadR);
			hServiceThreadR = NULL;
			gMem->Unlock ();
			return;
		}
		//
		//	Send ack
		//
		if ((! RecvCPP()) || (! SendCPP())) {
			gMem->Lock ();
			FailConnection ();
			SetEvent (hEvent);
			CloseHandle (hServiceThreadR);
			hServiceThreadR = NULL;
			gMem->Unlock ();
			return;
		}
	}

#if defined (SC_VERBOSE)
	scerror_DebugOut (VERBOSE_MASK_SESSION, L"Session with %s initialized successfully\n", lpszHostName);
#endif

	fSessionState = SCSESSION_STATE_OPERATING;
	SetEvent (hEvent);

	while (fSessionState == SCSESSION_STATE_OPERATING) {
		const int iHeaderSize = sizeof(CBaseHeader);
		const int iBufferSize = sizeof (CBaseHeader) + sizeof (CDebugSection) + sizeof(CSessionSection) +
			sizeof (CECSection) + sizeof (CCPSection) + sizeof (CInternalSection);

		char __buf[iBufferSize];

		ScPacketImage *pImage = NULL;
		char		  *pcBuffer = NULL;

		int			  fError = FALSE;

		int iTotalRecvd = 0;

		while (iTotalRecvd < iHeaderSize) {
			int iRecvd = recv (s, &__buf[iTotalRecvd], iHeaderSize - iTotalRecvd, 0);
			if (iRecvd <= 0) {
				fError = TRUE;
				break;
			}

			iTotalRecvd += iRecvd;
		}

		if (fError) {
			// The other side had just closed cconnection. If we are not done and are writing,
			// the writer thread will error out. Otherwise, we just become inactive...
			if ((iTotalRecvd == 0) && (fSessionState == SCSESSION_STATE_OPERATING)) {
				fSessionState = SCSESSION_STATE_INACTIVE;
				break;
			}

#if defined (SC_VERBOSE)
			scerror_DebugOut (VERBOSE_MASK_SESSION, L"Error receiving a packet from %s (%d bytes received)\n", lpszHostName, iTotalRecvd);
#endif
			break;
		}

#if defined (SC_VERBOSE)
		scerror_DebugOut (VERBOSE_MASK_SESSION, L"Received a packet from %s\n", lpszHostName);
#endif
		CBaseHeader *pBaseHeader = (CBaseHeader *)__buf;

		if (! (pBaseHeader->SignatureIsValid() &&  pBaseHeader->VersionIsValid())) {
#if defined (SC_VERBOSE)
			scerror_DebugOut (VERBOSE_MASK_SESSION, L"Bad packet from %s: incorrect version or signature\n", lpszHostName);
#endif
			break;
		}

        int iPacketSize;	// Has to be multiple of 4 and more than just header
		if (((iPacketSize = pBaseHeader->GetPacketSize()) <= iHeaderSize) ||
			(iPacketSize & 3)) {
#if defined (SC_VERBOSE)
			scerror_DebugOut (VERBOSE_MASK_SESSION, L"Bad packet from %s: too small (%d bytes)\n", lpszHostName, iPacketSize);
#endif
			break;
		}

		CSessionSection *pcSessionSection = NULL;

		int iTotalSize = iPacketSize;

		if (pBaseHeader->GetType() != FALCON_INTERNAL_PACKET) {
			iTotalSize += (pBaseHeader->SessionIsIncluded() ? CSessionSection::CalcSectionSize(): 0);

			pImage = (ScPacketImage *)g_funcAlloc (sizeof (*pImage) + iTotalSize, g_pvAllocData);
			if (! pImage)
				break;

			gMem->Lock ();
			++gSessionMan->fBusy;
			gMem->Unlock ();

			memset (&pImage->sect, 0, sizeof(pImage->sect));
			memset (&pImage->ucSourceAddr, 0, sizeof(pImage->ucSourceAddr));

			pImage->allflags = 0;
			pImage->flags.fSecureSession = ! gMachine->fUntrustedNetwork;
			pImage->hkOrderKey = 0;
			pImage->ipSourceAddr   = ipPeerAddr;
			pImage->pvBinary = NULL;
			pImage->pvExt    = NULL;

			void *pvBinaryStart = ((char *)pImage + sizeof(*pImage));
			memcpy (pvBinaryStart, __buf, iHeaderSize);

			pImage->flags.fHaveIpv4Addr = TRUE;

			pBaseHeader = (CBaseHeader *)pvBinaryStart;
			pcBuffer    = (char *)pBaseHeader;

			if (pBaseHeader->SessionIsIncluded())
				pcSessionSection = (CSessionSection *)(pcBuffer + iPacketSize);
		} else
			pcBuffer = __buf;

		while (iTotalRecvd < iTotalSize) {
			int iRecvd = recv (s, &pcBuffer[iTotalRecvd], iTotalSize - iTotalRecvd, 0);
			if (iRecvd <= 0) {
				fError = TRUE;
				break;
			}

			iTotalRecvd += iRecvd;
		}

		if (fError) {
#if defined (SC_VERBOSE)
			scerror_DebugOut (VERBOSE_MASK_SESSION, L"Error receiving a packet from %s (%d bytes out of %d received)\n", lpszHostName, iTotalRecvd, iTotalSize);
#endif
			if (pImage) {
				g_funcFree (pImage, g_pvFreeData);
				gMem->Lock ();
				--gSessionMan->fBusy;
				gMem->Unlock ();
			}

			break;
		}

		gMem->Lock ();

		int fRes;

		if (pImage) {
			fRes = HandleUserPacket (pImage, pcSessionSection);
			--gSessionMan->fBusy;
		} else
			fRes = HandleInternalPacket (pBaseHeader);

		gMem->Unlock ();

		if (! fRes)
			break;
	}

	if (fSessionState == SCSESSION_STATE_EXITING)
		return;

	gMem->Lock ();
	if (fSessionState == SCSESSION_STATE_OPERATING)
		FailConnection ();

	CloseHandle (hServiceThreadR);
	hServiceThreadR = NULL;
	SetEvent (hEvent);					// Thread exited
	gMem->Unlock ();
}

void ScSession::ReturnUnacketPacketsToQueues(void) {
	//
	//	Unacked packets return to the respective queues...
	//
    while (pSentPackets) {
        SentPacket *pSentNext = pSentPackets->pNext;
		SVSUTIL_ASSERT (! pSentPackets->pPacket->pQueue->qp.bIsIncoming);
#if defined (SC_VERBOSE)
        scerror_DebugOut (VERBOSE_MASK_SESSION, L"Returning express unacked message %08x ptr %08x to %s\n", pSentPackets->pPacket->uiMessageID, pSentPackets->pPacket, pSentPackets->pPacket->pQueue->lpszFormatName);
#endif
        pSentPackets->pPacket->pQueue->InsertPacket (pSentPackets->pPacket);
        svsutil_FreeFixed (pSentPackets, gMem->pAckNodeMem);
        pSentPackets = pSentNext;
    }

    while (pSentRelPackets) {
        SentPacket *pSentNext = pSentRelPackets->pNext;
		SVSUTIL_ASSERT (! pSentRelPackets->pPacket->pQueue->qp.bIsIncoming);
#if defined (SC_VERBOSE)
        scerror_DebugOut (VERBOSE_MASK_SESSION, L"Returning reliable unacked message %08x ptr %08x to %s\n", pSentRelPackets->pPacket->uiMessageID, pSentRelPackets->pPacket, pSentRelPackets->pPacket->pQueue->lpszFormatName);
#endif
        pSentRelPackets->pPacket->pQueue->InsertPacket (pSentRelPackets->pPacket);
        svsutil_FreeFixed (pSentRelPackets, gMem->pAckNodeMem);
        pSentRelPackets = pSentNext;
    }
}

void ScSession::FinishSession (void) {
	SVSUTIL_ASSERT (gMem->IsLocked ());

#if defined  (SC_VERBOSE)
	scerror_DebugOut (VERBOSE_MASK_SESSION, L"Finishing session...\n");
#endif

	int fSessStateSav = fSessionState;
	fSessionState = SCSESSION_STATE_EXITING;	// Temporarily so that it will exit without locking
	ipPeerAddr.S_un.S_addr = INADDR_NONE;

	if (s != INVALID_SOCKET) {
		closesocket (s);
		s = INVALID_SOCKET;
	}

	if (hServiceThreadR) {
		if (WaitForSingleObject (hServiceThreadR, SC_THREAD_WAIT2) == WAIT_TIMEOUT) {
			scerror_Inform (MSMQ_SC_ERRMSG_READERKILLED, lpszHostName);
			TerminateThread (hServiceThreadR, 0);
		}

		CloseHandle (hServiceThreadR);
	}

	hServiceThreadR = NULL;

	fSessionState = fSessStateSav;

	if (gMachine->fUseSRMP)
		SRMPCloseSession();

	gSessionMan->ReleaseThreadPair ();

	CloseHandle (hEvent);
	hEvent = NULL;
	CloseHandle (hServiceThreadW);
	hServiceThreadW = NULL;

	memset (&guidDest, 0, sizeof(guidDest));

	uiConnectionStamp	= 0;
	uiAckTimeout		= 0;
	uiStoreAckTimeout	= 0;
	uiMyWindowSize		= 0;
	uiOtherWindowSize   = 0;

	ReturnUnacketPacketsToQueues();

    SVSUTIL_ASSERT (! pSentPackets);
    SVSUTIL_ASSERT (! pSentRelPackets);
}

int ScSession::MakeSessionSect (CSessionSection *pSessSect, ScPacket *pPacket, int fForce) {
	SVSUTIL_ASSERT (sessnum_greater_equal (usRelPacketsReceived, usLastRelAckSent));

	unsigned short usRelFirstUnacked = usLastRelAckSent + 1;
	if (! usRelFirstUnacked)
		++usRelFirstUnacked;

	int iRelPacketsToAck = (signed short)((signed short)usRelPacketsReceived - (signed short)usRelFirstUnacked + 1);
	if (iRelPacketsToAck > STORED_ACK_BITFIELD_SIZE)
		iRelPacketsToAck = STORED_ACK_BITFIELD_SIZE;

	unsigned int   uiRelBitMask = (iRelPacketsToAck < 2) ? 0 : ~((-1) << (iRelPacketsToAck - 1));

	pSessSect->CSessionSection::CSessionSection(usPacketsReceived, iRelPacketsToAck ? usRelFirstUnacked : 0, uiRelBitMask,
												usPacketsSent, usRelPacketsSent, uiMyWindowSize);

    int iPacketSize = 0;

	if (pPacket)
		iPacketSize = pPacket->pImage->sect.pBaseHeader->GetPacketSize();

	if ((fForce) || ((uiAckDue && time_greater_equal (GetTickCount(), uiAckDue)) ||
		sessnum_greater_equal (usPacketsReceived, (unsigned short)(usLastAckSent + uiOtherWindowSize)) ||
		sessnum_greater_equal (usRelPacketsReceived, (unsigned short)(usLastRelAckSent + STORED_ACK_BITFIELD_SIZE)))) {

		if (pPacket) {
			pPacket->pImage->sect.pBaseHeader->IncludeSession(TRUE);

			iPacketSize += CSessionSection::CalcSectionSize();
		}

		usLastAckSent = usPacketsReceived;
		usLastRelAckSent = usRelFirstUnacked + iRelPacketsToAck - 1;

        if (usLastRelAckSent == usRelPacketsReceived) {
			uiAckDue      = 0;
			svsutil_ClearAttrTimer (gMem->pTimer, (SVSHandle)hEvent);
		}
	}

	return iPacketSize;
}

int ScSession::SendAck (void) {
	for ( ; ; ) {
		SVSUTIL_ASSERT (gMem->IsLocked ());

        if (((! uiAckDue) || time_less (GetTickCount(), uiAckDue)) &&
			sessnum_less (usPacketsReceived, (unsigned short)(usLastAckSent + uiOtherWindowSize)) &&
			sessnum_less (usRelPacketsReceived,  (unsigned short)(usLastRelAckSent + STORED_ACK_BITFIELD_SIZE)))
			return TRUE;

#if defined (SC_VERBOSE)
		scerror_DebugOut (VERBOSE_MASK_SESSION, L"Sending ACK for %d(%d)th packet(s) for %s\n", usPacketsReceived, usRelPacketsReceived, lpszHostName);
#endif

		const int iPacketSize = sizeof(CBaseHeader) + sizeof(CInternalSection) + sizeof(CSessionSection);
		char __buf[iPacketSize];

		CBaseHeader *pBase = (CBaseHeader *)__buf;

⌨️ 快捷键说明

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