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); }
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; } } }