working commit
This commit is contained in:
@@ -105,13 +105,14 @@ CONFIG_CLEAN_VPATH_FILES =
|
||||
am__installdirs = "$(DESTDIR)$(sbindir)"
|
||||
PROGRAMS = $(sbin_PROGRAMS)
|
||||
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__objects_1)
|
||||
helmetcli_OBJECTS = $(am_helmetcli_OBJECTS)
|
||||
helmetcli_LDADD = $(LDADD)
|
||||
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_LDADD = $(LDADD)
|
||||
AM_V_P = $(am__v_P_$(V))
|
||||
@@ -206,7 +207,7 @@ distcleancheck_listfiles = \
|
||||
ACLOCAL = ${SHELL} '/home/ziggi/Projects/stvpn/missing' aclocal-1.17
|
||||
AMTAR = $${TAR-tar}
|
||||
AM_DEFAULT_VERBOSITY = 1
|
||||
ASTYLE = /bin/astyle
|
||||
ASTYLE = /usr/bin/astyle
|
||||
AUTOCONF = ${SHELL} '/home/ziggi/Projects/stvpn/missing' autoconf
|
||||
AUTOHEADER = ${SHELL} '/home/ziggi/Projects/stvpn/missing' autoheader
|
||||
AUTOMAKE = ${SHELL} '/home/ziggi/Projects/stvpn/missing' automake-1.17
|
||||
@@ -219,7 +220,7 @@ CSCOPE = cscope
|
||||
CTAGS = ctags
|
||||
CXX = g++
|
||||
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
|
||||
DEFS = -DHAVE_CONFIG_H
|
||||
DEPDIR = .deps
|
||||
@@ -228,7 +229,7 @@ ECHO_N = -n
|
||||
ECHO_T =
|
||||
ETAGS = etags
|
||||
EXEEXT =
|
||||
INSTALL = /bin/install -c
|
||||
INSTALL = /usr/bin/install -c
|
||||
INSTALL_DATA = ${INSTALL} -m 644
|
||||
INSTALL_PROGRAM = ${INSTALL}
|
||||
INSTALL_SCRIPT = ${INSTALL}
|
||||
@@ -238,7 +239,7 @@ LIBOBJS =
|
||||
LIBS = -Wl,--as-need -lprotobuf
|
||||
LTLIBOBJS =
|
||||
MAKEINFO = ${SHELL} '/home/ziggi/Projects/stvpn/missing' makeinfo
|
||||
MKDIR_P = /bin/mkdir -p
|
||||
MKDIR_P = /usr/bin/mkdir -p
|
||||
OBJEXT = o
|
||||
PACKAGE = helmet
|
||||
PACKAGE_BUGREPORT =
|
||||
@@ -248,7 +249,7 @@ PACKAGE_TARNAME = helmet
|
||||
PACKAGE_URL =
|
||||
PACKAGE_VERSION = 0.0.1
|
||||
PATH_SEPARATOR = :
|
||||
PROTOC = /bin/protoc
|
||||
PROTOC = /usr/bin/protoc
|
||||
RANLIB = ranlib
|
||||
SET_MAKE =
|
||||
SHELL = /bin/bash
|
||||
@@ -304,6 +305,7 @@ AUTOMAKE_OPTIONS = foreign no-dependencies no-installinfo subdir-objects
|
||||
helmetsrv_SOURCES = helmetsrv.cpp \
|
||||
tservice.cpp tservice.hpp \
|
||||
sockhand.cpp dockhand.hpp \
|
||||
srvconfig.cpp srvconfig.hpp \
|
||||
$(helmet_SOURCES)
|
||||
|
||||
helmetcli_SOURCES = helmetcli.cpp \
|
||||
@@ -315,6 +317,8 @@ helmet_SOURCES = \
|
||||
msgheader.cpp msgheader.hpp \
|
||||
interface.cpp interface.hpp \
|
||||
iprouter.cpp iprouter.hpp \
|
||||
stringaux.cpp stringaux.hpp \
|
||||
networkaux.cpp networkaux.hpp \
|
||||
uxcontrol.pb.cc uxcontrol.pb.h
|
||||
|
||||
ASTYLE_OPTS = --indent=spaces=8 --style=java
|
||||
|
||||
+4
-1
@@ -1,7 +1,7 @@
|
||||
|
||||
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
|
||||
LIBS = -Wl,--as-need -lprotobuf
|
||||
|
||||
@@ -10,6 +10,7 @@ sbin_PROGRAMS = helmetsrv helmetcli
|
||||
helmetsrv_SOURCES = helmetsrv.cpp \
|
||||
tservice.cpp tservice.hpp \
|
||||
sockhand.cpp dockhand.hpp \
|
||||
srvconfig.cpp srvconfig.hpp \
|
||||
$(helmet_SOURCES)
|
||||
|
||||
helmetcli_SOURCES = helmetcli.cpp \
|
||||
@@ -21,6 +22,8 @@ helmet_SOURCES = \
|
||||
msgheader.cpp msgheader.hpp \
|
||||
interface.cpp interface.hpp \
|
||||
iprouter.cpp iprouter.hpp \
|
||||
stringaux.cpp stringaux.hpp \
|
||||
networkaux.cpp networkaux.hpp \
|
||||
uxcontrol.pb.cc uxcontrol.pb.h
|
||||
|
||||
ASTYLE_OPTS = --indent=spaces=8 --style=java
|
||||
|
||||
+7
-3
@@ -105,13 +105,14 @@ CONFIG_CLEAN_VPATH_FILES =
|
||||
am__installdirs = "$(DESTDIR)$(sbindir)"
|
||||
PROGRAMS = $(sbin_PROGRAMS)
|
||||
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__objects_1)
|
||||
helmetcli_OBJECTS = $(am_helmetcli_OBJECTS)
|
||||
helmetcli_LDADD = $(LDADD)
|
||||
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_LDADD = $(LDADD)
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
@@ -219,7 +220,7 @@ CSCOPE = @CSCOPE@
|
||||
CTAGS = @CTAGS@
|
||||
CXX = @CXX@
|
||||
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@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
@@ -304,6 +305,7 @@ AUTOMAKE_OPTIONS = foreign no-dependencies no-installinfo subdir-objects
|
||||
helmetsrv_SOURCES = helmetsrv.cpp \
|
||||
tservice.cpp tservice.hpp \
|
||||
sockhand.cpp dockhand.hpp \
|
||||
srvconfig.cpp srvconfig.hpp \
|
||||
$(helmet_SOURCES)
|
||||
|
||||
helmetcli_SOURCES = helmetcli.cpp \
|
||||
@@ -315,6 +317,8 @@ helmet_SOURCES = \
|
||||
msgheader.cpp msgheader.hpp \
|
||||
interface.cpp interface.hpp \
|
||||
iprouter.cpp iprouter.hpp \
|
||||
stringaux.cpp stringaux.hpp \
|
||||
networkaux.cpp networkaux.hpp \
|
||||
uxcontrol.pb.cc uxcontrol.pb.h
|
||||
|
||||
ASTYLE_OPTS = --indent=spaces=8 --style=java
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
listenport = 1025;
|
||||
tunnelnet = 10.1.1.0/24;
|
||||
+27
-5
@@ -5,17 +5,39 @@
|
||||
|
||||
#include <tservice.hpp>
|
||||
#include <uxlogger.hpp>
|
||||
#include <srvconfig.hpp>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
TCPService service(1025);
|
||||
std::expected<void, std::string> Run() {
|
||||
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();
|
||||
if (!bindRes) {
|
||||
uxlogger.Log("Bind error: " + bindRes.error());
|
||||
return 1;
|
||||
return std::unexpected("Bind error: " + bindRes.error());
|
||||
}
|
||||
uxlogger.Info(std::format("Listening on port {}", listport));
|
||||
auto listenRes = service.Listen();
|
||||
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 0;
|
||||
|
||||
+1
-4
@@ -155,14 +155,12 @@ std::expected<void, std::string> Interface::SetIP4Address(std::string ipaddr) {
|
||||
std::string error = std::strerror(errnocopy);
|
||||
return std::unexpected("Set address error: " + error);
|
||||
}
|
||||
|
||||
int sockfd = 0;
|
||||
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
int errnocopy = errno;
|
||||
std::string error = std::strerror(errnocopy);
|
||||
return std::unexpected("Set address error: " + error);
|
||||
}
|
||||
|
||||
if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) {
|
||||
close(sockfd);
|
||||
int errnocopy = errno;
|
||||
@@ -177,8 +175,7 @@ std::expected<void, std::string> Interface::SetIP4Netmask(int prefix) {
|
||||
if (prefix < 0 || prefix > 32) {
|
||||
return std::unexpected("Invalid prefix");
|
||||
}
|
||||
//uint32_t mask = (prefix == 0) ? 0 : (~0U << (32 - prefix));
|
||||
uint32_t mask = (prefix == 0) ? 0 : htonl(~((1U << (32 - prefix)) - 1));
|
||||
uint32_t mask = (prefix == 0) ? 0 : (~0U << (32 - prefix));
|
||||
|
||||
struct in_addr maskaddr;
|
||||
maskaddr.s_addr = htonl(mask);
|
||||
|
||||
+1
-1
@@ -44,6 +44,6 @@ std::expected<void, std::string> MessageHeader::Decode(const std::string rawHead
|
||||
return {};
|
||||
}
|
||||
|
||||
uint32_t MessageHeader::PacketSize() {
|
||||
uint32_t MessageHeader::PayloadSize() {
|
||||
return pSize;
|
||||
}
|
||||
|
||||
+1
-1
@@ -12,6 +12,6 @@ public:
|
||||
MessageHeader(void);
|
||||
std::string Encode(void);
|
||||
std::expected<void, std::string> Decode(const std::string buffer);
|
||||
uint32_t PacketSize(void);
|
||||
uint32_t PayloadSize(void);
|
||||
};
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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
@@ -19,29 +19,68 @@ extern "C" {
|
||||
|
||||
#include <uxcontrol.pb.h>
|
||||
|
||||
const std::string internetPkgMsg = "internetPkg";
|
||||
const std::string tunAddressMsg = "tunAddress";
|
||||
const std::string Msg = "localRoute";
|
||||
|
||||
|
||||
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;
|
||||
|
||||
auto createRes = interface.Create(std::format("uxsrv{}", sock));
|
||||
auto interfaceName = std::format("uxsrv{}", sock);
|
||||
auto createRes = interface.Create(interfaceName);
|
||||
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;
|
||||
}
|
||||
auto upRes = interface.Up();
|
||||
if (!createRes) {
|
||||
uxlogger.Log(createRes.error());
|
||||
uxlogger.Error(createRes.error());
|
||||
return;
|
||||
}
|
||||
|
||||
std::thread sendThr(&SocketHandler::SendMessages, this);
|
||||
sendThr.detach();
|
||||
|
||||
std::thread recvThr(&SocketHandler::RecvMessages, this);
|
||||
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();
|
||||
uxlogger.Log("Handler done");
|
||||
}
|
||||
@@ -60,7 +99,7 @@ void SocketHandler::SendMessages(void) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
std::this_thread::sleep_for(std::chrono::seconds(30));
|
||||
}
|
||||
done.release();
|
||||
uxlogger.Log("Send messages done");
|
||||
@@ -86,7 +125,7 @@ void SocketHandler::RecvMessages(void) {
|
||||
uxlogger.Log(std::format("Decode header error: {}", decodeRes.error()));
|
||||
break;
|
||||
}
|
||||
auto pSize = header.PacketSize();
|
||||
auto pSize = header.PayloadSize();
|
||||
if (pSize > 0) {
|
||||
std::string rawMessage(pSize, 0);
|
||||
if ((rsize = recv(sock, rawMessage.data(), rawMessage.size(), MSG_WAITALL)) < 0) {
|
||||
|
||||
+6
-1
@@ -9,6 +9,11 @@
|
||||
|
||||
#include <interface.hpp>
|
||||
|
||||
extern const std::string internetPkgMsg;
|
||||
extern const std::string tunAddressMsg;
|
||||
extern const std::string localRouteMsg;
|
||||
|
||||
|
||||
class SocketHandler {
|
||||
private:
|
||||
int sock;
|
||||
@@ -16,7 +21,7 @@ private:
|
||||
std::binary_semaphore done{0};
|
||||
Interface interface;
|
||||
public:
|
||||
void Handle(int newsock);
|
||||
void Handle(int newsock, std::string laddr, std::string raddr, int prefix);
|
||||
void RecvMessages(void);
|
||||
void SendMessages(void);
|
||||
};
|
||||
|
||||
@@ -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 {};
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -11,18 +11,21 @@ extern "C" {
|
||||
|
||||
#include <tservice.hpp>
|
||||
#include <uxlogger.hpp>
|
||||
#include <networkaux.hpp>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
TCPService::TCPService(int svcport) {
|
||||
port = svcport;
|
||||
TunService::TunService(int svcport, std::string itunnelnet, std::vector<std::string> ilocalnets) {
|
||||
listenport = svcport;
|
||||
tunnelnet = itunnelnet;
|
||||
localnets = ilocalnets;
|
||||
}
|
||||
|
||||
TCPService::~TCPService() {
|
||||
close(port);
|
||||
TunService::~TunService() {
|
||||
close(listenport);
|
||||
}
|
||||
|
||||
std::expected<void, std::string> TCPService::Bind(void) {
|
||||
std::expected<void, std::string> TunService::Bind(void) {
|
||||
struct sockaddr_in address;
|
||||
int srvsock;
|
||||
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_addr.s_addr = INADDR_ANY;
|
||||
address.sin_port = htons(port);
|
||||
address.sin_port = htons(listenport);
|
||||
if (bind(srvsock, (struct sockaddr *)&address, sizeof(address)) < 0) {
|
||||
int errnocopy = errno;
|
||||
std::string error = std::strerror(errnocopy);
|
||||
@@ -53,7 +56,7 @@ std::expected<void, std::string> TCPService::Bind(void) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, std::string> TCPService::Listen(void) {
|
||||
std::expected<void, std::string> TunService::Listen(void) {
|
||||
struct sockaddr_in address;
|
||||
int addrlen = sizeof(address);
|
||||
int newsock = 0;
|
||||
@@ -63,18 +66,42 @@ std::expected<void, std::string> TCPService::Listen(void) {
|
||||
std::string error = std::strerror(errnocopy);
|
||||
return std::unexpected("Accept error: " + error);
|
||||
}
|
||||
std::jthread t(&TCPService::Handle, this, newsock);
|
||||
|
||||
std::jthread t(&TunService::Handle, this, newsock);
|
||||
t.detach();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
void TCPService::Handle(int sock) {
|
||||
uxlogger.Log("Start socker handler");
|
||||
void TunService::Handle(int sock) {
|
||||
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;
|
||||
handler.Handle(sock);
|
||||
uxlogger.Log("Stop socker handler");
|
||||
std::string laddr = localaddrRes.value();
|
||||
std::string raddr = remoteaddrRes.value();
|
||||
auto prefix = prefixRes.value();
|
||||
handler.Handle(sock, laddr, raddr, prefix);
|
||||
uxlogger.Debug("Stop socker handler");
|
||||
close(sock);
|
||||
}
|
||||
|
||||
|
||||
+7
-4
@@ -4,19 +4,22 @@
|
||||
|
||||
#include <expected>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <sockhand.hpp>
|
||||
|
||||
class TCPService {
|
||||
class TunService {
|
||||
private:
|
||||
int port;
|
||||
std::string tunnelnet;
|
||||
std::vector<std::string> localnets;
|
||||
int listenport;
|
||||
int sock;
|
||||
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> Listen(void);
|
||||
void Handle(int sock);
|
||||
~TCPService();
|
||||
~TunService();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+7
-1
@@ -86,6 +86,7 @@ void UxClient::RecvMessages(void) {
|
||||
std::string rawHeader(msgHeaderSize, 0);
|
||||
if ((rsize = recv(sock, rawHeader.data(), rawHeader.size(), MSG_WAITALL)) < 0) {
|
||||
int errnoCopy = errno;
|
||||
uxlogger.Log(std::format("Read0 header error: {}", errno));
|
||||
std::string error = std::strerror(errnoCopy);
|
||||
uxlogger.Log(std::format("Read header error: {}", error));
|
||||
break;
|
||||
@@ -99,7 +100,7 @@ void UxClient::RecvMessages(void) {
|
||||
if (!decodeRes) {
|
||||
uxlogger.Log(std::format("Decode header error: {}", decodeRes.error()));
|
||||
}
|
||||
auto pSize = header.PacketSize();
|
||||
auto pSize = header.PayloadSize();
|
||||
if (pSize > 0) {
|
||||
std::string rawMessage(pSize, 0);
|
||||
if ((rsize = recv(sock, rawMessage.data(), rawMessage.size(), MSG_WAITALL)) < 0) {
|
||||
@@ -109,6 +110,7 @@ void UxClient::RecvMessages(void) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uxlogger.Log(std::format("Receive message with size {}", pSize));
|
||||
}
|
||||
done.release();
|
||||
@@ -117,6 +119,9 @@ void UxClient::RecvMessages(void) {
|
||||
|
||||
void UxClient::SendMessages(void) {
|
||||
while (true) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(10));
|
||||
continue;
|
||||
|
||||
auto readRes = interface.Read();
|
||||
if (!readRes) {
|
||||
uxlogger.Log(std::format("Read packet error: {}", readRes.error()));
|
||||
@@ -133,6 +138,7 @@ void UxClient::SendMessages(void) {
|
||||
|
||||
MessageHeader header(rawMessage.size());
|
||||
auto rawHeader = header.Encode();
|
||||
|
||||
int wsize = 0;
|
||||
if ((wsize = send(sock, rawHeader.data(), rawHeader.size(), 0)) < 0) {
|
||||
int errnoCopy = errno;
|
||||
|
||||
+10
-10
@@ -65,7 +65,7 @@ PROTOBUF_CONSTEXPR AddressMessage::AddressMessage(
|
||||
::_pbi::ConstantInitialized): _impl_{
|
||||
/*decltype(_impl_.address_)*/{&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}}
|
||||
, /*decltype(_impl_.meta_)*/nullptr
|
||||
, /*decltype(_impl_.prefix_)*/uint64_t{0u}
|
||||
, /*decltype(_impl_.prefix_)*/0u
|
||||
, /*decltype(_impl_._cached_size_)*/{}} {}
|
||||
struct 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"
|
||||
"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"
|
||||
"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"
|
||||
"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"
|
||||
@@ -893,7 +893,7 @@ inline void AddressMessage::SharedCtor(
|
||||
new (&_impl_) Impl_{
|
||||
decltype(_impl_.address_){}
|
||||
, decltype(_impl_.meta_){nullptr}
|
||||
, decltype(_impl_.prefix_){uint64_t{0u}}
|
||||
, decltype(_impl_.prefix_){0u}
|
||||
, /*decltype(_impl_._cached_size_)*/{}
|
||||
};
|
||||
_impl_.address_.InitDefault();
|
||||
@@ -932,7 +932,7 @@ void AddressMessage::Clear() {
|
||||
delete _impl_.meta_;
|
||||
}
|
||||
_impl_.meta_ = nullptr;
|
||||
_impl_.prefix_ = uint64_t{0u};
|
||||
_impl_.prefix_ = 0u;
|
||||
_internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
|
||||
}
|
||||
|
||||
@@ -960,10 +960,10 @@ const char* AddressMessage::_InternalParse(const char* ptr, ::_pbi::ParseContext
|
||||
} else
|
||||
goto handle_unusual;
|
||||
continue;
|
||||
// uint64 prefix = 3;
|
||||
// uint32 prefix = 3;
|
||||
case 3:
|
||||
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);
|
||||
} else
|
||||
goto handle_unusual;
|
||||
@@ -1014,10 +1014,10 @@ uint8_t* AddressMessage::_InternalSerialize(
|
||||
2, this->_internal_address(), target);
|
||||
}
|
||||
|
||||
// uint64 prefix = 3;
|
||||
// uint32 prefix = 3;
|
||||
if (this->_internal_prefix() != 0) {
|
||||
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())) {
|
||||
@@ -1050,9 +1050,9 @@ size_t AddressMessage::ByteSizeLong() const {
|
||||
*_impl_.meta_);
|
||||
}
|
||||
|
||||
// uint64 prefix = 3;
|
||||
// uint32 prefix = 3;
|
||||
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_);
|
||||
|
||||
+12
-12
@@ -716,13 +716,13 @@ class AddressMessage final :
|
||||
::uxcontrol::MetaHeader* meta);
|
||||
::uxcontrol::MetaHeader* unsafe_arena_release_meta();
|
||||
|
||||
// uint64 prefix = 3;
|
||||
// uint32 prefix = 3;
|
||||
void clear_prefix();
|
||||
uint64_t prefix() const;
|
||||
void set_prefix(uint64_t value);
|
||||
uint32_t prefix() const;
|
||||
void set_prefix(uint32_t value);
|
||||
private:
|
||||
uint64_t _internal_prefix() const;
|
||||
void _internal_set_prefix(uint64_t value);
|
||||
uint32_t _internal_prefix() const;
|
||||
void _internal_set_prefix(uint32_t value);
|
||||
public:
|
||||
|
||||
// @@protoc_insertion_point(class_scope:uxcontrol.AddressMessage)
|
||||
@@ -735,7 +735,7 @@ class AddressMessage final :
|
||||
struct Impl_ {
|
||||
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr address_;
|
||||
::uxcontrol::MetaHeader* meta_;
|
||||
uint64_t prefix_;
|
||||
uint32_t prefix_;
|
||||
mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
|
||||
};
|
||||
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)
|
||||
}
|
||||
|
||||
// uint64 prefix = 3;
|
||||
// uint32 prefix = 3;
|
||||
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_;
|
||||
}
|
||||
inline uint64_t AddressMessage::prefix() const {
|
||||
inline uint32_t AddressMessage::prefix() const {
|
||||
// @@protoc_insertion_point(field_get:uxcontrol.AddressMessage.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;
|
||||
}
|
||||
inline void AddressMessage::set_prefix(uint64_t value) {
|
||||
inline void AddressMessage::set_prefix(uint32_t value) {
|
||||
_internal_set_prefix(value);
|
||||
// @@protoc_insertion_point(field_set:uxcontrol.AddressMessage.prefix)
|
||||
}
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ message PacketMessage {
|
||||
message AddressMessage {
|
||||
MetaHeader meta = 1;
|
||||
string address = 2;
|
||||
uint64 prefix = 3;
|
||||
uint32 prefix = 3;
|
||||
}
|
||||
|
||||
message RouteMessage {
|
||||
|
||||
@@ -22,6 +22,7 @@ UxLogger::UxLogger(const std::string ilabel) {
|
||||
UxLogger::UxLogger(void) {
|
||||
label = "global";
|
||||
}
|
||||
|
||||
void UxLogger::Log(const std::string& message) {
|
||||
auto now = std::chrono::system_clock::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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,12 +11,18 @@
|
||||
class UxLogger {
|
||||
private:
|
||||
std::string label;
|
||||
void LogLevel(const std::string level, const std::string& message);
|
||||
public:
|
||||
UxLogger(std::string ilabel);
|
||||
UxLogger();
|
||||
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;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
# foo
|
||||
# foobare
|
||||
localnet == 10.1.1.0/24 #qwert
|
||||
localnet == 10.1.2.0/24 #qwert
|
||||
ddd =
|
||||
+17
-8
@@ -10,7 +10,7 @@ extern "C" {
|
||||
#include <ostream>
|
||||
#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;
|
||||
unsigned char mask[16] = {0};
|
||||
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 hostnum = be64toh(*host_part);
|
||||
hostnum += 2;
|
||||
hostnum += num;
|
||||
*host_part = htobe64(hostnum);
|
||||
|
||||
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;
|
||||
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) + 1;
|
||||
uint32_t fip = (ip & mask) + num;
|
||||
struct in_addr ip_addr;
|
||||
ip_addr.s_addr = htonl(ip);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
int main() {
|
||||
auto net4Res = network4("192.168.1.154", 26);
|
||||
auto net4Res = nethost4("192.168.1.151", 24, 1);
|
||||
if (!net4Res) {
|
||||
std::cerr << net4Res.error() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
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) {
|
||||
std::cerr << net6Res.error() << std::endl;
|
||||
return 1;
|
||||
|
||||
Reference in New Issue
Block a user