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) | |
{ | |
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()); | |
} |