Exemplo n.º 1
0
int CUnconnSocket::SendPingPacket()
{
	//ASSERT(m_pDataHandler);
	if(m_dwState & NAT_E_TIMEOUT) return 1;

	m_nPassivePing++;
	m_SendPingTime = time(NULL);

	T_TRACE("send ping packet for %02X%02X%02X%02X. ConnAck=%08x\n", m_ClientId[0],m_ClientId[1],m_ClientId[2],m_ClientId[3],
		m_dwConnAskNumber);

	if(m_dwClientIp && m_wClientPort)
	{
//		Packet pack(OP_NAT_PING, 20, OP_VC_NAT_HEADER,false);
		uchar pack[20];
		GetMyUserHash(pack);
		memcpy(pack+16, &m_dwConnAskNumber, 4);
		
		//TRACE("\nCUnconnSocket::SendPingPacket Send Ping Successful! IP : %d Port %d\n", m_dwClientIp, m_wClientPort);

		return CNatSocket::SendPacket(m_dwClientIp, m_wClientPort, OP_NAT_PING, pack, 20);
	}

	return -1;
}
Exemplo n.º 2
0
int CNatThread::Send(CAsyncSocketEx * sock, const void * data, int len)
{
	CNatSocket * nsock=NULL;
	CSingleLock locker(&m_Mutex, TRUE);
	m_SockMap.Lookup(sock, nsock);

	int nRet = -1;
	if(nsock)
	{
//		ASSERT(nsock->m_MyVSock == sock->m_MyVSock);
#ifdef _DEBUG_NAT
		const uchar * uh=nsock->GetUserHash();
		T_TRACE("%s: len=%d to %02X%02X%02X%02X",__FUNCTION__, len,
			uh[0],uh[1],uh[2],uh[3]);
#endif
		nRet = nsock->Send(data, len);
	}
	else
	{
		WSASetLastError(WSAEWOULDBLOCK);
		TRACE("->%s:  but no peer to send\n",__FUNCTION__);
	}

	return nRet;
}
Exemplo n.º 3
0
void CSourceExchangeNAT::CheckForTimeOut(CUpDownClient * pClient)
{
	if (pClient->m_nUDPState == UDP_DISCONNECT)
	{
		return;
	}

	if(time(NULL) - pClient->m_dwRegisterTime > 60 * 10)
	{
		byte pack[1+1+16];
		pack[0]         = OP_EMULEPROT;
		pack[1]		    = OP_UDPREGISTER;
		memcpy(pack+2, pClient->GetUserHash(), 16);

		SendUDPPacket(pClient->GetIP(), htons(pClient->GetUDPPort()), pack, 1+1+16, pClient);

		T_TRACE("\nSend Register From CSourceExchangeNAT::CheckForTimeOut.\n");

		pClient->m_dwRegisterTime		= time(NULL);
		pClient->m_dwSendKeepALiveTime	= time(NULL);

		return;
	}

	if(time(NULL) - pClient->m_dwSendKeepALiveTime > TM_KEEPALIVE)
	{
		byte pack[1+1];
		pack[0]         = OP_EMULEPROT;
		pack[1]		    = OP_UDPKEEPALIVE;

		SendUDPPacket(pClient->GetIP(), htons(pClient->GetUDPPort()), pack, 1+1, pClient);

		T_TRACE("\nSend KeepALive From CSourceExchangeNAT::CheckForTimeOut.\n");

		pClient->m_dwSendKeepALiveTime = time(NULL);

		return;
	}
}
int CTraverseBySourceExchange::SendPingPacket()
{
	T_TRACE("\nSend Ping From Source Exchange, IP : %d Port : %d!\n", m_dwClientIp, ntohs(m_wClientPort));

	if(m_dwState & NAT_E_TIMEOUT) return 1;

	m_nPassivePing++;
	m_SendPingTime = time(NULL);

	TRACE("send ping packet for %02X%02X%02X%02X. ConnAck=%08x\n", m_UserHash[0],m_UserHash[1],m_UserHash[2],m_UserHash[3],
		m_dwConnAskNumber);

	if(m_dwClientIp && m_wClientPort)
	{
		uchar pack[20];
		GetMyUserHash(pack);
		memcpy(pack+16, &m_dwConnAskNumber, 4);
		return CNatSocket::SendPacket(m_dwClientIp, m_wClientPort, OP_NAT_PING, pack, 20);
	}

	return -1;
}
int CTraverseBySourceExchange::SendConnectReq()
{
	if(m_dwState & NAT_E_TIMEOUT) return 1;

	m_SendReqTime = time(NULL);
	m_nSendReqCount++;
	m_dwNextSyncInterval = min(64, ExpoBackoff(SYNC_INIT_ATTEMPT_INTERVAL, m_nSendReqCount));

	CUpDownClient * pClient = CGlobalVariable::clientlist->FindClientByUserHash(m_UserHash);

	if (pClient)
	{
		const CUpDownClient * pHighClient = pClient->GetSourceExchangeClient();

		
		//ASSERT(pHighClient); //COMMENTED by VC-fengwen on 2007/11/16 : 程序运行过程中帮自己打洞的HighId是有可能不在了的。已做了这方面的处理了。

		if (pHighClient == NULL)
		{
			return -1;
		}

		byte pack[1+1+16+16+4];
		pack[0]         = OP_EMULEPROT;
		pack[1]		    = OP_UDPSENATREQ;	
		memcpy(pack+2, m_UserHash, 16);
		memcpy(pack+18, thePrefs.GetUserHash(), 16);
		memcpy(pack+34, &m_dwConnAskNumber, 4);

		T_TRACE("\nSend UDP SourceExchange NAT Request, IP : %d PORT : %d!\n", pHighClient->GetIP(), pHighClient->GetUDPPort());

		return CNatSocket::SendPacket(pHighClient->GetIP(), htons(pHighClient->GetUDPPort()), pack, 1+1+16+16+4);
	}
	else
	{
		return -1;
	}
}
Exemplo n.º 6
0
bool CSourceExchangeNAT::ProcessTCPPacket(const BYTE* packet, uint32 size, UINT opcode, UINT /*uRawSize*/, CClientReqSocket * socket)
{
	try
	{
		switch (opcode)
		{
		case OP_TCPSENATREQ:
			{
				T_TRACE("\nReceive TCP SourceExchange NAT Request!\n");

				CSafeMemFile data(packet, size);

				byte * natpack  = new byte[4+1+4+2+16+4];

				memset(natpack, 0, 4+1+4+2+16+4);

				natpack[4] = OP_NAT_SYNC;
				memcpy(natpack+5, packet, size);

				uint32 uUserIP  = data.ReadUInt32();
				uint16 uUdpPort = data.ReadUInt16(); 

				T_TRACE("\nIP:%d Port:%d\n", uUserIP, uUdpPort);

				uchar userhash[16];
				data.ReadHash16(userhash);

				uint32 con = data.ReadUInt32();

				byte * pack     = new byte[1+1+16+16+4];
				pack[0]         = OP_EMULEPROT;
				pack[1]		    = OP_UDPSENATACK;
				memcpy(pack+2, userhash, 16);
				memcpy(pack+18, thePrefs.GetUserHash(), 16);
				memcpy(pack+34, &con, 4);

				T_TRACE("\nSend UDP SourceExchange NAT Response!\n");

				if (!socket->client)
				{
					return false; // VC-SearchDream[2007-04-18]: 
				}

				CNatSocket::SendPacket(socket->client->GetIP(), htons(socket->client->GetUDPPort()), pack, 1+1+16+16+4);

				delete []pack;
				pack = NULL;

				theApp.natthread->ProcessPacket(natpack, 4+1+4+2+16+4, socket->client->GetIP(), htons(socket->client->GetUDPPort()));

				delete []natpack;
				natpack = NULL;

				break;
			}
		case OP_TCPSENATACK:
			{
				CSafeMemFile data(packet, size);

				byte natpack[4+1+4+2+16+4];

				memset(natpack, 0, 4+1+4+2+16+4);

				natpack[4] = OP_NAT_SYNC;
				memcpy(natpack+5, packet, size);

				uint32 uUserIP  = data.ReadUInt32();
				uint16 uUdpPort = data.ReadUInt16(); 

				uchar userhash[16];
				data.ReadHash16(userhash);

				CUpDownClient* pClient = theApp.clientlist->FindClientByUserHash(userhash);

				if (pClient)
				{	
					pClient->SetIP(uUserIP);
					pClient->SetUDPPort(uUdpPort);

					T_TRACE("\nReceive TCP SourceExchange NAT Response!\n");

					theApp.natthread->ProcessPacket(natpack, 4+1+4+2+16+4, socket->client->GetIP(), htons(socket->client->GetUDPPort()));
				}

				break;
			}
		case OP_TCPSECALLBACKREQ:
			{
				CSafeMemFile data(packet, size);
				uchar userhash[16];
				data.ReadHash16(userhash); // Read the Call Back Target Client's UserHash

				CUpDownClient * pClient = theApp.clientlist->FindClientByUserHash(userhash);

				if (pClient)
				{			
					if (!pClient->IsLowToLowClient() && (pClient->socket && pClient->socket->IsConnected()))
					{
						CSafeMemFile fileIO(16+6);
						fileIO.WriteHash16(socket->client->GetUploadFileID());
						fileIO.WriteUInt32(socket->client->GetIP());
						fileIO.WriteUInt16(socket->client->GetUserPort());

						Packet* pPacket = new Packet(&fileIO, OP_EMULEPROT, OP_SECALLBACK);

						pClient->socket->SendPacket(pPacket, true, true, 0, true);
					}
					else
					{
						byte pack[1+1+16+6];
						pack[0]         = OP_EMULEPROT;
						pack[1]		    = OP_SECALLBACK;

						uint32 ip   = socket->client->GetIP();
						uint16 port = socket->client->GetUserPort();

						memcpy(pack+2,  socket->client->GetUploadFileID(), 16);
						memcpy(pack+18, &ip, 4);
						memcpy(pack+22, &port, 2);

						SendUDPPacket(pClient->GetIP(), htons(pClient->GetUDPPort()), pack, 1+1+16+6, pClient);
					}
				}

				break;
			}
		case OP_SECALLBACK:
			{
				CSafeMemFile data(packet, size);

				uchar fileid[16];
				data.ReadHash16(fileid);

				CKnownFile* reqfile;

				if ( (reqfile = theApp.sharedfiles->GetFileByID(fileid)) == NULL )
				{
					if ( (reqfile = theApp.downloadqueue->GetFileByID(fileid)) == NULL)
					{
						socket->client->CheckFailedFileIdReqs(fileid);
						break;
					}
				}

				uint32 ip  = data.ReadUInt32();
				uint16 tcp = data.ReadUInt16();
				
				CUpDownClient* callback;
				
				callback = theApp.clientlist->FindClientByIP(ntohl(ip), tcp);
				
				if ( callback == NULL )
				{
					callback = new CUpDownClient(NULL,tcp,ip,0,0, true);
					theApp.clientlist->AddClient(callback);
				}

				callback->TryToConnect(true);

				break;
			}
		default:
			{
				return true;
			}
		}
	}
	catch(...)
	{
		return false; // The Process is Over Although Failure
	}

	return false;
}
Exemplo n.º 7
0
bool CSourceExchangeNAT::ProcessUDPPacket(const BYTE* packet, UINT size, uint8 opcode, uint32 ip, uint16 port)
{
	try
	{
		switch (opcode)
		{
		// VC-SearchDream[2007-04-18]: For SourceExchange NAT Begin	
		case OP_UDPSENATREQ:
			{
				CSafeMemFile data(packet, size);
				uchar userhash[16];
				data.ReadHash16(userhash); // Read the NAT Target Client's UserHash

				T_TRACE("\nReceive UDP SourceExchange NAT Request , IP : %d Port : %d!\n", ip, port);

				CUpDownClient * pClient = theApp.clientlist->FindClientByUserHash(userhash);

				if (pClient)
				{
					data.ReadHash16(userhash); // Read the Request Client's UserHash
					uint32 con = data.ReadUInt32();

					try
					{
						if (!pClient->IsLowToLowClient() && (pClient->socket && pClient->socket->IsConnected()))
						{
							//非LTL连接,且处于已连接状态
							CSafeMemFile data_out;
							data_out.WriteUInt32(ip);
							data_out.WriteUInt16(htons(port));
							data_out.WriteHash16(userhash);
							data_out.WriteUInt32(con);

							Packet* natreq = new Packet(&data_out, OP_EMULEPROT, OP_TCPSENATREQ);

							TRACE("\nThe Client is Exist and Send TCP SourceExchange NAT Request!\n");

							pClient->socket->SendPacket(natreq, true, true, 0, true);
						}
						else
						{
							//LTL连接或处于未连接状态
							uint16 uPort = htons(port);

							byte pack[1+1+4+2+16+4];
							pack[0]         = OP_EMULEPROT;
							pack[1]		    = OP_UDPTOUDPSENATREQ;
							memcpy(pack+2, &ip, 4);
							memcpy(pack+6, &uPort, 2);
							memcpy(pack+8, userhash, 16);
							memcpy(pack+24, &con, 4);

							T_TRACE("\nThe Client is Exist and Send UDP SourceExchange NAT Request!\n");

							SendUDPPacket(pClient->GetIP(), htons(pClient->GetUDPPort()), pack, 1+1+4+2+16+4, pClient);
						}
					}
					catch(...)
					{
						return false;
					}	
				}

				break;
			}	
		case OP_UDPSENATACK:
			{
				CSafeMemFile data(packet, size);
				uchar userhash[16];
				data.ReadHash16(userhash); // Read the Request Client's UserHash

				T_TRACE("\nReceive UDP SourceExchange NAT Response , IP : %d Port : %d!\n", ip, port);

				CUpDownClient * pClient = theApp.clientlist->FindClientByUserHash(userhash);

				if (pClient)
				{
					data.ReadHash16(userhash); // Read the NAT Target Client's UserHash
					uint32 con = data.ReadUInt32();

					try
					{
						if (!pClient->IsLowToLowClient() && (pClient->socket && pClient->socket->IsConnected()))
						{
							CSafeMemFile data_out;
							data_out.WriteUInt32(ip);
							data_out.WriteUInt16(htons(port));
							data_out.WriteHash16(userhash);
							data_out.WriteUInt32(con);

							Packet* natack = new Packet(&data_out, OP_EMULEPROT, OP_TCPSENATACK);

							T_TRACE("\nThe Client is Exist and Send TCP SourceExchange NAT Response!\n");

							pClient->socket->SendPacket(natack, true, true, 0, true);
						}
						else 
						{
							uint16 uPort = htons(port);

							byte pack[1+1+4+2+16+4];
							pack[0]         = OP_EMULEPROT;
							pack[1]		    = OP_UDPTOUDPSENATACK;
							memcpy(pack+2, &ip, 4);
							memcpy(pack+6, &uPort, 2);
							memcpy(pack+8, userhash, 16);
							memcpy(pack+24, &con, 4);

							T_TRACE("\nThe Client is Exist and Send UDP SourceExchange NAT Response!\n");

							SendUDPPacket(pClient->GetIP(), htons(pClient->GetUDPPort()), pack, 1+1+4+2+16+4, pClient);
						}
					}
					catch(...)
					{
						return false;
					}
				}
				break;
			}
		case OP_UDPTOUDPSENATREQ:
			{
				T_TRACE("\nReceive UDP SourceExchange NAT Request!\n");

				CSafeMemFile data(packet, size);

				byte * natpack  = new byte[4+1+4+2+16+4];

				memset(natpack, 0, 4+1+4+2+16+4);

				natpack[4] = OP_NAT_SYNC;
				memcpy(natpack+5, packet, size);

				uint32 uUserIP  = data.ReadUInt32();
				uint16 uUdpPort = data.ReadUInt16(); 

				T_TRACE("\nIP:%d Port:%d\n", uUserIP, uUdpPort);

				uchar userhash[16];
				data.ReadHash16(userhash);

				uint32 con = data.ReadUInt32();

				byte * pack     = new byte[1+1+16+16+4];
				pack[0]         = OP_EMULEPROT;
				pack[1]		    = OP_UDPSENATACK;
				memcpy(pack+2, userhash, 16);
				memcpy(pack+18, thePrefs.GetUserHash(), 16);
				memcpy(pack+34, &con, 4);

				T_TRACE("\nSend UDP SourceExchange NAT Response!\n");

				CNatSocket::SendPacket(ip, htons(port), pack, 1+1+16+16+4);

				delete []pack;
				pack = NULL;

				theApp.natthread->ProcessPacket(natpack, 4+1+4+2+16+4, ip, htons(port));

				delete []natpack;
				natpack = NULL;

				break;
			}
		case OP_UDPTOUDPSENATACK:
			{
				CSafeMemFile data(packet, size);

				byte natpack[4+1+4+2+16+4];

				memset(natpack, 0, 4+1+4+2+16+4);

				natpack[4] = OP_NAT_SYNC;
				memcpy(natpack+5, packet, size);

				uint32 uUserIP  = data.ReadUInt32();
				uint16 uUdpPort = data.ReadUInt16(); 

				uchar userhash[16];
				data.ReadHash16(userhash);

				CUpDownClient* pClient = theApp.clientlist->FindClientByUserHash(userhash);

				if (pClient)
				{	
					pClient->SetIP(uUserIP);
					pClient->SetUDPPort(uUdpPort);

					T_TRACE("\nReceive UDP SourceExchange NAT Response!\n");

					theApp.natthread->ProcessPacket(natpack, 4+1+4+2+16+4, ip, htons(port));
				}

				break;
			}
		case OP_UDPREGISTER:
			{
				CSafeMemFile data(packet, size);

				uchar userhash[16];
				data.ReadHash16(userhash); // Read the Request Client's UserHash

				CUpDownClient* pClient = theApp.clientlist->FindClientByUserHash(userhash);

				T_TRACE("\nReceive Register From CSourceExchangeNAT::ProcessUDPPacket\n");

				if (pClient)
				{
					if (port != pClient->GetUDPPort())
					{
						pClient->SetUDPPort(port);
					}

					pClient->SetRegisterTime();
				}

				break;
			}
		case OP_UDPKEEPALIVE:
			{
				CUpDownClient* pClient = theApp.clientlist->FindClientByIP_UDP(ip, port);

				T_TRACE("\nReceive KeepALive From CSourceExchangeNAT::ProcessUDPPacket\n");

				if (pClient)
				{
					pClient->SetReceiveALiveTime();
				}

				break;
			}
			// VC-SearchDream[2007-04-18]: For SourceExchange NAT End
		case OP_SECALLBACK:
			{
				CSafeMemFile data(packet, size);

				uchar fileid[16];
				data.ReadHash16(fileid);

				CKnownFile* reqfile;

				if ( (reqfile = theApp.sharedfiles->GetFileByID(fileid)) == NULL )
				{
					if ( (reqfile = theApp.downloadqueue->GetFileByID(fileid)) == NULL)
					{
						/*socket->client->CheckFailedFileIdReqs(fileid);*/
						break;
					}
				}

				uint32 ip  = data.ReadUInt32();
				uint16 tcp = data.ReadUInt16();

				CUpDownClient* callback;

				callback = theApp.clientlist->FindClientByIP(ntohl(ip), tcp);

				if ( callback == NULL )
				{
					callback = new CUpDownClient(NULL,tcp,ip,0,0, true);
					theApp.clientlist->AddClient(callback);
				}

				callback->TryToConnect(true);

				break;
			}
		default:
			{
				return true;
			}
		}
	}
	catch(...)
	{
		return false; // The Process is Over Although Failure
	}

	return false;
}
Exemplo n.º 8
0
void CTraverseByBuddy::OnRecvPing(const uchar * data, int /*len*/, DWORD ip, WORD port)
{
	//UINT realsize=len-1;
	const uchar * realdata=data+1;

	const uchar * hash=realdata;

	DWORD ConnAck=0;
	memcpy(&ConnAck, hash+16, 4);
	T_TRACE("recv ping 2. %02X%02X%02X%02X, ConnAck=%d\n", hash[0], hash[1], hash[2], hash[3],
		ConnAck);
	CAsyncSocketEx * pASock=NULL;

	if(ConnAck && !m_dwConnAskNumber)
		m_dwConnAskNumber = ConnAck;
	pASock = m_Sock;

	ASSERT(pASock);
	if(!pASock)
	{
		T_TRACE("no AsyncsocketEx for unconnect sk\n");
		Failed();
		return;
	}
	
	CNatSocket * nsock = NULL;

	if( CGlobalVariable::natthread )
	{
		nsock = CGlobalVariable::natthread->FindNatSocket(hash);

		if(nsock)
		{
			Finish();
			return ;
		}
	}
	
	nsock=new CNatSocket(pASock);
	nsock->m_dwConnAskNumber= m_dwConnAskNumber;
	sUserModeTCPConfig * tc=new sUserModeTCPConfig(ip, port);
	nsock->SetConfig(tc);

//	nsock->m_bTraverseBySvr= true;
//	m_dwTraverseBySvr++;
	nsock->m_TraversalType = CNatSocket::Traversal_bybuddy;

	memcpy(nsock->GetUserHash(), hash, 16);
	
	if( CGlobalVariable::natthread )
	{
		CGlobalVariable::natthread->AddNatSocket(pASock, nsock);
		CGlobalVariable::natthread->RemoveUnconnSocket(hash);	//ADDED by VC-fengwen on 2007/10/15 : sock连通后,在unconnectsocket里要清除它。

		_AddLogLine(false, _T("NAT traversal connected. %s."), UserHashToString(hash));

		CGlobalVariable::natthread->RemoveTempASock(hash);
	}

	//pASock->TriggerEvent(FD_CONNECT);
	//pASock->TriggerEvent(FD_WRITE);
	CClientReqSocket * pClientSock = NULL;
	try
	{
		pClientSock = DYNAMIC_DOWNCAST(CClientReqSocket, pASock);
	}
	catch(...)
	{
		TRACE("Exception: %s\n", __FUNCTION__);
		Failed();
		return ;
	}

	if(pClientSock && pClientSock->client)
	{
		pClientSock->client->SetIP(ip);
		pClientSock->client->ResetIP2Country();
	}
	else Failed();

	Finish();
}
Exemplo n.º 9
0
void CTraverseByBuddy::OnRecvSync(const uchar * data, int /*len*/, DWORD /*ip*/, WORD /*port*/)
{
	//UINT realsize=len-1;
	const uchar * realdata=data+1;

	DWORD cip = *(DWORD*)(realdata);
	WORD cport = *(WORD*)(realdata+4);

	if(cip==0 || cport==0)
	{
		return;
	}
	const uchar * id=realdata+6;

	DWORD ConnAck = 0;
	memcpy(&ConnAck, id+16, 4);

	T_TRACE("recv sync, ConnAck=%08x\n", ConnAck);
#ifdef _DEBUG
	in_addr addr;
	addr.s_addr = cip;
	T_TRACE("peer addr of %02X%02X%02X%02X = %s:%d\n", id[0], id[1], id[2],id[3],
		inet_ntoa(addr), ntohs(cport));
#endif
	uchar myid[16];
	GetMyUserHash(myid);
	if(memcmp(id, myid, 16)==0)
	{
		_AddLogLine(false, _T("ERROR: recv myself for traversal"));
		return;
	}

	CAsyncSocketEx * pASock=NULL;
	CUpDownClient * pClient= CGlobalVariable::clientlist->FindClientByUserHash(id);
	if(pClient)
	{
		pASock = pClient->socket;

		if(! pASock)
		{
			CRuntimeClass * pClassSocket = RUNTIME_CLASS(CClientReqSocket);
			CClientReqSocket * socket = static_cast<CClientReqSocket*>(pClassSocket->CreateObject());
			socket->SetClient(pClient);
			if (!socket->Create())
			{
				socket->Safe_Delete();
				return;
			}

			pClient->socket = socket;
			pASock = socket;
		}
		ASSERT(pASock);
		if(! pASock) return;
	}
	else
	{
		T_TRACE("\n->%s: Accept a incoming sock for %02X%02X%02X%02X\n", __FUNCTION__,
			id[0],id[1],id[2],id[3]);
		
		if( CGlobalVariable::natthread )
			pASock = CGlobalVariable::natthread->GetTempASock(id);
	}

	m_dwClientIp = cip;
	m_wClientPort = cport;

	m_dwState |=NAT_S_SYNC;
	SendPingPacket();
}
Exemplo n.º 10
0
bool CNatThread::ProcessPacket(const BYTE* packet, UINT size, uint32 ip, uint16 port)
{
	uint8 opcode=packet[4];
	const uchar * realdata=packet+5;
	UINT realsize=size-5;
	
	CSingleLock locker(&m_Mutex, TRUE);
	
// modiefied by robert, 2010-08-03
// beta版屏蔽try,以求暴露更多问题
#ifndef _BETA
	try
	{
#endif

	switch(opcode)
	{
	case OP_NAT_REPING:
		OnReping(ip, port, realdata, realsize);
		break;
	case OP_NAT_REGISTER:

		// VC-SearchDream[2007-06-15]: Add Login Support
		if (realsize >= 2 && !m_bRegister && ip==m_dwSvrIp && port==m_wSvrPort )
		{
			if (realsize >= 6)
			{
				WORD	port	= *(WORD*)(realdata);
				DWORD	ip		= *(DWORD*)(realdata + 2);

				if (ip != m_dwSvrIp || port != m_wSvrPort)
				{
					m_dwSvrIp = ip;
					m_wSvrPort = port;
					m_bRegister	= false;
					RegisterMe(m_dwSvrIp,m_wSvrPort);
					m_dwRegAttemptTimes = 1;
					m_dwRegNextAttempInterval = INIT_ATTEMPT_INTERVAL*2;
					break;
				}
			}
			else
			{
				WORD  port = *(WORD*)(realdata);

				if (port != m_wSvrPort)
				{
					m_wSvrPort	= port;
					m_bRegister	= false;
					RegisterMe(m_dwSvrIp,m_wSvrPort);
					m_dwRegAttemptTimes = 1;
					m_dwRegNextAttempInterval = INIT_ATTEMPT_INTERVAL*2;
					T_TRACE("new server port : %d.", ntohs(port));
					break;
				}
			}
		}
	
		m_dwSvrRetTime = time(NULL);

		if(!m_bRegister)
		{
			m_bRegister=true;
			m_dwSvrKeepalive = time(NULL);
			m_dwRegAttemptTimes = 0;
			m_dwRegNextAttempInterval = INIT_ATTEMPT_INTERVAL;
			T_TRACE("reset svr time in register");
			AddLogLine(false, _T("Registered to NAT traversal server\n"));
		}

		break;
	case OP_NAT_FAILED:
		{
/*
			if(realdata[0]==2)
			{
				m_bRegister = false;
				break;
			}
			else */if(realdata[0]==1)
			{
				realdata++;
				realsize--;
				int n=realsize/16;

				if(ProcessStrategyPacket(realdata, ip, port, packet+4, size-4))
					break;

				for(int i=0; i<n; i++)
				{
					TRACE(_T("failed conn request for %s\n"),UserHashToString(realdata));
					CUnconnSocket * us= FindUnconnectSocket(realdata);
					if(us) us->m_dwState |= NAT_E_NOPEER;
					realdata+=16;
				}
			}
		}
		break;
	//case OP_NAT_SYNC2:
		//if(ProcessStrategyPacket(realdata+6, ip, port, packet+4, size-4))
		//	break;
		//OnSync2(ip, port, realdata, realsize);
		//break;
	case OP_NAT_SYNC2:
	case OP_NAT_SYNC:
		OnSync(ip, port, realdata, realsize);
		break;
	case OP_NAT_PING:
		OnPing(ip, port, realdata, realsize);
		break;
	case OP_NAT_DATA:
		{
			if(size < 4) // ACK (+ DATA)
				break;

			DWORD ConnAck = 0;
			memcpy(&ConnAck, realdata, 4);
			realdata += 4;
			realsize -= 4;
			CNatSocket* source = FindNatSocket(ip, port, ConnAck);
			if( source == NULL )
			{
#ifdef _DEBUG_NAT
				TRACE("\n*** no nat sock to recv NAT_DATA. connack=%08x\n", ConnAck);
#endif
				uint32 uSequenceNr = PeekUInt32(realdata);
				if(uSequenceNr==1)
				{
					uchar pack[16];
					GetMyUserHash(pack);
					CNatSocket::SendPacket(ip, port, OP_NAT_REPING, pack, 16);
				}
				else 
				{
					CNatSocket::SendPacket(ip, port, OP_NAT_RST, NULL, 0);
				}
				break;
			}


			if(source->ProcessDataPacket(realdata, realsize))
			{
				//TRACE("source->ProcessDataPacket is OK. tag=%08x. Asyncsock=%08x\n", tag,source->GetParent());
				//source->OnReceive(0);
				source->m_Parent->TriggerEvent(FD_READ);
				return true;
			}
			else
			{
				T_TRACE("\nFailed to source->ProcessDataPacket. ConnAck=%08x\n\n", ConnAck);
			}
			break;
		}
	case OP_NAT_ACK:
		{
			DWORD ConnAck = 0;
			memcpy(&ConnAck, realdata, 4);
			realdata+=4;
			realsize-=4;
			CNatSocket* source = FindNatSocket(ip, port, ConnAck);
			if( source == NULL )
			{
#ifdef _DEBUG_NAT
				TRACE("\nsend RST for no nat sock to do NAT_ACK\n");
#endif
				CNatSocket::SendPacket(ip, port, OP_NAT_RST,0,0);
				break;
			}
			source->ProcessAckPacket(realdata, realsize);
			break;
		}
	case OP_NAT_RST:
		{
			break;
		}
	default:
		TRACE("Unknown command\n");
		break;
	}

// modiefied by robert, 2010-08-03
// beta版屏蔽try,以求暴露更多问题
#ifndef _BETA
	}catch(...)
		{
			TRACE("Exception: %s\n", __FUNCTION__);
		}
#endif

	return true;
}
Exemplo n.º 11
0
void CNatThread::OnSync(DWORD ip, WORD port, const uchar * pData, int nDataSize)
{
	// modified by robert, 2010-07-30 加锁
	CSingleLock locker(&m_Mutex, TRUE);

	if(ip==m_dwSvrIp && port==m_wSvrPort)
	{
		m_dwSvrRetTime = time(NULL);
		T_TRACE("reset svr time in sync");
	}

	DWORD cip = *(DWORD*)(pData);
	WORD cport = *(WORD*)(pData+4);

	if(cip==0 || cport==0)
	{
		return;
	}

	const uchar * id=pData+6;
	DWORD ConnAck = 0;
	memcpy(&ConnAck, id+16, 4);

	CNatSocket * nsock=FindNatSocket(id);

	if(nsock)
	{
		nsock->SetTargetAddr(cip, cport);
		if(nsock->m_dwConnAskNumber!=ConnAck)
		{
			// VC-linhai[2007-08-06]:warning C4189: “pOldParent” : 局部变量已初始化但不引用
			//CAsyncSocketEx * pOldParent=nsock->GetParent();
			nsock->RenewNatSock();
			nsock->m_dwConnAskNumber = ConnAck;
		}

		uchar pack[20];
		GetMyUserHash(pack);
		memcpy(pack+16, &nsock->m_dwConnAskNumber, 4);

		nsock->SendPacket(OP_NAT_PING, pack, 20);

		return;
	}

	if(WakeupNatSocketFromPool(id, cip, cport, ConnAck))
		return;

	if(ProcessStrategyPacket(id, ip, port, pData-1, nDataSize+1))  // Include opcode
		return;

	uchar myid[16];
	GetMyUserHash(myid);
	if(memcmp(id, myid, 16)==0)
	{
		_AddLogLine(false, _T("ERROR: recv myself for traversal"));
		return;
	}

	//  create a new unconnect socket

	CAsyncSocketEx * pASock=NULL;
	pASock = GetTempASock(id);
	ASSERT(pASock);

	CUnconnSocket * usock=FindUnconnectSocket(id);// FindUnconnectSocketByIP(cip, cport);
	if(! usock)
	{
		TRACE("create unconnsock for recv sync. asyncsock=%08x\n", pASock);

		usock = new CUnconnSocket(ip, port, pASock, id);
		usock->m_dwConnAskNumber = 0;
		usock->m_dwClientIp = cip;
		usock->m_wClientPort =cport;
		m_UnConnectSocket.AddTail(usock);

		_AddDebugLogLine(false, _T("CNatThread::ProcessPacket Create CUnconnSocket Successful for %s!\n"),ipstr(cip,cport));
	}
	else
	{
		//ASSERT(usock->m_MyVSock==tag);
		usock->m_dwClientIp = cip;
		usock->m_wClientPort = cport;
	}

	usock->m_dwState |=NAT_S_SYNC;
	usock->SendPingPacket();
}
Exemplo n.º 12
0
void CNatThread::OnPing(DWORD ip, WORD port, const uchar * pData, int nDataSize)
{
	// modified by robert, 2010-07-30 加锁
	CSingleLock locker(&m_Mutex, TRUE);

	if(nDataSize==0)
	{
		//数据区长度为0

		if(ip==m_dwSvrIp && port==m_wSvrPort)
		{
			m_dwSvrRetTime = time(NULL);
			T_TRACE("reset svr time in ping");
			return;
		}

		POSITION pos = m_SockMap.GetHeadPosition();
		while(pos)
		{
			CNatSocket * nsock=m_SockMap.GetNext(pos)->m_value;
			if(nsock && nsock->GetTargetIP()==ip && nsock->GetTargetPort()==port)
			{
#ifdef _DEBUG_NAT
				const uchar * id=nsock->GetUserHash();
				TRACE("recv keepalive from %02X%02X%02X%02X \n", id[0],id[1],id[2],id[3]);
#endif
				nsock->m_dwRecvKeepalive = time(NULL);
			}
		}

		pos = m_NatSockPool.GetHeadPosition();
		while(pos)
		{
			CNatSocket * nsock=m_NatSockPool.GetNextValue(pos);
			if(nsock && nsock->GetTargetIP()==ip && nsock->GetTargetPort()==port)
			{
#ifdef _DEBUG_NAT
				const uchar * id=nsock->GetUserHash();
				TRACE("recv keepalive(sock pool) from %02X%02X%02X%02X \n", id[0],id[1],id[2],id[3]);
#endif
				nsock->m_dwRecvKeepalive = time(NULL);
			}
		}

		return;
	}

	//数据区长度非0,数据区为user hash, Connack
	const uchar * hash=pData;

	
	if(ProcessStrategyPacket(hash, ip, port, pData-1, nDataSize+1))  //  Include opcode
		return;//必然不返回

	DWORD ConnAck=0;
	memcpy(&ConnAck, hash+16, 4);
	TRACE("recv ping 1. %02X%02X%02X%02X, ConnAck=%d\n", hash[0], hash[1], hash[2], hash[3],
		ConnAck);

	CAsyncSocketEx * pASock=NULL;
	CUnconnSocket * usock=FindUnconnectSocket(hash);
	if(usock)
	{
		//发现此未连接用户

		if(ConnAck && !usock->m_dwConnAskNumber)
			usock->m_dwConnAskNumber = ConnAck;
		pASock = usock->m_Sock;

		if(!pASock)
		{
			//未发现此用户套接字

			TRACE("no AsyncsocketEx for unconnect sk\n");
			POSITION pos = m_UnConnectSocket.GetHeadPosition(), curPos;

			while(pos)
			{
				curPos = pos;
				CUnconnSocket * us= m_UnConnectSocket.GetNext(pos);
				if(us && memcmp(us->m_ClientId, hash, 16)==0)
				{
					TRACE("remove invalid unconnected sk\n");

					RemoveSocketInUnconn(curPos);
					break;
				}
			}
			return;
		}
	}
	else
	{
		//未发现此未连接用户

		if(nDataSize>20) return;

		CNatSocket * nsock = FindNatSocket(hash);

		if(! nsock)
		{
			//未发现此nat用户
			nsock =WakeupNatSocketFromPool(hash);
			if(! nsock)
			{
				TRACE("*** recv a invalid ping.  %02X%02X%02X%02X\n", hash[0], hash[1], hash[2], hash[3]);
				return;
			}
			if(ConnAck) nsock->m_dwConnAskNumber = ConnAck;
		}

		if(nsock->m_dwConnAskNumber!=ConnAck)
		{
			T_TRACE("invalid ConnAck for ping.ConnAck=%d", ConnAck);
			return;
			//nsock->DumpData();
		}

		nsock->m_UserModeTCPConfig->TargetIP = ip;
		nsock->m_UserModeTCPConfig->TargetPort = port;
		uchar pack[21];
		GetMyUserHash(pack);
		memcpy(pack+16, &ConnAck, 4);

		nsock->SendPacket(OP_NAT_PING, pack, 21);
		TRACE("I am connected, echo a ping for connecting.  %02X%02X%02X%02X\n", hash[0], hash[1], hash[2], hash[3]);

		//nsock->GetParent()->TriggerEvent(FD_CONNECT);
		return;
	}

	//发现此用户套接字,此部分不可能被执行到
	ASSERT(pASock);
	CNatSocket * nsock=new CNatSocket(pASock);
	nsock->m_dwConnAskNumber= usock->m_dwConnAskNumber;
	sUserModeTCPConfig * tc=new sUserModeTCPConfig(ip, port);
	nsock->SetConfig(tc);
	nsock->m_dwRecvKeepalive = time(NULL);
	//if(! usock->m_bByBuddy)
	//{
	//	nsock->m_bTraverseBySvr= true;
	//	m_dwTraverseBySvr++;
	//}
	nsock->m_TraversalType = CNatSocket::Traversal_bysvr;

	ASSERT(m_SockMap.Lookup(pASock)==0);
	//m_SockMap.SetAt(pASock, nsock);
	AddNatSocket(pASock, nsock);
	memcpy(nsock->GetUserHash(), hash, 16);
	POSITION pos =m_UnConnectSocket.Find(usock);
	if(pos)
	{
		m_UnConnectSocket.RemoveAt(pos);
	}

	_AddLogLine(false, _T("NAT traversal connected. %s."), UserHashToString(hash));

	RemoveTempASock(hash);

	//nsock->m_Parent->TriggerEvent(FD_CONNECT);
	//nsock->m_Parent->TriggerEvent(FD_WRITE);
	CClientReqSocket * pClientSock = DYNAMIC_DOWNCAST(CClientReqSocket, pASock);
	if(pClientSock && pClientSock->client)
	{
		pClientSock->client->SetIP(ip);
		pClientSock->client->ResetIP2Country();
	}
	delete usock;
}
Exemplo n.º 13
0
void CNatThread::OnReping(DWORD ip, WORD port, const uchar * pData, int nDataSize)
{
	CNatSocket * nsock=NULL;

	// modified by robert, 2010-07-30 加锁
	CSingleLock locker(&m_Mutex, TRUE);

	POSITION pos = m_SockMap.GetHeadPosition();

	while(pos)
	{
		CNatSocket * tmp=m_SockMap.GetNext(pos)->m_value;
		if(tmp && memcmp(pData, tmp->GetUserHash(), 16)==0)
		{
			nsock = tmp;
			break;
		}
	}

	T_TRACE("%s, nDataSize=%d. %02X%02X%02X%02X", __FUNCTION__ , nDataSize, pData[0],pData[1],pData[2],pData[3]);

	if(nDataSize==16)
	{
		if(!nsock)
		{
			T_TRACE("no NatSock for REPING 1. %02X%02X%02X%02X", pData[0],pData[1],pData[2],pData[3]);
			return;
		}
		uchar pack[20];
		GetMyUserHash(pack);
		memcpy(pack+16, &nsock->m_dwConnAskNumber, 4);
		CNatSocket::SendPacket(ip, port, OP_NAT_REPING, pack, 20);
	}
	else if(nDataSize==20)
	{
		DWORD dwConnAck=0;
		memcpy(&dwConnAck, pData+16, 4);

		T_TRACE("reping tell ConnAck=%d", dwConnAck);

		if(! dwConnAck) return;

		if(nsock)
		{
			nsock->m_dwConnAskNumber = dwConnAck;
			return;
		}

		//  from natsock pool 
		CNatSocket * nsock_inpool=NULL;
		if(m_NatSockPool.Lookup(pData, nsock_inpool))
		{
			m_NatSockPool.RemoveKey(pData);
			nsock_inpool->m_Parent = CGlobalVariable::listensocket->OnAcceptEx(0);
			nsock_inpool->m_dwConnAskNumber=dwConnAck;

			ASSERT(nsock_inpool->m_UserModeTCPConfig);
			nsock_inpool->m_UserModeTCPConfig->TargetIP = ip;
			nsock_inpool->m_UserModeTCPConfig->TargetPort = port;

			//m_SockMap.SetAt(nsock_inpool->m_Parent, nsock_inpool);
			AddNatSocket(nsock_inpool->m_Parent, nsock_inpool);
			RemoveUnconnSocket(pData); //ADDED by VC-fengwen on 2007/10/15 : sock连通后,在unconnectsocket里要清除它。

			return;
		}

		CAsyncSocketEx * pASock = RemoveUnconnSocket(pData);

		if(!pASock) pASock = CGlobalVariable::listensocket->OnAcceptEx(0);

		CNatSocket * nsock=new CNatSocket(pASock);
		nsock->m_dwConnAskNumber =dwConnAck ;
		memcpy(nsock->GetUserHash(), pData, 16);
		sUserModeTCPConfig * tc=new sUserModeTCPConfig(ip, port);
		nsock->SetConfig(tc);
		nsock->m_dwRecvKeepalive = time(NULL);

		//m_SockMap.SetAt(pASock, nsock);
		AddNatSocket(pASock, nsock);
	}
}