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