#include "udp_client.h" #include "conn_map.h" #include "hv/UdpClient.h" #include "bolt/datagram.h" #include "spdlog/spdlog.h" #include 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 new_client = std::make_unique(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) { 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) hio_write(io, boltdata, boltdata_len); } 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(); return true; } void UdpClientProxy::close() { cli.closesocket(); } void UdpClientProxy::onRecv(const hv::SocketChannelPtr &channel, hv::Buffer *buf) { spdlog::info("<<< size:{} : data: {}", (int)buf->size(), (char *)buf->data()); auto serverProxy = UdpConnMap::getInstance().get(session_id); if (!serverProxy) { return; } 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()); }