#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(&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)); }