ProxyServerTcp / src /udp_client.cpp
xukc
[fix]script
a97d8f8
raw
history blame
4 kB
#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)
{
std::unique_ptr<UdpClientProxy> new_client = std::make_unique<UdpClientProxy>(t_addr, u_addr, session_id);
if (!new_client->init())
{
return false;
}
_map.add(key, new_client);
client = new_client.get();
}
if (getConfig().ept_type == CRYPT_TYPE::XOR)
{
xor_::crypt((char *)dest, dest_len, getConfig().ept_key);
}
client->getClient()->sendto(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);
auto client = _map.get(key);
if (client)
{
client->close();
_map.remove(key);
}
}
void UdpServerBoltProxy::recycle()
{
for (auto it = _map.begin(); it != _map.end(); ++it)
{
it->second->close();
}
_map.clear();
}
bool UdpClientProxy::init()
{
int sockfd = cli.createsocket(t_addr.sin_port, inet_ntoa(t_addr.sin_addr));
if (sockfd < 0)
{
return false;
}
cli.onWriteComplete = [this](const hv::SocketChannelPtr &channel, hv::Buffer *buf)
{
onWrited(channel, buf);
};
cli.onMessage = [this](const hv::SocketChannelPtr &channel, hv::Buffer *buf)
{
onRecv(channel, buf);
};
hio_setcb_close(cli.channel.get()->io(), [](hio_t *io) {
});
cli.start();
timer.setInterval(TIMEOUT_TIMEUNIT, [this](hv::TimerID timerID) {
long timeout = isDns() ? DNS_TIMEOUT : TIMEOUT_TIMEUNIT;
long time = currentTimeMillis() - ts;
if (time > 0 && time < timeout)
{
long remaining = (timeout-time);
if(remaining < TIMEOUT_TIMEUNIT) {
} else {
}
} else {
auto serverProxy = UdpConnMap<uint32_t, UdpServerBoltProxy>::getInstance().get(session_id);
if (!serverProxy)
{
close();
return;
}
serverProxy->closeClient(t_addr, u_addr);
}
});
return true;
}
void UdpClientProxy::close()
{
cli.closesocket();
timer.stop();
}
void UdpClientProxy::onRecv(const hv::SocketChannelPtr &channel, hv::Buffer *buf)
{
spdlog::info("<<< size:{} : data: {}", (int)buf->size(), (char *)buf->data());
auto serverProxy = UdpConnMap<uint32_t, UdpServerBoltProxy>::getInstance().get(session_id);
if (!serverProxy)
{
return;
}
ts = currentTimeMillis();
serverProxy->sendData(t_addr, u_addr, buf->data(), buf->size());
}
void UdpClientProxy::onWrited(const hv::SocketChannelPtr &channel, hv::Buffer *buf)
{
spdlog::info(">>> size:{} : data: {}", (int)buf->size(), (char *)buf->data());
}