コード例 #1
0
void CTraverseBySourceExchange::SendPacket()
{
	m_bFailed = m_dwState & NAT_E_NOPEER;

	try
	{
		if(!m_bFailed && (m_dwState&NAT_S_SYNC)==0 && time(NULL)-m_SendReqTime > 5) //  5 seconds
		{
			//  failed to connect
			if(m_nSendReqCount > 12)
			{
				m_dwState|=NAT_E_TIMEOUT;
				if(m_nSendReqCount>23)
					Failed();
				m_nSendReqCount++;
			}
			else
			{
				if(m_nSendReqCount==0)
					_AddLogLine(false, _T("Begin to connect %s."), UserHashToString(m_UserHash));
				SendConnectReq();
			}
		}

		if(m_bFailed)
		{
			if(m_Sock)// && pClientSock->client)
			{
				//m_Sock->m_bUseNat = false;
			}

			if(m_dwState & NAT_E_NOPEER)
			{
				_AddLogLine(false, _T("Unconnected NatSock was deleted. server return E_NOPEER. %s."), UserHashToString(m_UserHash));
			}
			else
			{
				_AddLogLine(false, _T("Unconnected NatSock was deleted. time out. %s."), UserHashToString(m_UserHash));
			}
		}

		if(m_dwState & NAT_S_SYNC && time(NULL)-m_SendPingTime >4)
		{
			if(m_nPassivePing> 15)
			{
				_AddLogLine(false, _T("Passive Unconnected NatSock was deleted. timeout. %s."), UserHashToString(m_UserHash));
				Failed();
			}
			else 
			{
				SendPingPacket();
			}
		}
	}
	catch(...)
	{
		//  the CAsyncSocketEx maybe is deleted
		Failed();
	}
}
コード例 #2
0
ファイル: NatThread.cpp プロジェクト: techpub/archive-code
void CNatThread::RemoveNatSocket(const uchar *UserId)
{
	USERHASH k(UserId);
	CNatSocket * nsock=NULL;

	CSingleLock locker(&m_Mutex, TRUE);
	if(m_NatSockPool.Lookup(k, nsock))
	{
		m_NatSockPool.RemoveKey(k);
		_AddLogLine(false, _T("NatSock (in sock pool) was deleted. by above application. %s."), UserHashToString(nsock->GetUserHash()));
		delete nsock;
	}
}
コード例 #3
0
void CTraverseByBuddy::SendPacket()
{
	try
	{
		if(!m_bFailed && (m_dwState&NAT_S_SYNC)==0 && time(NULL)-m_SendReqTime > 10)
		{
			//  failed to connect
			if(m_nSendReqCount>60)
			{
				m_dwState|=NAT_E_TIMEOUT;
				if(m_nSendReqCount>70)
					Failed();
				m_nSendReqCount++;
			}
			else
			{
				SendConnectReq();
				SendPingPacket();
			}
		}

		if(m_bFailed)
		{
			if(m_Sock)// && pClientSock->client)
			{
				//m_Sock->m_bUseNat = false;
			}
			_AddLogLine(false, _T("Unconnected NatSock was deleted. time out. %s."), UserHashToString(m_UserHash));
		}
	}
	catch(...)
	{
		//  the CAsyncSocketEx maybe is deleted
		TRACE("Exception: %s\n", __FUNCTION__);
		Failed();
	}
}
コード例 #4
0
ファイル: NatThread.cpp プロジェクト: techpub/archive-code
void CNatThread::RemoveSocket(CAsyncSocketEx * sock,bool bDisconnectAll/*=false*/,const uchar* pUserHash/*=NULL*/)
{
	//AFX_MANAGE_STATE(AfxGetStaticModuleState())

	CSingleLock locker(&m_Mutex, TRUE);
	CNatSocket *nsock=NULL;
	m_SockMap.Lookup(sock, nsock);
	if(nsock)
	{
#ifdef _DEBUG_NAT
		_AddLogLine(false, _T("NatSock was put into pool. by above application. %s."), UserHashToString(nsock->GetUserHash()));
#endif
		m_SockMap.RemoveKey(sock);
		RemoveTempASock(nsock->GetUserHash());

		if(bDisconnectAll)
		{
			delete nsock;
		}
		else
		{
			nsock->DumpData();
			nsock->m_Parent = NULL;
			nsock->m_dwConnAskNumber = 0;
			m_NatSockPool.SetAt(nsock->GetUserHash(), nsock);
		}				
	}

	RemoveSocketInUnconn(sock);

	if( bDisconnectAll && pUserHash )
	{
		RemoveStrategy( pUserHash );
		RemoveNatSocket( pUserHash );
	}
}
コード例 #5
0
void CTraverseBySourceExchange::OnRecvPing(const uchar * data, int /*len*/, DWORD ip, WORD port)
{
	if( NULL==CGlobalVariable::natthread )
		return;

	TRACE("\nReceive Ping From Source Exchange!\n");

	// For the strict design Process
	if (!(m_dwState & NAT_S_SYNC))
	{
		TRACE("\nReceive Ping before Sync!\n");
		return;
	}

	//UINT realsize=len-1;// VC-linhai[2007-08-06]:warning C4189: “realsize” : 局部变量已初始化但不引用
	const uchar * realdata=data+1;

	const uchar * hash=realdata;

	DWORD ConnAck=0;
	memcpy(&ConnAck, hash+16, 4);
	TRACE("recv ping 3. %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)
	{
		TRACE("no AsyncsocketEx for unconnect sk\n");
		Failed();
		return;
	}

	CNatSocket * 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_TraversalType = CNatSocket::Traversal_byexchangesource;

	memcpy(nsock->GetUserHash(), hash, 16);

	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 = DYNAMIC_DOWNCAST(CClientReqSocket, pASock);
	if(pClientSock && pClientSock->client)
	{
		pClientSock->client->SetIP(ip);
		pClientSock->client->ResetIP2Country();
	}

	Finish();
}
コード例 #6
0
void CTraverseBySourceExchange::OnRecvSync(const uchar * data, int /*len*/, DWORD /*ip*/, WORD /*port*/)
{
	TRACE("Receive NAT Sync Request From Source Exchange!\n");

	//UINT realsize=len-1;// VC-linhai[2007-08-06]:warning C4189: “realsize” : 局部变量已初始化但不引用
	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);

	TRACE("recv sync, ConnAck=%08x\n", ConnAck);
#ifdef _DEBUG
	in_addr addr;
	addr.s_addr = cip;
	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
	{
		TRACE("\n->%s: Accept a incoming sock for %02X%02X%02X%02X\n", __FUNCTION__,
			id[0],id[1],id[2],id[3]);

		pASock = CGlobalVariable::natthread->GetTempASock(id);
	}

	m_dwClientIp = cip;
	m_wClientPort = cport;

	m_dwState |=NAT_S_SYNC;
	SendPingPacket();
}
コード例 #7
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();
}
コード例 #8
0
ファイル: NatThread.cpp プロジェクト: techpub/archive-code
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();
}
コード例 #9
0
ファイル: NatThread.cpp プロジェクト: techpub/archive-code
void CNatThread::CheckConnection()
{
	// modified by robert, 2010-07-30 加锁
	CSingleLock locker(&m_Mutex, TRUE);

	POSITION pos = NULL, posCur=NULL;
	if(! m_UnConnectSocket.IsEmpty())
	{
		pos = m_UnConnectSocket.GetHeadPosition();
		for(; pos!=NULL; )
		{
			posCur = pos;
			CUnconnSocket * usock=m_UnConnectSocket.GetNext(pos);
			if(!usock)
			{
				m_UnConnectSocket.RemoveAt(posCur);
				continue;
			}

			if(usock->m_dwState & NAT_S_SYNC && time(NULL)-usock->m_SendPingTime >4)
			{
				if(usock->m_nPassivePing> 15)
				{
					if(usock->m_Sock)
					{
						usock->m_Sock->TriggerEvent(FD_FAILED, 1);
					}

					_AddLogLine(false, _T("Passive Unconnected NatSock was deleted. timeout. %s."), UserHashToString(usock->m_ClientId));
					
					RemoveSocketInUnconn(posCur);

				}
				else usock->SendPingPacket();
			}

		}
	}

	pos = m_SockMap.GetHeadPosition();
	while(pos)
	{
		posCur=pos;
		CNatSocket * nsock=m_SockMap.GetNextValue(pos);
		if(!nsock)
		{
			m_SockMap.RemoveAt(posCur);
			continue;
		}

		if(time(NULL) - nsock->m_dwRecvKeepalive > 4*TM_KEEPALIVE)
		{
			_AddLogLine(false, _T("NatSock was deleted. timeout. %s."), UserHashToString(nsock->GetUserHash()));

			m_SockMap.RemoveAt(posCur);
			delete nsock;
		}
	}

	//  check natsock pool
	pos = m_NatSockPool.GetHeadPosition();
	while(pos)
	{
		posCur=pos;
		CNatSocket * nsock=m_NatSockPool.GetNextValue(pos);
		if(!nsock)
		{
			m_SockMap.RemoveAt(posCur);
			continue;
		}

		if(time(NULL) - nsock->m_dwRecvKeepalive > 4*TM_KEEPALIVE)
		{
			_AddLogLine(false, _T("NatSock(in pool) was deleted. timeout. %s."), UserHashToString(nsock->GetUserHash()));
			m_NatSockPool.RemoveAt(posCur);
			delete nsock;
		}
	}

	if (NULL != theApp.emuledlg)
		PostMessage(theApp.emuledlg->GetSafeHwnd(), UM_NAT_CHECK_STRATEGIES, 0, 0);
}
コード例 #10
0
ファイル: NatThread.cpp プロジェクト: techpub/archive-code
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;
}