예제 #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
void
IpVerify::PrintAuthTable(int dprintf_level) {
	struct in6_addr host;
	UserPerm_t * ptable;
	PermHashTable->startIterations();

	while (PermHashTable->iterate(host, ptable)) {
		MyString userid;
		perm_mask_t mask;

		ptable->startIterations();
		while( ptable->iterate(userid,mask) ) {
				// Call has_user() to get the full mask
			has_user(ptable, userid.Value(), mask);

			MyString auth_entry_str;
			AuthEntryToString(host,userid.Value(),mask, auth_entry_str);
			dprintf(dprintf_level,"%s\n", auth_entry_str.Value());
		}
	}

	dprintf(dprintf_level,"Authorizations yet to be resolved:\n");
	DCpermission perm;
	for ( perm=FIRST_PERM; perm < LAST_PERM; perm=NEXT_PERM(perm) ) {

		PermTypeEntry* pentry = PermTypeArray[perm];
		ASSERT( pentry );

		MyString allow_users,deny_users;

		if( pentry->allow_users ) {
			UserHashToString(pentry->allow_users,allow_users);
		}

		if( pentry->deny_users ) {
			UserHashToString(pentry->deny_users,deny_users);
		}

		if( allow_users.Length() ) {
			dprintf(dprintf_level,"allow %s: %s\n",
					PermString(perm),
					allow_users.Value());
		}

		if( deny_users.Length() ) {
			dprintf(dprintf_level,"deny %s: %s\n",
					PermString(perm),
					deny_users.Value());
		}
	}
}
예제 #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
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 );
	}
}
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
int CTraverseByBuddy::SendConnectReq()
{
	if(m_dwState & NAT_E_TIMEOUT) return 1;

	m_SendReqTime = time(NULL);
	m_nSendReqCount++;

	CClientReqSocket * pClientSock = NULL;
	try
	{
		pClientSock=DYNAMIC_DOWNCAST(CClientReqSocket, m_Sock);
	}
	catch(...)
	{
		TRACE("Exception: %s\n", __FUNCTION__);
		Failed();
		return 1;
	}

	if(pClientSock && pClientSock->client)
	{
		m_dwTraverseIp = pClientSock->client->GetBuddyIP();
		m_wTraversePort = htons(pClientSock->client->GetBuddyPort());

		//if(!m_dwTraverseIp || !m_wTraversePort)
		//	return 1;
	}
	else
	{
		//T_TRACE("failed to get buddy addr by CUpdownClient");
		Failed();
		return 1;
	}

	Kademlia::CUInt128 uBuddyID(true);
	uBuddyID.Xor(pClientSock->client->GetBuddyID());
	byte cID[16];
	uBuddyID.ToByteArray(cID);

#ifdef _DEBUG_NAT
	const uchar *uh=m_UserHash;
	TRACE(_T("send sync to connect %02X%02X%02X%02X by buddy. kad id=%s\n"), uh[0],uh[1],uh[2],uh[3],
		UserHashToString(cID));
	CString str=ipstr(m_dwTraverseIp, ntohs(m_wTraversePort));
	TRACE(_T("\n\n******* buddy dest addr:   %s\n"), (LPCTSTR)str);
#endif
	//  header + opcode + kadid&reserve + vc_header + sync + myaddr + myid + connack
	uchar Buf[2+32+1+4+1+6+16+4];
	Buf[0] =OP_EMULEPROT;
	Buf[1] = OP_REASKCALLBACKUDP;

	//  target kad id
	memcpy(Buf+2, pClientSock->client->GetBuddyID(), 16);
	memset(Buf+18,0,16);
	Buf[34] = OP_VC_NAT_HEADER;
	DWORD packsize=rand();
	memcpy(Buf+35, &packsize, 4);
	Buf[39] = OP_NAT_SYNC;
	GetMyUserHash((uchar*)Buf+46);
	memcpy(Buf+62, &m_dwConnAskNumber, 4);

	//SendPingPacket();

	return  CNatSocket::SendPacket(m_dwTraverseIp, m_wTraversePort, Buf, 2+32+1+4+1+6+16+4);
}
예제 #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
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;
}
예제 #9
0
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
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;
}
예제 #11
0
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;
	}
}