extern "C" { #include } #include #include #include #include #include #include #include #include TunNetwork::TunNetwork(std::string iladdr, std::string iraddr) { laddr = iladdr; raddr = iraddr; used = false; } TunService::TunService(int svcport, std::string itunnelnet, std::vector ilocalnets) { listenport = svcport; tunnelnet = itunnelnet; localnets = ilocalnets; } std::expected TunService::Init(void) { auto netprefixRes = netprefix(tunnelnet); if (!netprefixRes) { return std::unexpected(netprefixRes.error()); } auto networkRes = network(tunnelnet); if (!netprefixRes) { return std::unexpected(networkRes.error()); }; auto prefix = netprefixRes.value(); auto netaddr = networkRes.value(); auto totalHostsRes = netcapa(netaddr, prefix); if (!totalHostsRes) { return std::unexpected(totalHostsRes.error()); }; auto totalNets = totalHostsRes.value() / 4; uxlogger.Debug(std::format("Total networks: {}", totalNets)); for (uint64_t i = 0; i < totalNets; i += 4) { auto laddrRes = nethost(netaddr, prefix, i + 1); auto raddrRes = nethost(netaddr, prefix, i + 2); auto laddr = laddrRes.value(); auto raddr = raddrRes.value(); TunNetwork tunnet(laddr, raddr); tunnets.push_back(tunnet); uxlogger.Debug(std::format("Available address: {} -- {}", laddr, raddr)); } return {}; } TunService::~TunService() { close(listenport); } std::expected TunService::Bind(void) { struct sockaddr_in address; int srvsock; if ((srvsock = socket(AF_INET, SOCK_STREAM, 0)) == 0) { int errnocopy = errno; std::string error = std::strerror(errnocopy); return std::unexpected("Create socker error: " + error); } int opt = 1; if (setsockopt(srvsock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) { int errnocopy = errno; std::string error = std::strerror(errnocopy); return std::unexpected("Set socket option error: " + error); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(listenport); if (bind(srvsock, (struct sockaddr *)&address, sizeof(address)) < 0) { int errnocopy = errno; std::string error = std::strerror(errnocopy); return std::unexpected("Bind error: " + error); } if (listen(srvsock, 3) < 0) { int errnocopy = errno; std::string error = std::strerror(errnocopy); return std::unexpected("Listen error: " + error); } sock = srvsock; return {}; } std::expected TunService::Listen(void) { struct sockaddr_in address; int addrlen = sizeof(address); int newsock = 0; for (;;) { if ((newsock = accept(sock, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) { int errnocopy = errno; std::string error = std::strerror(errnocopy); return std::unexpected("Accept error: " + error); } std::jthread t(&TunService::Handle, this, newsock); t.detach(); } return {}; } void TunService::Handle(int sock) { std::string laddr, raddr; bool netFound = false; for (auto& net: tunnets) { if (!net.used) { laddr = net.laddr; raddr = net.raddr; net.used = true; netFound = true; break; } } if (!netFound) { uxlogger.Error("Not found free tunnnel network"); close(sock); return; } uxlogger.Debug("Start socker handler"); SocketHandler handler; handler.Handle(sock, laddr, raddr, localnets); uxlogger.Debug("Stop socket handler"); close(sock); }