working commit

This commit is contained in:
2026-05-15 15:30:29 +02:00
parent 879481feab
commit 886684e224
28 changed files with 629 additions and 81 deletions
+11 -7
View File
@@ -105,13 +105,14 @@ CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(sbindir)" am__installdirs = "$(DESTDIR)$(sbindir)"
PROGRAMS = $(sbin_PROGRAMS) PROGRAMS = $(sbin_PROGRAMS)
am__objects_1 = uxlogger.$(OBJEXT) msgheader.$(OBJEXT) \ am__objects_1 = uxlogger.$(OBJEXT) msgheader.$(OBJEXT) \
interface.$(OBJEXT) iprouter.$(OBJEXT) uxcontrol.pb.$(OBJEXT) interface.$(OBJEXT) iprouter.$(OBJEXT) stringaux.$(OBJEXT) \
networkaux.$(OBJEXT) uxcontrol.pb.$(OBJEXT)
am_helmetcli_OBJECTS = helmetcli.$(OBJEXT) uxclient.$(OBJEXT) \ am_helmetcli_OBJECTS = helmetcli.$(OBJEXT) uxclient.$(OBJEXT) \
$(am__objects_1) $(am__objects_1)
helmetcli_OBJECTS = $(am_helmetcli_OBJECTS) helmetcli_OBJECTS = $(am_helmetcli_OBJECTS)
helmetcli_LDADD = $(LDADD) helmetcli_LDADD = $(LDADD)
am_helmetsrv_OBJECTS = helmetsrv.$(OBJEXT) tservice.$(OBJEXT) \ am_helmetsrv_OBJECTS = helmetsrv.$(OBJEXT) tservice.$(OBJEXT) \
sockhand.$(OBJEXT) $(am__objects_1) sockhand.$(OBJEXT) srvconfig.$(OBJEXT) $(am__objects_1)
helmetsrv_OBJECTS = $(am_helmetsrv_OBJECTS) helmetsrv_OBJECTS = $(am_helmetsrv_OBJECTS)
helmetsrv_LDADD = $(LDADD) helmetsrv_LDADD = $(LDADD)
AM_V_P = $(am__v_P_$(V)) AM_V_P = $(am__v_P_$(V))
@@ -206,7 +207,7 @@ distcleancheck_listfiles = \
ACLOCAL = ${SHELL} '/home/ziggi/Projects/stvpn/missing' aclocal-1.17 ACLOCAL = ${SHELL} '/home/ziggi/Projects/stvpn/missing' aclocal-1.17
AMTAR = $${TAR-tar} AMTAR = $${TAR-tar}
AM_DEFAULT_VERBOSITY = 1 AM_DEFAULT_VERBOSITY = 1
ASTYLE = /bin/astyle ASTYLE = /usr/bin/astyle
AUTOCONF = ${SHELL} '/home/ziggi/Projects/stvpn/missing' autoconf AUTOCONF = ${SHELL} '/home/ziggi/Projects/stvpn/missing' autoconf
AUTOHEADER = ${SHELL} '/home/ziggi/Projects/stvpn/missing' autoheader AUTOHEADER = ${SHELL} '/home/ziggi/Projects/stvpn/missing' autoheader
AUTOMAKE = ${SHELL} '/home/ziggi/Projects/stvpn/missing' automake-1.17 AUTOMAKE = ${SHELL} '/home/ziggi/Projects/stvpn/missing' automake-1.17
@@ -219,7 +220,7 @@ CSCOPE = cscope
CTAGS = ctags CTAGS = ctags
CXX = g++ CXX = g++
CXXDEPMODE = depmode=none CXXDEPMODE = depmode=none
CXXFLAGS = -O1 -std=c++23 -Wall -I. -pthread -D_GNU_SOURCE=1 -MMD -MP CXXFLAGS = -O -std=c++23 -Wall -I. -pthread -D_GNU_SOURCE=1 -MMD -MP
CYGPATH_W = echo CYGPATH_W = echo
DEFS = -DHAVE_CONFIG_H DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps DEPDIR = .deps
@@ -228,7 +229,7 @@ ECHO_N = -n
ECHO_T = ECHO_T =
ETAGS = etags ETAGS = etags
EXEEXT = EXEEXT =
INSTALL = /bin/install -c INSTALL = /usr/bin/install -c
INSTALL_DATA = ${INSTALL} -m 644 INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL} INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL} INSTALL_SCRIPT = ${INSTALL}
@@ -238,7 +239,7 @@ LIBOBJS =
LIBS = -Wl,--as-need -lprotobuf LIBS = -Wl,--as-need -lprotobuf
LTLIBOBJS = LTLIBOBJS =
MAKEINFO = ${SHELL} '/home/ziggi/Projects/stvpn/missing' makeinfo MAKEINFO = ${SHELL} '/home/ziggi/Projects/stvpn/missing' makeinfo
MKDIR_P = /bin/mkdir -p MKDIR_P = /usr/bin/mkdir -p
OBJEXT = o OBJEXT = o
PACKAGE = helmet PACKAGE = helmet
PACKAGE_BUGREPORT = PACKAGE_BUGREPORT =
@@ -248,7 +249,7 @@ PACKAGE_TARNAME = helmet
PACKAGE_URL = PACKAGE_URL =
PACKAGE_VERSION = 0.0.1 PACKAGE_VERSION = 0.0.1
PATH_SEPARATOR = : PATH_SEPARATOR = :
PROTOC = /bin/protoc PROTOC = /usr/bin/protoc
RANLIB = ranlib RANLIB = ranlib
SET_MAKE = SET_MAKE =
SHELL = /bin/bash SHELL = /bin/bash
@@ -304,6 +305,7 @@ AUTOMAKE_OPTIONS = foreign no-dependencies no-installinfo subdir-objects
helmetsrv_SOURCES = helmetsrv.cpp \ helmetsrv_SOURCES = helmetsrv.cpp \
tservice.cpp tservice.hpp \ tservice.cpp tservice.hpp \
sockhand.cpp dockhand.hpp \ sockhand.cpp dockhand.hpp \
srvconfig.cpp srvconfig.hpp \
$(helmet_SOURCES) $(helmet_SOURCES)
helmetcli_SOURCES = helmetcli.cpp \ helmetcli_SOURCES = helmetcli.cpp \
@@ -315,6 +317,8 @@ helmet_SOURCES = \
msgheader.cpp msgheader.hpp \ msgheader.cpp msgheader.hpp \
interface.cpp interface.hpp \ interface.cpp interface.hpp \
iprouter.cpp iprouter.hpp \ iprouter.cpp iprouter.hpp \
stringaux.cpp stringaux.hpp \
networkaux.cpp networkaux.hpp \
uxcontrol.pb.cc uxcontrol.pb.h uxcontrol.pb.cc uxcontrol.pb.h
ASTYLE_OPTS = --indent=spaces=8 --style=java ASTYLE_OPTS = --indent=spaces=8 --style=java
+4 -1
View File
@@ -1,7 +1,7 @@
AUTOMAKE_OPTIONS = foreign no-dependencies no-installinfo subdir-objects AUTOMAKE_OPTIONS = foreign no-dependencies no-installinfo subdir-objects
CXXFLAGS = -O1 -std=c++23 -Wall -I. -pthread -D_GNU_SOURCE=1 -MMD -MP CXXFLAGS = -O -std=c++23 -Wall -I. -pthread -D_GNU_SOURCE=1 -MMD -MP
LDFLAGS = -pthread LDFLAGS = -pthread
LIBS = -Wl,--as-need -lprotobuf LIBS = -Wl,--as-need -lprotobuf
@@ -10,6 +10,7 @@ sbin_PROGRAMS = helmetsrv helmetcli
helmetsrv_SOURCES = helmetsrv.cpp \ helmetsrv_SOURCES = helmetsrv.cpp \
tservice.cpp tservice.hpp \ tservice.cpp tservice.hpp \
sockhand.cpp dockhand.hpp \ sockhand.cpp dockhand.hpp \
srvconfig.cpp srvconfig.hpp \
$(helmet_SOURCES) $(helmet_SOURCES)
helmetcli_SOURCES = helmetcli.cpp \ helmetcli_SOURCES = helmetcli.cpp \
@@ -21,6 +22,8 @@ helmet_SOURCES = \
msgheader.cpp msgheader.hpp \ msgheader.cpp msgheader.hpp \
interface.cpp interface.hpp \ interface.cpp interface.hpp \
iprouter.cpp iprouter.hpp \ iprouter.cpp iprouter.hpp \
stringaux.cpp stringaux.hpp \
networkaux.cpp networkaux.hpp \
uxcontrol.pb.cc uxcontrol.pb.h uxcontrol.pb.cc uxcontrol.pb.h
ASTYLE_OPTS = --indent=spaces=8 --style=java ASTYLE_OPTS = --indent=spaces=8 --style=java
+7 -3
View File
@@ -105,13 +105,14 @@ CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(sbindir)" am__installdirs = "$(DESTDIR)$(sbindir)"
PROGRAMS = $(sbin_PROGRAMS) PROGRAMS = $(sbin_PROGRAMS)
am__objects_1 = uxlogger.$(OBJEXT) msgheader.$(OBJEXT) \ am__objects_1 = uxlogger.$(OBJEXT) msgheader.$(OBJEXT) \
interface.$(OBJEXT) iprouter.$(OBJEXT) uxcontrol.pb.$(OBJEXT) interface.$(OBJEXT) iprouter.$(OBJEXT) stringaux.$(OBJEXT) \
networkaux.$(OBJEXT) uxcontrol.pb.$(OBJEXT)
am_helmetcli_OBJECTS = helmetcli.$(OBJEXT) uxclient.$(OBJEXT) \ am_helmetcli_OBJECTS = helmetcli.$(OBJEXT) uxclient.$(OBJEXT) \
$(am__objects_1) $(am__objects_1)
helmetcli_OBJECTS = $(am_helmetcli_OBJECTS) helmetcli_OBJECTS = $(am_helmetcli_OBJECTS)
helmetcli_LDADD = $(LDADD) helmetcli_LDADD = $(LDADD)
am_helmetsrv_OBJECTS = helmetsrv.$(OBJEXT) tservice.$(OBJEXT) \ am_helmetsrv_OBJECTS = helmetsrv.$(OBJEXT) tservice.$(OBJEXT) \
sockhand.$(OBJEXT) $(am__objects_1) sockhand.$(OBJEXT) srvconfig.$(OBJEXT) $(am__objects_1)
helmetsrv_OBJECTS = $(am_helmetsrv_OBJECTS) helmetsrv_OBJECTS = $(am_helmetsrv_OBJECTS)
helmetsrv_LDADD = $(LDADD) helmetsrv_LDADD = $(LDADD)
AM_V_P = $(am__v_P_@AM_V@) AM_V_P = $(am__v_P_@AM_V@)
@@ -219,7 +220,7 @@ CSCOPE = @CSCOPE@
CTAGS = @CTAGS@ CTAGS = @CTAGS@
CXX = @CXX@ CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@ CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = -O1 -std=c++23 -Wall -I. -pthread -D_GNU_SOURCE=1 -MMD -MP CXXFLAGS = -O -std=c++23 -Wall -I. -pthread -D_GNU_SOURCE=1 -MMD -MP
CYGPATH_W = @CYGPATH_W@ CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@ DEFS = @DEFS@
DEPDIR = @DEPDIR@ DEPDIR = @DEPDIR@
@@ -304,6 +305,7 @@ AUTOMAKE_OPTIONS = foreign no-dependencies no-installinfo subdir-objects
helmetsrv_SOURCES = helmetsrv.cpp \ helmetsrv_SOURCES = helmetsrv.cpp \
tservice.cpp tservice.hpp \ tservice.cpp tservice.hpp \
sockhand.cpp dockhand.hpp \ sockhand.cpp dockhand.hpp \
srvconfig.cpp srvconfig.hpp \
$(helmet_SOURCES) $(helmet_SOURCES)
helmetcli_SOURCES = helmetcli.cpp \ helmetcli_SOURCES = helmetcli.cpp \
@@ -315,6 +317,8 @@ helmet_SOURCES = \
msgheader.cpp msgheader.hpp \ msgheader.cpp msgheader.hpp \
interface.cpp interface.hpp \ interface.cpp interface.hpp \
iprouter.cpp iprouter.hpp \ iprouter.cpp iprouter.hpp \
stringaux.cpp stringaux.hpp \
networkaux.cpp networkaux.hpp \
uxcontrol.pb.cc uxcontrol.pb.h uxcontrol.pb.cc uxcontrol.pb.h
ASTYLE_OPTS = --indent=spaces=8 --style=java ASTYLE_OPTS = --indent=spaces=8 --style=java
BIN
View File
Binary file not shown.
+2
View File
@@ -0,0 +1,2 @@
listenport = 1025;
tunnelnet = 10.1.1.0/24;
+27 -5
View File
@@ -5,17 +5,39 @@
#include <tservice.hpp> #include <tservice.hpp>
#include <uxlogger.hpp> #include <uxlogger.hpp>
#include <srvconfig.hpp>
int main(int argc, char** argv) { std::expected<void, std::string> Run() {
TCPService service(1025); ServConfig config;
auto readRes = config.Read("helmetsrv.conf");
if (!readRes) {
return std::unexpected("Read config error: " + readRes.error());
}
auto validateRes = config.Validate();
if (!validateRes) {
return std::unexpected("Validate config error: " + validateRes.error());
}
auto listport = config.Listenport();
auto localnets = config.Localnets();
auto tunnelnet = config.Tunnelnet();
TunService service(listport, tunnelnet, localnets);
auto bindRes = service.Bind(); auto bindRes = service.Bind();
if (!bindRes) { if (!bindRes) {
uxlogger.Log("Bind error: " + bindRes.error()); return std::unexpected("Bind error: " + bindRes.error());
return 1;
} }
uxlogger.Info(std::format("Listening on port {}", listport));
auto listenRes = service.Listen(); auto listenRes = service.Listen();
if (!listenRes) { if (!listenRes) {
uxlogger.Log("Listen error: " + listenRes.error()); return std::unexpected("Listen error: " + listenRes.error());
}
return {};
}
int main(int argc, char** argv) {
auto runRes = Run();
if (!runRes) {
uxlogger.Log(runRes.error());
return 1; return 1;
} }
return 0; return 0;
+1 -4
View File
@@ -155,14 +155,12 @@ std::expected<void, std::string> Interface::SetIP4Address(std::string ipaddr) {
std::string error = std::strerror(errnocopy); std::string error = std::strerror(errnocopy);
return std::unexpected("Set address error: " + error); return std::unexpected("Set address error: " + error);
} }
int sockfd = 0; int sockfd = 0;
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
int errnocopy = errno; int errnocopy = errno;
std::string error = std::strerror(errnocopy); std::string error = std::strerror(errnocopy);
return std::unexpected("Set address error: " + error); return std::unexpected("Set address error: " + error);
} }
if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) { if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) {
close(sockfd); close(sockfd);
int errnocopy = errno; int errnocopy = errno;
@@ -177,8 +175,7 @@ std::expected<void, std::string> Interface::SetIP4Netmask(int prefix) {
if (prefix < 0 || prefix > 32) { if (prefix < 0 || prefix > 32) {
return std::unexpected("Invalid prefix"); return std::unexpected("Invalid prefix");
} }
//uint32_t mask = (prefix == 0) ? 0 : (~0U << (32 - prefix)); uint32_t mask = (prefix == 0) ? 0 : (~0U << (32 - prefix));
uint32_t mask = (prefix == 0) ? 0 : htonl(~((1U << (32 - prefix)) - 1));
struct in_addr maskaddr; struct in_addr maskaddr;
maskaddr.s_addr = htonl(mask); maskaddr.s_addr = htonl(mask);
+1 -1
View File
@@ -44,6 +44,6 @@ std::expected<void, std::string> MessageHeader::Decode(const std::string rawHead
return {}; return {};
} }
uint32_t MessageHeader::PacketSize() { uint32_t MessageHeader::PayloadSize() {
return pSize; return pSize;
} }
+1 -1
View File
@@ -12,6 +12,6 @@ public:
MessageHeader(void); MessageHeader(void);
std::string Encode(void); std::string Encode(void);
std::expected<void, std::string> Decode(const std::string buffer); std::expected<void, std::string> Decode(const std::string buffer);
uint32_t PacketSize(void); uint32_t PayloadSize(void);
}; };
+81
View File
@@ -0,0 +1,81 @@
extern "C" {
#include <stdio.h>
#include <arpa/inet.h>
}
#include <format>
#include <expected>
#include <string>
#include <networkaux.hpp>
#include <stringaux.hpp>
std::expected<uint32_t, std::string> netprefix(const std::string network) {
auto hostprefix = split(network, "/");
if (hostprefix.size() < 2) {
return std::unexpected("Incorrect network definition");
}
auto prefixRes = strtoint(hostprefix[1]);
if (!prefixRes) {
return std::unexpected("Incorrect tunnel network prefix:" + prefixRes.error());
}
return prefixRes.value();
}
std::expected<std::string, std::string> network(const std::string network) {
auto hostprefix = split(network, "/");
if (hostprefix.size() < 2) {
return std::unexpected("Incorrect network definition");
}
return hostprefix[0];
}
std::expected<std::string, std::string> nethost6(std::string network, int prefix, uint32_t num) {
struct in6_addr addr;
unsigned char mask[16] = {0};
if (inet_pton(AF_INET6, network.data(), &addr) != 1) {
return std::unexpected(std::format("Invalid network address {}", network));
}
for (int i = 0; i < prefix; i++) {
mask[i / 8] |= (1 << (7 - (i % 8)));
}
for (int i = 0; i < 16; i++) {
addr.s6_addr[i] &= mask[i];
}
uint64_t *host_part = (uint64_t *)&addr.s6_addr[8];
uint64_t hostnum = be64toh(*host_part);
hostnum += num;
*host_part = htobe64(hostnum);
char buffer[INET6_ADDRSTRLEN] = {'\0'};
inet_ntop(AF_INET6, &addr, buffer, INET6_ADDRSTRLEN);
return std::string(buffer);
}
std::expected<std::string, std::string> nethost4(std::string network, int prefix, uint32_t num) {
struct in_addr inaddr;
if (inet_pton(AF_INET, network.data(), &inaddr) != 1) {
return std::unexpected(std::format("Invalid network address {}", network));
}
uint32_t ip = ntohl(inaddr.s_addr);
uint32_t mask = (prefix == 0) ? 0 : (~0U << (32 - prefix));
uint32_t fip = (ip & mask) + num;
struct in_addr ip_addr;
ip_addr.s_addr = htonl(fip);
return std::string(inet_ntoa(ip_addr));
}
std::expected<std::string, std::string> nethost(std::string network, int prefix, uint32_t num) {
struct sockaddr_in sa;
if (inet_pton(AF_INET, network.data(), &(sa.sin_addr)) == 1) {
return nethost4(network, prefix, num);
} else if (inet_pton(AF_INET6, network.data(), &(sa.sin_addr)) == 1) {
return nethost6(network, prefix, num);
}
return std::unexpected(std::format("Unknown network address {}", network));
}
+11
View File
@@ -0,0 +1,11 @@
#ifndef NETWORKAUX_HPP
#include <expected>
#include <string>
std::expected<std::string, std::string> nethost(std::string network, int prefix, uint32_t num);
std::expected<uint32_t, std::string> netprefix(const std::string network);
std::expected<std::string, std::string> network(const std::string network);
#endif
+49 -10
View File
@@ -19,29 +19,68 @@ extern "C" {
#include <uxcontrol.pb.h> #include <uxcontrol.pb.h>
const std::string internetPkgMsg = "internetPkg";
const std::string tunAddressMsg = "tunAddress";
const std::string Msg = "localRoute";
using namespace std::chrono_literals; using namespace std::chrono_literals;
void SocketHandler::Handle(int newsock) { void SocketHandler::Handle(int newsock, std::string laddr, std::string raddr, int prefix) {
sock = newsock; sock = newsock;
auto interfaceName = std::format("uxsrv{}", sock);
auto createRes = interface.Create(std::format("uxsrv{}", sock)); auto createRes = interface.Create(interfaceName);
if (!createRes) { if (!createRes) {
uxlogger.Log(createRes.error()); uxlogger.Error(createRes.error());
return;
}
uxlogger.Debug(std::format("Set local ip address {}/{} for {}", laddr, prefix, interfaceName));
auto setAddrRes = interface.SetIP4Address(laddr);
if (!setAddrRes) {
uxlogger.Error(setAddrRes.error());
return;
}
auto setPrefixRes = interface.SetIP4Netmask(prefix);
if (!setPrefixRes) {
uxlogger.Error(setPrefixRes.error());
return; return;
} }
auto upRes = interface.Up(); auto upRes = interface.Up();
if (!createRes) { if (!createRes) {
uxlogger.Log(createRes.error()); uxlogger.Error(createRes.error());
return; return;
} }
std::thread sendThr(&SocketHandler::SendMessages, this);
sendThr.detach();
std::thread recvThr(&SocketHandler::RecvMessages, this); std::thread recvThr(&SocketHandler::RecvMessages, this);
recvThr.detach(); recvThr.detach();
#if 1
uxcontrol::AddressMessage addrMsg;
auto meta = addrMsg.mutable_meta();
meta->set_kind(tunAddressMsg);
addrMsg.set_address(raddr);
addrMsg.set_prefix(prefix);
std::string rawMessage;
addrMsg.SerializeToString(&rawMessage);
MessageHeader header(rawMessage.size());
auto rawHeader = header.Encode();
std::string rawPacket;
rawPacket.append(rawHeader);
rawPacket.append(rawMessage);
int wsize;
if ((wsize = write(sock, rawPacket.data(), rawPacket.size())) < 0) {
int errnoCopy = errno;
std::string error = std::strerror(errnoCopy);
uxlogger.Log(std::format("Write message error: {}", error));
return;
}
#endif
std::thread sendThr(&SocketHandler::SendMessages, this);
sendThr.detach();
done.acquire(); done.acquire();
uxlogger.Log("Handler done"); uxlogger.Log("Handler done");
} }
@@ -60,7 +99,7 @@ void SocketHandler::SendMessages(void) {
break; break;
} }
} }
std::this_thread::sleep_for(std::chrono::seconds(1)); std::this_thread::sleep_for(std::chrono::seconds(30));
} }
done.release(); done.release();
uxlogger.Log("Send messages done"); uxlogger.Log("Send messages done");
@@ -86,7 +125,7 @@ void SocketHandler::RecvMessages(void) {
uxlogger.Log(std::format("Decode header error: {}", decodeRes.error())); uxlogger.Log(std::format("Decode header error: {}", decodeRes.error()));
break; break;
} }
auto pSize = header.PacketSize(); auto pSize = header.PayloadSize();
if (pSize > 0) { if (pSize > 0) {
std::string rawMessage(pSize, 0); std::string rawMessage(pSize, 0);
if ((rsize = recv(sock, rawMessage.data(), rawMessage.size(), MSG_WAITALL)) < 0) { if ((rsize = recv(sock, rawMessage.data(), rawMessage.size(), MSG_WAITALL)) < 0) {
+6 -1
View File
@@ -9,6 +9,11 @@
#include <interface.hpp> #include <interface.hpp>
extern const std::string internetPkgMsg;
extern const std::string tunAddressMsg;
extern const std::string localRouteMsg;
class SocketHandler { class SocketHandler {
private: private:
int sock; int sock;
@@ -16,7 +21,7 @@ private:
std::binary_semaphore done{0}; std::binary_semaphore done{0};
Interface interface; Interface interface;
public: public:
void Handle(int newsock); void Handle(int newsock, std::string laddr, std::string raddr, int prefix);
void RecvMessages(void); void RecvMessages(void);
void SendMessages(void); void SendMessages(void);
}; };
+97
View File
@@ -0,0 +1,97 @@
#include <expected>
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <stdexcept>
#include <string>
#include <utility>
#include <srvconfig.hpp>
#include <stringaux.hpp>
#include <networkaux.hpp>
int ServConfig::Listenport(void) {
return listenport;
}
std::vector<std::string> ServConfig::Localnets(void) {
return localnets;
}
std::string ServConfig::Tunnelnet(void) {
return tunnelnet;
}
std::expected<void, std::string> ServConfig::Read(std::string filename) {
std::ifstream file;
file.open(filename);
if (file.fail()) {
auto state = file.rdstate();
if (state & std::ios_base::badbit) {
return std::unexpected("Read/writing error on i/o operation");
} else if (state & std::ios_base::failbit) {
return std::unexpected("Logical error on i/o operation");
}
}
std::string line;
while (std::getline(file, line)) {
auto tokens = split(line, "#;");
auto keyval = trim(tokens[0]);
if (keyval.size() == 0) continue;
tokens = split(keyval, "=");
if (tokens.size() < 2) continue;
auto key = trim(tokens[0]);
auto val = trim(tokens[1]);
kvmap[key] = val;
if (key == "localnet") {
localnets.push_back(val);
} else if (key == "tunnelnet") {
tunnelnet = val;
} else if (key == "listenport") {
auto convRes = strtoint(val);
if (!convRes) {
auto msg = std::format("listenport: {}", convRes.error());
return std::unexpected(msg);
}
listenport = convRes.value();
}
}
file.close();
return {};
}
std::expected<void, std::string> ServConfig::Validate(void) {
if (tunnelnet.size() == 0) {
return std::unexpected("Empty tunnel network");
}
if (listenport == 0) {
return std::unexpected("Zero listen port");
}
auto netprefixRes = netprefix(tunnelnet);
if (!netprefixRes) {
return std::unexpected("Incorrect tunnel network:" + netprefixRes.error());
}
auto networkRes = network(tunnelnet);
if (!networkRes) {
return std::unexpected("Incorrect tunnel network:" + networkRes.error());
}
for (const auto& val : localnets) {
auto netprefixRes = netprefix(val);
if (!netprefixRes) {
return std::unexpected("Incorrect local network " + val + ":" + netprefixRes.error());
}
auto networkRes = network(val);
if (!networkRes) {
return std::unexpected("Incorrect local network " + val + ":" + networkRes.error());
}
}
return {};
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef SRVCONFIG_HPP
#define SRVCONFIG_HPP
#include <string>
#include <expected>
#include <map>
#include <vector>
class ServConfig {
private:
std::map<std::string, std::string> kvmap;
std::vector<std::string> localnets;
std::string tunnelnet;
int listenport;
public:
std::expected<void, std::string> Read(std::string filename);
int Listenport(void);
std::string Tunnelnet(void);
std::vector<std::string> Localnets(void);
std::expected<void, std::string> Validate(void);
};
#endif
+39
View File
@@ -0,0 +1,39 @@
#include <expected>
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <cstring>
std::vector<std::string> split(std::string s, std::string delimiters) {
std::vector<std::string> tokens;
size_t last = 0, next = 0;
while ((next = s.find_first_of(delimiters, last)) != std::string::npos) {
if (next != last) tokens.push_back(s.substr(last, next - last));
last = next + 1;
}
if (last < s.length()) tokens.push_back(s.substr(last));
return tokens;
}
std::string trim(std::string& source) {
auto line = source;
std::string whitespaces(" \t\n\r\f\v");
line.erase(0, line.find_first_not_of(whitespaces));
line.erase(line.find_last_not_of(whitespaces) + 1);
return line;
}
std::expected<int, std::string> strtoint (std::string source) {
std::size_t pos{};
int res;
try {
res = std::stoi(source, &pos);
} catch (std::invalid_argument const& ex) {
return std::unexpected(std::format("invalid argument:{}", ex.what()));
} catch (std::out_of_range const& ex) {
return std::unexpected(std::format("out of range", ex.what()));
}
return res;
}
+13
View File
@@ -0,0 +1,13 @@
#ifndef STRINGAUX_HPP
#define STRINGAUX_HPP
#include <string>
#include <vector>
#include <expected>
std::vector<std::string> split(std::string s, std::string delimiters);
std::string trim(std::string& source);
std::expected<int, std::string> strtoint (std::string source);
#endif
+39 -12
View File
@@ -11,18 +11,21 @@ extern "C" {
#include <tservice.hpp> #include <tservice.hpp>
#include <uxlogger.hpp> #include <uxlogger.hpp>
#include <networkaux.hpp>
using namespace std::chrono_literals; using namespace std::chrono_literals;
TCPService::TCPService(int svcport) { TunService::TunService(int svcport, std::string itunnelnet, std::vector<std::string> ilocalnets) {
port = svcport; listenport = svcport;
tunnelnet = itunnelnet;
localnets = ilocalnets;
} }
TCPService::~TCPService() { TunService::~TunService() {
close(port); close(listenport);
} }
std::expected<void, std::string> TCPService::Bind(void) { std::expected<void, std::string> TunService::Bind(void) {
struct sockaddr_in address; struct sockaddr_in address;
int srvsock; int srvsock;
if ((srvsock = socket(AF_INET, SOCK_STREAM, 0)) == 0) { if ((srvsock = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
@@ -38,7 +41,7 @@ std::expected<void, std::string> TCPService::Bind(void) {
} }
address.sin_family = AF_INET; address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY; address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(port); address.sin_port = htons(listenport);
if (bind(srvsock, (struct sockaddr *)&address, sizeof(address)) < 0) { if (bind(srvsock, (struct sockaddr *)&address, sizeof(address)) < 0) {
int errnocopy = errno; int errnocopy = errno;
std::string error = std::strerror(errnocopy); std::string error = std::strerror(errnocopy);
@@ -53,7 +56,7 @@ std::expected<void, std::string> TCPService::Bind(void) {
return {}; return {};
} }
std::expected<void, std::string> TCPService::Listen(void) { std::expected<void, std::string> TunService::Listen(void) {
struct sockaddr_in address; struct sockaddr_in address;
int addrlen = sizeof(address); int addrlen = sizeof(address);
int newsock = 0; int newsock = 0;
@@ -63,18 +66,42 @@ std::expected<void, std::string> TCPService::Listen(void) {
std::string error = std::strerror(errnocopy); std::string error = std::strerror(errnocopy);
return std::unexpected("Accept error: " + error); return std::unexpected("Accept error: " + error);
} }
std::jthread t(&TCPService::Handle, this, newsock);
std::jthread t(&TunService::Handle, this, newsock);
t.detach(); t.detach();
} }
return {}; return {};
} }
void TCPService::Handle(int sock) { void TunService::Handle(int sock) {
uxlogger.Log("Start socker handler"); auto prefixRes = netprefix(tunnelnet);
if (!prefixRes) {
uxlogger.Error(prefixRes.error());
return;
}
auto networkRes = network(tunnelnet);
if (!networkRes) {
uxlogger.Error(networkRes.error());
return;
}
auto localaddrRes = nethost(networkRes.value(), prefixRes.value(), sock);
if (!networkRes) {
uxlogger.Error(networkRes.error());
return;
}
auto remoteaddrRes = nethost(networkRes.value(), prefixRes.value(), sock + 1);
if (!remoteaddrRes) {
uxlogger.Error(remoteaddrRes.error());
return;
}
uxlogger.Debug("Start socker handler");
SocketHandler handler; SocketHandler handler;
handler.Handle(sock); std::string laddr = localaddrRes.value();
uxlogger.Log("Stop socker handler"); std::string raddr = remoteaddrRes.value();
auto prefix = prefixRes.value();
handler.Handle(sock, laddr, raddr, prefix);
uxlogger.Debug("Stop socker handler");
close(sock); close(sock);
} }
+7 -4
View File
@@ -4,19 +4,22 @@
#include <expected> #include <expected>
#include <string> #include <string>
#include <vector>
#include <sockhand.hpp> #include <sockhand.hpp>
class TCPService { class TunService {
private: private:
int port; std::string tunnelnet;
std::vector<std::string> localnets;
int listenport;
int sock; int sock;
public: public:
explicit TCPService(int port); explicit TunService(int port, std::string tunnelnet, std::vector<std::string> localnets);
std::expected<void, std::string> Bind(void); std::expected<void, std::string> Bind(void);
std::expected<void, std::string> Listen(void); std::expected<void, std::string> Listen(void);
void Handle(int sock); void Handle(int sock);
~TCPService(); ~TunService();
}; };
#endif #endif
+7 -1
View File
@@ -86,6 +86,7 @@ void UxClient::RecvMessages(void) {
std::string rawHeader(msgHeaderSize, 0); std::string rawHeader(msgHeaderSize, 0);
if ((rsize = recv(sock, rawHeader.data(), rawHeader.size(), MSG_WAITALL)) < 0) { if ((rsize = recv(sock, rawHeader.data(), rawHeader.size(), MSG_WAITALL)) < 0) {
int errnoCopy = errno; int errnoCopy = errno;
uxlogger.Log(std::format("Read0 header error: {}", errno));
std::string error = std::strerror(errnoCopy); std::string error = std::strerror(errnoCopy);
uxlogger.Log(std::format("Read header error: {}", error)); uxlogger.Log(std::format("Read header error: {}", error));
break; break;
@@ -99,7 +100,7 @@ void UxClient::RecvMessages(void) {
if (!decodeRes) { if (!decodeRes) {
uxlogger.Log(std::format("Decode header error: {}", decodeRes.error())); uxlogger.Log(std::format("Decode header error: {}", decodeRes.error()));
} }
auto pSize = header.PacketSize(); auto pSize = header.PayloadSize();
if (pSize > 0) { if (pSize > 0) {
std::string rawMessage(pSize, 0); std::string rawMessage(pSize, 0);
if ((rsize = recv(sock, rawMessage.data(), rawMessage.size(), MSG_WAITALL)) < 0) { if ((rsize = recv(sock, rawMessage.data(), rawMessage.size(), MSG_WAITALL)) < 0) {
@@ -109,6 +110,7 @@ void UxClient::RecvMessages(void) {
break; break;
} }
} }
uxlogger.Log(std::format("Receive message with size {}", pSize)); uxlogger.Log(std::format("Receive message with size {}", pSize));
} }
done.release(); done.release();
@@ -117,6 +119,9 @@ void UxClient::RecvMessages(void) {
void UxClient::SendMessages(void) { void UxClient::SendMessages(void) {
while (true) { while (true) {
std::this_thread::sleep_for(std::chrono::seconds(10));
continue;
auto readRes = interface.Read(); auto readRes = interface.Read();
if (!readRes) { if (!readRes) {
uxlogger.Log(std::format("Read packet error: {}", readRes.error())); uxlogger.Log(std::format("Read packet error: {}", readRes.error()));
@@ -133,6 +138,7 @@ void UxClient::SendMessages(void) {
MessageHeader header(rawMessage.size()); MessageHeader header(rawMessage.size());
auto rawHeader = header.Encode(); auto rawHeader = header.Encode();
int wsize = 0; int wsize = 0;
if ((wsize = send(sock, rawHeader.data(), rawHeader.size(), 0)) < 0) { if ((wsize = send(sock, rawHeader.data(), rawHeader.size(), 0)) < 0) {
int errnoCopy = errno; int errnoCopy = errno;
+10 -10
View File
@@ -65,7 +65,7 @@ PROTOBUF_CONSTEXPR AddressMessage::AddressMessage(
::_pbi::ConstantInitialized): _impl_{ ::_pbi::ConstantInitialized): _impl_{
/*decltype(_impl_.address_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}} /*decltype(_impl_.address_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
, /*decltype(_impl_.meta_)*/nullptr , /*decltype(_impl_.meta_)*/nullptr
, /*decltype(_impl_.prefix_)*/uint64_t{0u} , /*decltype(_impl_.prefix_)*/0u
, /*decltype(_impl_._cached_size_)*/{}} {} , /*decltype(_impl_._cached_size_)*/{}} {}
struct AddressMessageDefaultTypeInternal { struct AddressMessageDefaultTypeInternal {
PROTOBUF_CONSTEXPR AddressMessageDefaultTypeInternal() PROTOBUF_CONSTEXPR AddressMessageDefaultTypeInternal()
@@ -185,7 +185,7 @@ const char descriptor_table_protodef_uxcontrol_2eproto[] PROTOBUF_SECTION_VARIAB
"Message\022#\n\004meta\030\001 \001(\0132\025.uxcontrol.MetaHe" "Message\022#\n\004meta\030\001 \001(\0132\025.uxcontrol.MetaHe"
"ader\022\017\n\007payload\030\002 \001(\014\"V\n\016AddressMessage\022" "ader\022\017\n\007payload\030\002 \001(\014\"V\n\016AddressMessage\022"
"#\n\004meta\030\001 \001(\0132\025.uxcontrol.MetaHeader\022\017\n\007" "#\n\004meta\030\001 \001(\0132\025.uxcontrol.MetaHeader\022\017\n\007"
"address\030\002 \001(\t\022\016\n\006prefix\030\003 \001(\004\"T\n\014RouteMe" "address\030\002 \001(\t\022\016\n\006prefix\030\003 \001(\r\"T\n\014RouteMe"
"ssage\022#\n\004meta\030\001 \001(\0132\025.uxcontrol.MetaHead" "ssage\022#\n\004meta\030\001 \001(\0132\025.uxcontrol.MetaHead"
"er\022\017\n\007address\030\002 \001(\t\022\016\n\006prefix\030\003 \001(\004\"D\n\014H" "er\022\017\n\007address\030\002 \001(\t\022\016\n\006prefix\030\003 \001(\004\"D\n\014H"
"elloMessage\022#\n\004meta\030\001 \001(\0132\025.uxcontrol.Me" "elloMessage\022#\n\004meta\030\001 \001(\0132\025.uxcontrol.Me"
@@ -893,7 +893,7 @@ inline void AddressMessage::SharedCtor(
new (&_impl_) Impl_{ new (&_impl_) Impl_{
decltype(_impl_.address_){} decltype(_impl_.address_){}
, decltype(_impl_.meta_){nullptr} , decltype(_impl_.meta_){nullptr}
, decltype(_impl_.prefix_){uint64_t{0u}} , decltype(_impl_.prefix_){0u}
, /*decltype(_impl_._cached_size_)*/{} , /*decltype(_impl_._cached_size_)*/{}
}; };
_impl_.address_.InitDefault(); _impl_.address_.InitDefault();
@@ -932,7 +932,7 @@ void AddressMessage::Clear() {
delete _impl_.meta_; delete _impl_.meta_;
} }
_impl_.meta_ = nullptr; _impl_.meta_ = nullptr;
_impl_.prefix_ = uint64_t{0u}; _impl_.prefix_ = 0u;
_internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
} }
@@ -960,10 +960,10 @@ const char* AddressMessage::_InternalParse(const char* ptr, ::_pbi::ParseContext
} else } else
goto handle_unusual; goto handle_unusual;
continue; continue;
// uint64 prefix = 3; // uint32 prefix = 3;
case 3: case 3:
if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) { if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 24)) {
_impl_.prefix_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); _impl_.prefix_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint32(&ptr);
CHK_(ptr); CHK_(ptr);
} else } else
goto handle_unusual; goto handle_unusual;
@@ -1014,10 +1014,10 @@ uint8_t* AddressMessage::_InternalSerialize(
2, this->_internal_address(), target); 2, this->_internal_address(), target);
} }
// uint64 prefix = 3; // uint32 prefix = 3;
if (this->_internal_prefix() != 0) { if (this->_internal_prefix() != 0) {
target = stream->EnsureSpace(target); target = stream->EnsureSpace(target);
target = ::_pbi::WireFormatLite::WriteUInt64ToArray(3, this->_internal_prefix(), target); target = ::_pbi::WireFormatLite::WriteUInt32ToArray(3, this->_internal_prefix(), target);
} }
if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
@@ -1050,9 +1050,9 @@ size_t AddressMessage::ByteSizeLong() const {
*_impl_.meta_); *_impl_.meta_);
} }
// uint64 prefix = 3; // uint32 prefix = 3;
if (this->_internal_prefix() != 0) { if (this->_internal_prefix() != 0) {
total_size += ::_pbi::WireFormatLite::UInt64SizePlusOne(this->_internal_prefix()); total_size += ::_pbi::WireFormatLite::UInt32SizePlusOne(this->_internal_prefix());
} }
return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
+12 -12
View File
@@ -716,13 +716,13 @@ class AddressMessage final :
::uxcontrol::MetaHeader* meta); ::uxcontrol::MetaHeader* meta);
::uxcontrol::MetaHeader* unsafe_arena_release_meta(); ::uxcontrol::MetaHeader* unsafe_arena_release_meta();
// uint64 prefix = 3; // uint32 prefix = 3;
void clear_prefix(); void clear_prefix();
uint64_t prefix() const; uint32_t prefix() const;
void set_prefix(uint64_t value); void set_prefix(uint32_t value);
private: private:
uint64_t _internal_prefix() const; uint32_t _internal_prefix() const;
void _internal_set_prefix(uint64_t value); void _internal_set_prefix(uint32_t value);
public: public:
// @@protoc_insertion_point(class_scope:uxcontrol.AddressMessage) // @@protoc_insertion_point(class_scope:uxcontrol.AddressMessage)
@@ -735,7 +735,7 @@ class AddressMessage final :
struct Impl_ { struct Impl_ {
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr address_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr address_;
::uxcontrol::MetaHeader* meta_; ::uxcontrol::MetaHeader* meta_;
uint64_t prefix_; uint32_t prefix_;
mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
}; };
union { Impl_ _impl_; }; union { Impl_ _impl_; };
@@ -1541,22 +1541,22 @@ inline void AddressMessage::set_allocated_address(std::string* address) {
// @@protoc_insertion_point(field_set_allocated:uxcontrol.AddressMessage.address) // @@protoc_insertion_point(field_set_allocated:uxcontrol.AddressMessage.address)
} }
// uint64 prefix = 3; // uint32 prefix = 3;
inline void AddressMessage::clear_prefix() { inline void AddressMessage::clear_prefix() {
_impl_.prefix_ = uint64_t{0u}; _impl_.prefix_ = 0u;
} }
inline uint64_t AddressMessage::_internal_prefix() const { inline uint32_t AddressMessage::_internal_prefix() const {
return _impl_.prefix_; return _impl_.prefix_;
} }
inline uint64_t AddressMessage::prefix() const { inline uint32_t AddressMessage::prefix() const {
// @@protoc_insertion_point(field_get:uxcontrol.AddressMessage.prefix) // @@protoc_insertion_point(field_get:uxcontrol.AddressMessage.prefix)
return _internal_prefix(); return _internal_prefix();
} }
inline void AddressMessage::_internal_set_prefix(uint64_t value) { inline void AddressMessage::_internal_set_prefix(uint32_t value) {
_impl_.prefix_ = value; _impl_.prefix_ = value;
} }
inline void AddressMessage::set_prefix(uint64_t value) { inline void AddressMessage::set_prefix(uint32_t value) {
_internal_set_prefix(value); _internal_set_prefix(value);
// @@protoc_insertion_point(field_set:uxcontrol.AddressMessage.prefix) // @@protoc_insertion_point(field_set:uxcontrol.AddressMessage.prefix)
} }
+1 -1
View File
@@ -21,7 +21,7 @@ message PacketMessage {
message AddressMessage { message AddressMessage {
MetaHeader meta = 1; MetaHeader meta = 1;
string address = 2; string address = 2;
uint64 prefix = 3; uint32 prefix = 3;
} }
message RouteMessage { message RouteMessage {
+25
View File
@@ -22,6 +22,7 @@ UxLogger::UxLogger(const std::string ilabel) {
UxLogger::UxLogger(void) { UxLogger::UxLogger(void) {
label = "global"; label = "global";
} }
void UxLogger::Log(const std::string& message) { void UxLogger::Log(const std::string& message) {
auto now = std::chrono::system_clock::now(); auto now = std::chrono::system_clock::now();
std::chrono::zoned_time localnow{std::chrono::current_zone(), now}; std::chrono::zoned_time localnow{std::chrono::current_zone(), now};
@@ -30,3 +31,27 @@ void UxLogger::Log(const std::string& message) {
std::cout << std::format("{} {} {}\n", timenow, label, message); std::cout << std::format("{} {} {}\n", timenow, label, message);
} }
void UxLogger::Debug(const std::string& message) {
LogLevel("debug", message);
}
void UxLogger::Info(const std::string& message) {
LogLevel("info", message);
}
void UxLogger::Warning(const std::string& message) {
LogLevel("warning", message);
}
void UxLogger::Error(const std::string& message) {
LogLevel("error", message);
}
void UxLogger::LogLevel(const std::string level, const std::string& message) {
auto now = std::chrono::system_clock::now();
std::chrono::zoned_time localnow{std::chrono::current_zone(), now};
std::string timenow = std::format("{:%Y-%m-%dT%H:%M:%OS%Z}", localnow);
std::lock_guard<std::mutex> lock(mtx);
std::cout << std::format("{} {} {} {}\n", timenow, level, label, message);
}
+6
View File
@@ -11,12 +11,18 @@
class UxLogger { class UxLogger {
private: private:
std::string label; std::string label;
void LogLevel(const std::string level, const std::string& message);
public: public:
UxLogger(std::string ilabel); UxLogger(std::string ilabel);
UxLogger(); UxLogger();
void Log(const std::string& message); void Log(const std::string& message);
void Debug(const std::string& message);
void Info(const std::string& message);
void Warning(const std::string& message);
void Error(const std::string& message);
}; };
extern UxLogger uxlogger; extern UxLogger uxlogger;
#endif #endif
+126
View File
@@ -0,0 +1,126 @@
#include <expected>
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <stdexcept>
#include <string>
#include <utility>
std::vector<std::string> split(std::string s, std::string delimiters) {
std::vector<std::string> tokens;
size_t last = 0, next = 0;
while ((next = s.find_first_of(delimiters, last)) != std::string::npos) {
if (next != last) tokens.push_back(s.substr(last, next - last));
last = next + 1;
}
if (last < s.length()) tokens.push_back(s.substr(last));
return tokens;
}
std::string trim(std::string& source) {
auto line = source;
std::string whitespaces(" \t\n\r\f\v");
line.erase(0, line.find_first_not_of(whitespaces));
line.erase(line.find_last_not_of(whitespaces) + 1);
return line;
}
std::expected<int, std::string> str2int (std::string source) {
std::size_t pos{};
int res;
try {
res = std::stoi(source, &pos);
}
catch (std::invalid_argument const& ex) {
return std::unexpected(std::format("invalid argument:{}", ex.what()));
}
catch (std::out_of_range const& ex) {
return std::unexpected(std::format("out of range", ex.what()));
}
return res;
}
class Registry {
private:
std::map<std::string, std::string> kvmap;
std::vector<std::string> localnets;
std::string tunnelnet;
int listenport;
public:
std::expected<void, std::string> Read(std::string filename);
int Listenport(void);
std::string Tunnelnet(void);
std::vector<std::string> Localnets(void);
};
int Registry::Listenport(void){
return listenport;
}
std::vector<std::string> Registry::Localnets(void){
return localnets;
}
std::string Registry::Tunnelnet(void){
return tunnelnet;
}
std::expected<void, std::string> Registry::Read(std::string filename) {
std::ifstream file;
file.open(filename);
if (file.fail()) {
auto state = file.rdstate();
if (state & std::ios_base::badbit) {
return std::unexpected("Read/writing error on i/o operation");
} else if (state & std::ios_base::failbit) {
return std::unexpected("Logical error on i/o operation");
}
}
std::string line;
while (std::getline(file, line)) {
auto tokens = split(line, "#;");
auto keyval = trim(tokens[0]);
if (keyval.size() == 0) continue;
tokens = split(keyval, "=");
if (tokens.size() < 2) continue;
auto key = trim(tokens[0]);
auto val = trim(tokens[1]);
kvmap[key] = val;
if (key == "localnet") {
localnets.push_back(val);
} else if (key == "tunnelnet") {
tunnelnet = val;
} else if (key == "listenport") {
auto convRes = str2int(val);
if (!convRes) {
auto msg = std::format("listenport: {}", convRes.error());
return std::unexpected(msg);
}
listenport = convRes.value();
}
}
file.close();
//for (auto const& [key, val] : kvmap) {
// std::cout << key << ":" << val << std::endl;
//}
return {};
}
int main() {
Registry config;
auto openRes = config.Read("example.conf");
if (!openRes) {
std::cerr << openRes.error() << std::endl;
return 1;
}
return 0;
}
+5
View File
@@ -0,0 +1,5 @@
# foo
# foobare
localnet == 10.1.1.0/24 #qwert
localnet == 10.1.2.0/24 #qwert
ddd =
+17 -8
View File
@@ -10,7 +10,7 @@ extern "C" {
#include <ostream> #include <ostream>
#include <iostream> #include <iostream>
std::expected<std::string, std::string> network6(std::string network, int prefix) { std::expected<std::string, std::string> nethost6(std::string network, int prefix, uint32_t num) {
struct in6_addr addr; struct in6_addr addr;
unsigned char mask[16] = {0}; unsigned char mask[16] = {0};
if (inet_pton(AF_INET6, network.data(), &addr) != 1) { if (inet_pton(AF_INET6, network.data(), &addr) != 1) {
@@ -25,7 +25,7 @@ std::expected<std::string, std::string> network6(std::string network, int prefix
uint64_t *host_part = (uint64_t *)&addr.s6_addr[8]; uint64_t *host_part = (uint64_t *)&addr.s6_addr[8];
uint64_t hostnum = be64toh(*host_part); uint64_t hostnum = be64toh(*host_part);
hostnum += 2; hostnum += num;
*host_part = htobe64(hostnum); *host_part = htobe64(hostnum);
char buffer[INET6_ADDRSTRLEN] = {'\0'}; char buffer[INET6_ADDRSTRLEN] = {'\0'};
@@ -35,29 +35,38 @@ std::expected<std::string, std::string> network6(std::string network, int prefix
} }
std::expected<std::string, std::string> network4(std::string network, int prefix) { std::expected<std::string, std::string> nethost4(std::string network, int prefix, uint32_t num) {
struct in_addr inaddr; struct in_addr inaddr;
if (inet_pton(AF_INET, network.data(), &inaddr) != 1) { if (inet_pton(AF_INET, network.data(), &inaddr) != 1) {
return std::unexpected(std::format("Invalid network address {}", network)); return std::unexpected(std::format("Invalid network address {}", network));
} }
uint32_t ip = ntohl(inaddr.s_addr); uint32_t ip = ntohl(inaddr.s_addr);
uint32_t mask = (prefix == 0) ? 0 : (~0U << (32 - prefix)); uint32_t mask = (prefix == 0) ? 0 : (~0U << (32 - prefix));
uint32_t fip = (ip & mask) + 1; uint32_t fip = (ip & mask) + num;
struct in_addr ip_addr; struct in_addr ip_addr;
ip_addr.s_addr = htonl(ip); ip_addr.s_addr = htonl(fip);
return std::string(inet_ntoa(ip_addr)); return std::string(inet_ntoa(ip_addr));
} }
std::expected<std::string, std::string> nethost(std::string network, int prefix, uint32_t num) {
struct sockaddr_in sa;
if (inet_pton(AF_INET, network.data(), &(sa.sin_addr)) == 1) {
return nethost4(network, prefix, num);
} else if (inet_pton(AF_INET6, network.data(), &(sa.sin_addr)) == 1) {
return nethost6(network, prefix, num);
}
return std::unexpected(std::format("Unknown network address {}", network));
}
int main() { int main() {
auto net4Res = network4("192.168.1.154", 26); auto net4Res = nethost4("192.168.1.151", 24, 1);
if (!net4Res) { if (!net4Res) {
std::cerr << net4Res.error() << std::endl; std::cerr << net4Res.error() << std::endl;
return 1; return 1;
} }
std::cout << net4Res.value() << std::endl; std::cout << net4Res.value() << std::endl;
auto net6Res = network6("2001:db8:abcd:1234::0", 64); auto net6Res = nethost6("2001:db8:abcd:1234::0", 64, 1);
if (!net6Res) { if (!net6Res) {
std::cerr << net6Res.error() << std::endl; std::cerr << net6Res.error() << std::endl;
return 1; return 1;