111 lines
4.2 KiB
C++
111 lines
4.2 KiB
C++
#include <mutex>
|
|
#include <arpa/inet.h>
|
|
#include <ThreadPool/Thread.h>
|
|
#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<threads::Mutex> 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<const sockaddr *>(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));
|
|
} |