tekno_uttv2/ultimateteknotool.v2/Winsock_Client.cpp
2020-12-31 15:35:46 +03:00

143 lines
3.9 KiB
C++

#include "pch.h"
#include "Winsock_Client.h"
Winsock_Client::Winsock_Client()
{
this->bdSecurityID.Init(0x31);
}
Winsock_Client::~Winsock_Client()
{
::closesocket(this->m_Socket);
}
void Winsock_Client::doDTLSconnect(sockaddr_in* address)
{
if (WSAController::WSAC0ntroller().IsValid() == false) { return; }
this->m_Socket = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
this->m_ServerAddr.sin_addr = address->sin_addr;
this->m_ServerAddr.sin_family = AF_INET;
this->m_ServerAddr.sin_port = address->sin_port;
DWORD timeout = 2 * 1000;
setsockopt(this->m_Socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
this->buffer_for_dtls.Flush();
this->Send_Init();
WCWOUT("Winsock_Client::doDTLSconnect: sent init");
if (NO_ERROR != this->RecvFrom(this->buffer_for_dtls.Data(), this->buffer_for_dtls.Size())) {
return;
}
else
{
memcpy((char*)&this->initialACK, this->buffer_for_dtls.Data(), sizeof(this->initialACK));
this->buffer_for_dtls.Flush();
this->Send_CookieAck();
WCWOUT("Winsock_Client::doDTLSconnect: sent cookieack");
/* next steps are not released */
}
}
void Winsock_Client::SetPlayerNetData(iw5mp_structs::playerNetData& ppp)
{
WCWOUT("Winsock_Client::SetPlayerNetData()");
this->playernetdata = ppp;
}
long Winsock_Client::SendTo(const char* buf, int len, int flags)
{
int sendret = 0; // SOCKET_ERROR, etc ...
sendret = ::sendto(this->m_Socket, buf, len, flags, reinterpret_cast<const ::SOCKADDR*>(&this->m_ServerAddr), sizeof(this->m_ServerAddr));
if (sendret <= 0)
{
//wsaerror = ::WSAGetLastError();
//std::cout << "error/socket/::sendto wsaerror: " << wsaerror << '\n';
//switch (wsaerror)
//{
//case WSAETIMEDOUT:
//case WSAEHOSTUNREACH:
//case WSAECONNABORTED:
// return WSABASEERR - WSAECONNABORTED;
//default:
// return WSABASEERR;
//}
WCWOUT("Winsock_Client::SendTo failed");
return WSABASEERR;
}
return NO_ERROR;
}
long Winsock_Client::RecvFrom(char* buf, int len, int flags)
{
this->m_recvbytes = 0;
int wsaerror = 0;
int recvret = 0; // SOCKET_ERROR, etc ...
int fromlen = sizeof(this->m_ServerAddr);
recvret = ::recvfrom(this->m_Socket, buf, len, flags, reinterpret_cast<::SOCKADDR*>(&this->m_ServerAddr), &fromlen);
if (recvret > 0) {
this->m_recvbytes = recvret;
}
else
{
wsaerror = ::WSAGetLastError();
WCWOUT("this->RecvFrom failed", wsaerror);
//std::cout << "error/socket/::recvfrom wsaerror: " << wsaerror << '\n';
//switch (wsaerror)
//{
//case WSAETIMEDOUT:
//case WSAEHOSTUNREACH:
//case WSAECONNABORTED:
// return WSAECONNABORTED - WSABASEERR;
//default:
// return WSABASEERR;
//}
return WSABASEERR;
}
return NO_ERROR;
}
void Winsock_Client::FlushStruct(char* dst, size_t sz)
{
char crypt = RANDBYTE;
for (size_t i = 0; i < sz; i++)
{
dst[i] = (dst[i] + 1) ^ crypt;
crypt++;
}
}
void Winsock_Client::Send_Init()
{
iw5mp_structs::DTLS::InitPacket initial;
initial.header_high = 0x01;
initial.header_low = 0x02;
initial.unknown = 0;
initial.m_initTag = MAKEWORD(RANDBYTEH1, RANDBYTEH0);
initial.bdSecurityID.Set(&(this->bdSecurityID));
this->SendTo((char*)&initial, sizeof(iw5mp_structs::DTLS::InitPacket));
}
void Winsock_Client::Send_CookieAck()
{
this->CookieAckPacket.header_high = 0x03;
this->CookieAckPacket.header_low = 0x02;
/* initack part */
this->CookieAckPacket.initack = this->initialACK;
this->initialACK.cookie.localTag = 0;
this->CookieAckPacket.cookie = this->initialACK.cookie;
this->FlushStruct((char*)&this->initialACK, sizeof(this->initialACK));
/* netdata */
this->CookieAckPacket.pND = this->playernetdata;
/* bdsecurity */
this->CookieAckPacket.bdSecurityID.Set(&this->bdSecurityID);
/* ecckey */
TomLibKeyGen::GetT0mLibKeyGen().ECC_GetExportKey(this->CookieAckPacket.ECCkey_exportkey, sizeof(this->CookieAckPacket.ECCkey_exportkey));
this->SendTo((char*)&this->CookieAckPacket, sizeof(this->CookieAckPacket));
this->FlushStruct((char*)&this->CookieAckPacket, sizeof(this->CookieAckPacket));
}