예제 #1
0
파일: utpsocket.cpp 프로젝트: HackerJLY/utp
void Socket::handle_readable()
{
    char buf[2048];
    struct sockaddr sa;
    do {
        socklen_t salen = sizeof(sa);
        int res = recvfrom(udp_sock, buf, sizeof(buf), 0, &sa, &salen);
        if (res == -1) return;
        UTP_IsIncomingUTP(_UTPGotIncomingConnection, _SendToProc, this, (const byte *)buf, res, (const struct sockaddr *)&sa, salen);
    } while (true);
}
예제 #2
0
void CUTPSocketListner::Recv(const byte* Buffer, size_t uSize, const struct sockaddr* sa, socklen_t sa_len)
{
	byte* pBuffer = (byte*)Buffer;
	size_t uPos = 0;

	if(uSize < 8)
		return;

	uint32 Rand;
	memcpy(&Rand, pBuffer, sizeof(uint32));						uPos += 4;

	CryptoPP::Weak1::MD5 md5;
	md5.Update((byte*)&Rand, sizeof(uint32));
	md5.Update((byte*)&m_RecvKey, sizeof(uint64));
	byte Hash[16];
	md5.Final(Hash);

//#ifdef _DEBUG
//	LogLine(LOG_INFO | LOG_DEBUG, L"Recv from %s PassKey %I64u -> %s", 
//		CSafeAddress(sa, sa_len, sa_len == sizeof(sockaddr_in) ? CSafeAddress::eUTP_IP4 : CSafeAddress::eUTP_IP6).ToString().c_str(),
//		m_RecvKey, ToHex(Hash, 16).c_str());
//#endif

	CryptoPP::Weak::ARC4::Encryption RC4;
	RC4.SetKey(Hash, 16);
	RC4.DiscardBytes(256);

	RC4.ProcessData(pBuffer + 4, pBuffer + 4, 4);
	UHdr Hdr;
	memcpy(&Hdr.Bits, pBuffer + uPos, 4);						uPos += 4;

	if(Hdr.Fields.Discard)
		RC4.DiscardBytes(Hdr.Fields.Discard * 256);

	RC4.ProcessData(pBuffer + uPos, pBuffer + uPos, uSize - uPos);

	uint64 PassKey = 0;
	if(Hdr.Fields.HasKey)
	{
		if(uSize - uPos < 8)
			return;
		memcpy(&PassKey, pBuffer + uPos, sizeof(uint64));		uPos += 8;
	}

	if(uSize - uPos < Hdr.Fields.PadLen)
		return;
	uSize -= Hdr.Fields.PadLen;
	
	if(Hdr.Fields.Reserved != 0) // if we want to use the reserverd bits we must set the magic value
	{
		if(memcmp(pBuffer + uSize, NEO_MAGIC, 4) != 0)
			return;
	}

	TKeyMap::iterator I = m_SendKeys.find((struct sockaddr*)sa);
	if(I == m_SendKeys.end())
	{
		if(PassKey == 0)
			return; // drop this packet as wen cant answer it

		SPassKey* pSendKey = new SPassKey((struct sockaddr*)sa);
		I = m_SendKeys.insert(TKeyMap::value_type(pSendKey->sa, pSendKey)).first;
	}
	if(PassKey != 0)
		I->second->PassKey = PassKey;
	//I->second->bAck = true; // if we got a packet it means that the other site knows out passkey and those we dont have to send it
	I->second->LastActivity = GetCurTick();


	switch(Hdr.Fields.Type)
	{
	case 0:
		{
			CBuffer Packet(pBuffer + uPos, uSize - uPos, true);
			CSafeAddress Address((sockaddr*)sa, sa_len, sa_len == sizeof(sockaddr_in) ? CSafeAddress::eUTP_IP4 : CSafeAddress::eUTP_IP6);
			Address.SetPassKey(I->second->PassKey);
			ReceiveFrom(Packet, Address);
			break;
		}
	case 1:
		// Lookup the right UTP socket that can handle this message
		UTP_IsIncomingUTP(&got_incoming_connection, &send_to, this, pBuffer + uPos, uSize - uPos, (const struct sockaddr*)sa, sa_len, &utp_overhead_2);
		break;
	case 15:
		{
			if(m_RecvKey < I->second->PassKey) // we have to decide who does the Sync, we do that in a trivial way
				Send(NULL, 0, sa, sa_len, 15);
			else
			{
				CSafeAddress Address(sa, sa_len, sa_len == sizeof(sockaddr_in) ? CSafeAddress::eUTP_IP4 : CSafeAddress::eUTP_IP6);
				Address.SetPassKey(I->second->PassKey);
				CSmartSocket* pSocket = GetParent<CSmartSocket>();
				CUTPSocketSession* pSession = pSocket->NewChannel(Address)->Cast<CUTPSocketSession>();
				if(pSession && !pSession->IsValid())
					pSession->Connect(sa, sa_len);
			}
			break;
		}
	}
}