#include #include #include #include "ProxiedClient.h" using namespace std; using namespace std::chrono; using namespace ts::flood; #define CERROR(msg) \ do { \ cerr << msg << endl;\ this->disconnect();\ return;\ } while(0) static int port = 10000; static threads::Mutex portLock; void ProxiedClient::handleProxyMessage(const std::string &msg) { if(this->state == PROXY_INIT_METHODS){ if(msg[0] != 0x05) CERROR("Invalid proxy version response (methode exchange)"); if(msg[1] != 0x00) CERROR("Invalid respond methode"); this->state = PROXY_INIT_CONNECTION; char buffer[128]; int index = 0; buffer[index++] = 0x05; //Version buffer[index++] = 0x03; //Udp weiterleitung buffer[index++] = 0x00; //Resv buffer[index++] = 0x01; //Addr type = IPv4 auto addr = IPv4{this->remoteAddr->sin_addr.s_addr}; buffer[index++] = addr._1; buffer[index++] = addr._2; buffer[index++] = addr._3; buffer[index++] = addr._4; buffer[index++] = (ntohs(this->remoteAddr->sin_port) >> 8) & 0xFF; buffer[index++] = (ntohs(this->remoteAddr->sin_port) >> 0) & 0xFF; this->sendMessage(string(buffer, index)); } else if(this->state = PROXY_INIT_CONNECTION){ cout << "res!" << endl; int index = 0; if(msg[index++] != 0x05) CERROR("Invalid proxy version response (connection request)"); if(msg[index++] != 0x00) CERROR("Could not create connection (" + to_string((int) msg[1]) + ")"); if(msg[index++] != 0x00) CERROR("Invalid proxy rsv response (connection request)"); if(msg[index++] != 0x01) CERROR("Invalid proxy ip response type"); auto rAddr = IPv4{}; rAddr._1 = msg[index++]; rAddr._2 = msg[index++]; rAddr._3 = msg[index++]; rAddr._4 = msg[index++]; uint16_t pHigh = ((uint16_t) msg[index++]) & 0xFF; uint16_t pLow = ((uint16_t) msg[index++]) & 0xFF; uint16_t rPort = (pHigh << 8) | pLow; cout << "Got udp relay " << rAddr.string() << ":" << rPort << endl; //Delete old connection //shutdown(this->fileDescriptor, SHUT_RDWR); event_del(this->wEvent); event_del(this->rEvent); this->fileDescriptor = 0; //Setup relay this->relayAddr = new sockaddr_in{}; memset(relayAddr, 0, sizeof(*relayAddr)); relayAddr->sin_family = AF_INET; relayAddr->sin_port = htons(rPort); relayAddr->sin_addr.s_addr = rAddr.addr; cout << "Relay addr: " << inet_ntoa(relayAddr->sin_addr) << ":" << ntohs(relayAddr->sin_port) << endl; this->localAddr = new sockaddr_in{}; memset(localAddr, 0, sizeof(*localAddr)); localAddr->sin_family = AF_INET; { lock_guard l(portLock); localAddr->sin_port = this->remoteAddr->sin_port; // = htons(10000 + (port++ % 30000)); } localAddr->sin_addr.s_addr = htonl(INADDR_ANY); this->fileDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); cout << "fd -> " << this->fileDescriptor << endl; int allow = 1; if(setsockopt(this->fileDescriptor, SOL_SOCKET, SO_REUSEADDR, &allow, sizeof(int)) < 0) CERROR("Could not enable reuse addr"); if(bind(this->fileDescriptor, reinterpret_cast(this->localAddr), sizeof(*this->localAddr)) < 0) CERROR("Could nto bind to relay"); cout << "Bind on " << inet_ntoa(this->localAddr->sin_addr) << ":" << ntohs(this->localAddr->sin_port) << endl; this->state = PROXY_CONNECTED; this->rEvent = event_new(this->evBase, this->fileDescriptor, EV_READ | EV_PERSIST, ProxiedClient::handleEventRead, this); this->wEvent = event_new(this->evBase, this->fileDescriptor, EV_WRITE, ProxiedClient::handleEventWrite, this); event_add(rEvent, nullptr); threads::Thread([&](){ threads::self::sleep_for(seconds(1)); this->proxyInizalisized(); }); } } void ProxiedClient::requestProxyConnection() { char buffer[3]; buffer[0] = 0x05; //Version buffer[1] = 1; //One methode buffer[2] = 0x00; //No auth required this->sendMessage(string(buffer, 3)); }