Spaces:
Paused
Paused
std::string get_key(struct sockaddr_in t_addr, struct sockaddr_in u_addr) | |
{ | |
std::ostringstream string_stream; | |
string_stream << t_addr.sin_addr.s_addr << t_addr.sin_port; | |
string_stream << u_addr.sin_addr.s_addr << u_addr.sin_port; | |
return string_stream.str(); | |
} | |
bool UdpServerBoltProxy::analyzeData(struct sockaddr_in t_addr, struct sockaddr_in u_addr, | |
uint32_t session_id, char *dest, int dest_len, char *extend, int extend_len) | |
{ | |
auto key = get_key(t_addr, u_addr); | |
auto client = _map.get(key); | |
if (!client) | |
{ | |
hloop_t *loop = (hloop_t *)hevent_userdata(io); | |
std::unique_ptr<UdpClientProxy> new_client = std::make_unique<UdpClientProxy>(t_addr, u_addr, session_id); | |
if (!new_client->init(loop)) | |
{ | |
return false; | |
} | |
client = new_client.get(); | |
_map.add(key, new_client); | |
} | |
// if (getConfig().ept_type == CRYPT_TYPE::XOR) | |
// { | |
// xor_::crypt((char *)dest, dest_len, getConfig().ept_key); | |
// } | |
hio_write(client->getClientIO(), dest, dest_len); | |
return true; | |
} | |
int UdpServerBoltProxy::sendData(struct sockaddr_in t_addr, struct sockaddr_in u_addr, void *data, int data_len) | |
{ | |
// if (getConfig().ept_type == CRYPT_TYPE::XOR) | |
// { | |
// xor_::crypt((char *)data, data_len, getConfig().ept_key); | |
// } | |
PACK_TUNNEL_DATA(boltdata, boltdata_len, BOLT_VERSION, BOLT_RESERVE, BOLT_PAYLOAD_TYPE_UDP, t_addr.sin_addr.s_addr, t_addr.sin_port, u_addr.sin_addr.s_addr, u_addr.sin_port, config.session_id, 0, 0, data, data_len) | |
return hio_write(io, boltdata, boltdata_len); | |
} | |
void UdpServerBoltProxy::closeClient(struct sockaddr_in &t_addr, struct sockaddr_in &u_addr) | |
{ | |
auto key = get_key(t_addr, u_addr); | |
_map.remove(key); | |
} | |
void UdpServerBoltProxy::recycle() | |
{ | |
for (auto it = _map.begin(); it != _map.end(); ++it) | |
{ | |
it->second->close(); | |
} | |
_map.clear(); | |
} | |
bool UdpClientProxy::init(hloop_t *loop) | |
{ | |
spdlog::info("UdpClientProxy::init {}:{}<==>{}:{}", inet_ntoa(u_addr.sin_addr), ntohs(u_addr.sin_port), inet_ntoa(t_addr.sin_addr), ntohs(t_addr.sin_port)); | |
cli_io = hloop_create_udp_client(loop, inet_ntoa(t_addr.sin_addr), ntohs(t_addr.sin_port)); | |
if (cli_io == nullptr) | |
{ | |
return false; | |
} | |
hevent_set_userdata(cli_io, this); | |
hio_setcb_read(cli_io, [](hio_t *io, void *buf, int readbytes) { | |
UdpClientProxy *cli = (UdpClientProxy *)hevent_userdata(io); | |
if (cli) | |
{ | |
cli->onRecv(buf, readbytes); | |
} | |
}); | |
hio_setcb_write(cli_io, [](hio_t *io, const void *buf, int writebytes) { | |
UdpClientProxy* cli = (UdpClientProxy*)hevent_userdata(io); | |
if (cli) | |
{ | |
cli->onWrited(buf, writebytes); | |
} | |
}); | |
hio_setcb_close(cli_io, [](hio_t *io) { | |
UdpClientProxy* cli = (UdpClientProxy*)hevent_userdata(io); | |
if (cli) | |
{ | |
cli->onClosed(); | |
} | |
}); | |
hio_read(cli_io); | |
timer = htimer_add(loop, [](htimer_t *timer) { | |
UdpClientProxy* cli = (UdpClientProxy*)hevent_userdata(timer); | |
if (cli) | |
{ | |
long timeout = cli->isDns() ? DNS_TIMEOUT : TIMEOUT_TIMEUNIT; | |
long time = currentTimeMillis() - cli->ts; | |
if (time > 0 && time < timeout) | |
{ | |
long remaining = (timeout - time); | |
if (remaining < TIMEOUT_TIMEUNIT) | |
{ | |
htimer_reset(timer, remaining); | |
} | |
else | |
{ | |
htimer_reset(timer, TIMEOUT_TIMEUNIT); | |
} | |
} | |
else | |
{ | |
cli->close(); | |
} | |
} | |
}, TIMEOUT_TIMEUNIT); | |
hevent_set_userdata(timer, this); | |
return true; | |
} | |
void UdpClientProxy::close() | |
{ | |
if (timer) | |
{ | |
htimer_del(timer); | |
timer = nullptr; | |
} | |
if (cli_io) { | |
hio_close(cli_io); | |
cli_io = nullptr; | |
} | |
} | |
void UdpClientProxy::onRecv(void *buf, int readbytes) | |
{ | |
spdlog::info("UdpClientProxy::onRecv {}:{}<==>{}:{} <<< size:{} : data: {}", inet_ntoa(u_addr.sin_addr), ntohs(u_addr.sin_port), inet_ntoa(t_addr.sin_addr), ntohs(t_addr.sin_port), readbytes, std::string((char *)buf, readbytes).c_str()); | |
auto serverProxy = UdpConnMap<uint32_t, UdpServerBoltProxy>::getInstance().get(session_id); | |
if (!serverProxy) | |
{ | |
return; | |
} | |
ts = currentTimeMillis(); | |
serverProxy->sendData(t_addr, u_addr, buf, readbytes); | |
} | |
void UdpClientProxy::onWrited(const void *buf, int writebytes) | |
{ | |
spdlog::info("UdpClientProxy::onWrited {}:{}<==>{}:{} >>> size:{} : data: {}", inet_ntoa(u_addr.sin_addr), ntohs(u_addr.sin_port), inet_ntoa(t_addr.sin_addr), ntohs(t_addr.sin_port), writebytes, std::string((char *)buf, writebytes).c_str()); | |
} | |
void UdpClientProxy::onClosed() | |
{ | |
spdlog::info("UdpClientProxy::onClosed {}:{}<==>{}:{}", inet_ntoa(u_addr.sin_addr), ntohs(u_addr.sin_port), inet_ntoa(t_addr.sin_addr), ntohs(t_addr.sin_port)); | |
auto key = get_key(t_addr, u_addr); | |
auto serverProxy = UdpConnMap<uint32_t, UdpServerBoltProxy>::getInstance().get(session_id); | |
if (!serverProxy) | |
{ | |
return; | |
} | |
serverProxy->closeClient(t_addr, u_addr); | |
} |