コード例 #1
0
ファイル: tuxreader.c プロジェクト: Felipeasg/TuxPLC
int DisconnectPlc(PLC *plc)
{
	if (plc==NULL) return(0);
	Log(LOG_DEBUG,"Entering DisconnectPlc (%s)\n",plc->PlcName);
	if (plc->Connection!=NULL)
	{
		Log(LOG_DEBUG,"DisconnectPlc : Connection %p (%d References)\n",plc->Connection,plc->Connection->References);
		plc->Connection->References--;
		if (plc->Connection->References<=0)
		{
			Log(LOG_DEBUG,"DisconnectPlc : No more Reference to Connection %p, closing\n",plc->Connection);
			KillConnection(plc->Connection);
		}
	}
	if (plc->Session!=NULL)
	{
		Log(LOG_DEBUG,"DisconnectPlc : Session %p (%d References)\n",plc->Session,plc->Session->References);
		plc->Session->References--;
		if (plc->Session->References<=0)
		{
			Log(LOG_DEBUG,"DisconnectPlc : No more Reference to Session %p, closing\n",plc->Session);
			KillSession(plc->Session);
		}
	}
	plc->Connection=NULL;
	plc->Session=NULL;
	return(0);
}
コード例 #2
0
Connection::~Connection()
{
	LogMessage("[%d] Connection Destroyed\n", m_RecvThreadHandle);
	
	KillConnection();
	
	// Let thread know it is terminated.
	if (!m_TcpThreadTerminated)
	{
		m_TcpThreadTerminated = true;
		WakeupThread();

		m_Mutex.Lock();
		Sleep(1);
		m_Mutex.Unlock();
	}

	delete m_SendQueue;
}
コード例 #3
0
void Connection::RunRecvThread()
{
	bool isSocketReady	= false;		// Used for checking Socket state
	int numretries		= 0;

	int received;
	unsigned short bytes;
	short opcode;

	EnbTcpHeader header;
	char *ptr_hdr = (char*)&header;

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

	while (!g_ServerShutdown && !m_TcpThreadTerminated)
	{
		while (m_TcpThreadRunning)
		{
			// Do the key exchange if it hasn't been done yet
			if (!m_KeysExchanged)
			{
				if (!RunKeyExchange())
				{
					// Key Exchange failed.
					KillConnection();
					break;
				}
				else
				{
					m_KeysExchanged = true;
				}
			}

			// Main Loop

			isSocketReady = SocketReady(1);		// One Second Timeout

			if ( isSocketReady && (recv(m_Socket, ptr_hdr, 4, 0) == 4) )
			{
				m_InactivityTimer = 0;				

				if (m_PacketLoggingEnabled)
				{
					LogMessage("[%d] Received 4 byte header (encrypted):\n", m_RecvThreadHandle);
					DumpBuffer((unsigned char *) &header, 4);
				}

				if (m_ServerType != CONNECTION_TYPE_SECTOR_SERVER_TO_PROXY && m_ServerType != CONNECTION_TYPE_GLOBAL_PROXY_TO_SERVER)
				{
					m_CryptIn.RC4((unsigned char *) &header, 4);
				}

				if (m_PacketLoggingEnabled)
				{
					LogMessage("[%d] Received 4 byte header (decrypted):\n", m_RecvThreadHandle);
					DumpBuffer((unsigned char *) &header, 4);
				}

				bytes	= header.size - sizeof(EnbTcpHeader);	// Bytes to fetch
				opcode	= header.opcode;			// Opcode for this packet

				// This buffer check MUST be in place
				if ( (bytes > MAX_BUFFER) )
				{
					LogMessage("[%d] Received packet with incorrect payload length: opcode = 0x%02x, length = %d. Aborting.\n", m_RecvThreadHandle, opcode, bytes);
					
					KillConnection();			// We're not permitting a 2nd chance.
					break;
				}

				//LogMessage("Received packet: opcode = 0x%02x, length = %d\n", opcode, bytes);
				
				received = recv(m_Socket, (char *) m_RecvBuffer, bytes, 0);
				numretries = 0;

				while ( received != bytes && 			// Did we fetch everything?
					SocketReady() && 			// Can we still get more?
					numretries < MAX_RETRIES &&		// Can we still retry to get more?
					m_TcpThreadRunning )			// And we haven't been told to stop?
				{
					int rcv = recv(m_Socket, (char *) (m_RecvBuffer + received), bytes - received, 0);
					if (rcv > 0)
					{
						received += rcv;
					}
					else break;

					numretries++;				// Prevent an infinite loop
				}

				if ( received == bytes && m_TcpThreadRunning )	// We got the whole package and we haven't been told top stop
				{
					if (m_ServerType != CONNECTION_TYPE_SECTOR_SERVER_TO_PROXY && m_ServerType != CONNECTION_TYPE_GLOBAL_PROXY_TO_SERVER)
					{
						m_CryptIn.RC4(m_RecvBuffer, bytes);
					}

					if (m_PacketLoggingEnabled)
					{
						LogMessage("[%d] Received %d byte packet\n", m_RecvThreadHandle, received);
						DumpBuffer(m_RecvBuffer,bytes);
					}

					switch (m_ServerType)
					{
						case CONNECTION_TYPE_CLIENT_TO_GLOBAL_SERVER :
							ProcessGlobalServerOpcode(opcode, bytes);
							break;

						case CONNECTION_TYPE_CLIENT_TO_MASTER_SERVER :
							ProcessMasterServerOpcode(opcode, bytes);
							break;

						case CONNECTION_TYPE_CLIENT_TO_SECTOR_SERVER :
							//ProcessSectorServerOpcode(opcode, bytes);
							LogMessage("[%d] ERROR!!: Sector Server opcode received!\n", m_RecvThreadHandle);
							break;

						case CONNECTION_TYPE_MASTER_SERVER_TO_SECTOR_SERVER :
							ProcessMasterServerToSectorServerOpcode(opcode, bytes);
							break;

						case CONNECTION_TYPE_SECTOR_SERVER_TO_SECTOR_SERVER :
							ProcessSectorServerToSectorServerOpcode(opcode, bytes);
							break;

						case CONNECTION_TYPE_SECTOR_SERVER_TO_PROXY:
							ProcessProxyClientOpcode(opcode, bytes);
							break;

						case CONNECTION_TYPE_GLOBAL_PROXY_TO_SERVER:
							ProcessProxyGlobalOpcode(opcode, bytes);
							break;

						default:
							LogMessage("[%d] ERROR: Unknown type of connection.\n", m_RecvThreadHandle);
							m_TcpThreadRunning = false; // Shouldn't happen (but was able to with a buffer overflow).
							break;
					}
				}
				else
				{
					// Error Stage

					if (m_TcpThreadRunning) // We weren't told to stop, but never got our whole packet
					{
						LogMessage("[%d] Error receiving TCP packet on port %d, got %d bytes, expecting %d -- aborting!\n", m_RecvThreadHandle,m_TcpPort, received, bytes);
						if (received > 0 && g_Debug && received < 10000) DumpBuffer(m_RecvBuffer, received);
					}

					m_TcpThreadRunning = false;
				}
			}
			else
			{
				// Check Connection Status

				DWORD error = WSAGetLastError();
				if ( !isSocketReady && error == 0 )
				{
					m_InactivityTimer++;

					if ( (m_MaxInactivityTime > 0) && (m_InactivityTimer > m_MaxInactivityTime) )
					{
						LogMessage("[%d] TCP connection on port %d exceeded maximum inactivity. Aborting.\n", m_RecvThreadHandle, m_TcpPort);

						m_TcpThreadRunning = false;
					}
				}
				else
				{
					switch (error)
					{
						case 0:
							LogMessage("[%d] TCP connection on port %d gracefully closed\n", m_RecvThreadHandle, m_TcpPort);
							break;
						case WSAECONNRESET:
							LogMessage("[%d] TCP connection on port %d was reset\n", m_RecvThreadHandle, m_TcpPort);
							break;
						default:
							LogMessage("[%d] TCP error on port %d (Error %d). Aborting.\n", m_RecvThreadHandle, m_TcpPort, error);
							break;
					}
					
					m_TcpThreadRunning = false;
				}
			}
		}

		KillConnection();		

		// m_TcpThreadRunning was set to false. Go to sleep...		
#ifdef WIN32
		SuspendThread(m_RecvThreadHandle);
#else
		pthread_cond_wait(&m_RecvThreadCond, &m_RecvThreadMtx);
#endif
	}

	m_TcpThreadTerminated = true;
}