ProxyServerTcp / src /udp_client.cpp
xukc
[fix]udp runtime error
99dc157
#include "udp_client.h"
#include "conn_map.h"
#include "utils.h"
#include "hv/UdpClient.h"
#include "bolt/datagram.h"
#include "spdlog/spdlog.h"
#include <sstream>
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);
}