From 76c797b489efc686887476986892192da254276d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9E=D0=BB=D0=B5=D0=B3=20=D0=91=D0=BE=D1=80=D0=BE=D0=B4?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Wed, 22 Apr 2026 18:15:05 +0200 Subject: [PATCH] working commit --- Makefile | 49 ++++++++++++++--------------- Makefile.am | 19 ++++++------ Makefile.in | 49 ++++++++++++++--------------- interface.cpp | 15 ++++++++- interface.hpp | 2 ++ iprouter.cpp | 11 +++++++ iprouter.hpp | 18 +++++++++++ server.cpp | 39 ------------------------ server_test.cpp | 25 --------------- tunclient.cpp | 61 +++++++++++++++++++++++++++++++++++++ server.hpp => tunclient.hpp | 3 +- tunclient_test.cpp | 31 +++++++++++++++++++ udpclient_test.cpp | 20 +++++------- 13 files changed, 207 insertions(+), 135 deletions(-) create mode 100644 iprouter.cpp create mode 100644 iprouter.hpp delete mode 100644 server.cpp delete mode 100644 server_test.cpp create mode 100644 tunclient.cpp rename server.hpp => tunclient.hpp (80%) create mode 100644 tunclient_test.cpp diff --git a/Makefile b/Makefile index cbbd47f..3fa7554 100644 --- a/Makefile +++ b/Makefile @@ -90,7 +90,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : sbin_PROGRAMS = helmetd$(EXEEXT) noinst_PROGRAMS = udpclient_test$(EXEEXT) service_test$(EXEEXT) \ - server_test$(EXEEXT) + tunclient_test$(EXEEXT) subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac @@ -106,19 +106,19 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" PROGRAMS = $(noinst_PROGRAMS) $(sbin_PROGRAMS) -am_helmetd_OBJECTS = helmetd.$(OBJEXT) server.$(OBJEXT) \ +am_helmetd_OBJECTS = helmetd.$(OBJEXT) tunclient.$(OBJEXT) \ service.$(OBJEXT) interface.$(OBJEXT) hello.pb.$(OBJEXT) \ - udpclient.$(OBJEXT) resolver.$(OBJEXT) + udpclient.$(OBJEXT) resolver.$(OBJEXT) iprouter.$(OBJEXT) helmetd_OBJECTS = $(am_helmetd_OBJECTS) helmetd_LDADD = $(LDADD) -am_server_test_OBJECTS = server_test.$(OBJEXT) server.$(OBJEXT) \ - service.$(OBJEXT) interface.$(OBJEXT) -server_test_OBJECTS = $(am_server_test_OBJECTS) -server_test_LDADD = $(LDADD) -am_service_test_OBJECTS = service_test.$(OBJEXT) server.$(OBJEXT) \ +am_service_test_OBJECTS = service_test.$(OBJEXT) tunclient.$(OBJEXT) \ service.$(OBJEXT) interface.$(OBJEXT) service_test_OBJECTS = $(am_service_test_OBJECTS) service_test_LDADD = $(LDADD) +am_tunclient_test_OBJECTS = tunclient_test.$(OBJEXT) \ + tunclient.$(OBJEXT) service.$(OBJEXT) interface.$(OBJEXT) +tunclient_test_OBJECTS = $(am_tunclient_test_OBJECTS) +tunclient_test_LDADD = $(LDADD) am_udpclient_test_OBJECTS = resolver.$(OBJEXT) udpclient.$(OBJEXT) \ udpclient_test.$(OBJEXT) udpclient_test_OBJECTS = $(am_udpclient_test_OBJECTS) @@ -163,10 +163,10 @@ AM_V_CCLD = $(am__v_CCLD_$(V)) am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(helmetd_SOURCES) $(server_test_SOURCES) \ - $(service_test_SOURCES) $(udpclient_test_SOURCES) -DIST_SOURCES = $(helmetd_SOURCES) $(server_test_SOURCES) \ - $(service_test_SOURCES) $(udpclient_test_SOURCES) +SOURCES = $(helmetd_SOURCES) $(service_test_SOURCES) \ + $(tunclient_test_SOURCES) $(udpclient_test_SOURCES) +DIST_SOURCES = $(helmetd_SOURCES) $(service_test_SOURCES) \ + $(tunclient_test_SOURCES) $(udpclient_test_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -244,7 +244,7 @@ INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s -LDFLAGS = -pthread +LDFLAGS = -pthread LIBOBJS = LIBS = -Wl,--as-need -lprotobuf-lite LTLIBOBJS = @@ -313,20 +313,21 @@ top_builddir = . top_srcdir = . AUTOMAKE_OPTIONS = foreign no-dependencies no-installinfo subdir-objects helmetd_SOURCES = helmetd.cpp \ - server.cpp server.hpp \ + tunclient.cpp tunclient.hpp \ service.cpp service.hpp \ interface.cpp interface.hpp \ hello.pb.cc hello.pb.h \ udpclient.cpp udpclient.hpp \ - resolver.cpp resolver.hpp + resolver.cpp resolver.hpp \ + iprouter.cpp iprouter.hpp -server_test_SOURCES = server_test.cpp \ - server.cpp server.hpp \ +tunclient_test_SOURCES = tunclient_test.cpp \ + tunclient.cpp tunclient.hpp \ service.cpp service.hpp \ interface.cpp interface.hpp service_test_SOURCES = service_test.cpp \ - server.cpp server.hpp \ + tunclient.cpp tunclient.hpp \ service.cpp service.hpp \ interface.cpp interface.hpp @@ -439,14 +440,14 @@ helmetd$(EXEEXT): $(helmetd_OBJECTS) $(helmetd_DEPENDENCIES) $(EXTRA_helmetd_DEP @rm -f helmetd$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(helmetd_OBJECTS) $(helmetd_LDADD) $(LIBS) -server_test$(EXEEXT): $(server_test_OBJECTS) $(server_test_DEPENDENCIES) $(EXTRA_server_test_DEPENDENCIES) - @rm -f server_test$(EXEEXT) - $(AM_V_CXXLD)$(CXXLINK) $(server_test_OBJECTS) $(server_test_LDADD) $(LIBS) - service_test$(EXEEXT): $(service_test_OBJECTS) $(service_test_DEPENDENCIES) $(EXTRA_service_test_DEPENDENCIES) @rm -f service_test$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(service_test_OBJECTS) $(service_test_LDADD) $(LIBS) +tunclient_test$(EXEEXT): $(tunclient_test_OBJECTS) $(tunclient_test_DEPENDENCIES) $(EXTRA_tunclient_test_DEPENDENCIES) + @rm -f tunclient_test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(tunclient_test_OBJECTS) $(tunclient_test_LDADD) $(LIBS) + udpclient_test$(EXEEXT): $(udpclient_test_OBJECTS) $(udpclient_test_DEPENDENCIES) $(EXTRA_udpclient_test_DEPENDENCIES) @rm -f udpclient_test$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(udpclient_test_OBJECTS) $(udpclient_test_LDADD) $(LIBS) @@ -829,8 +830,8 @@ uninstall-am: uninstall-sbinPROGRAMS .PRECIOUS: Makefile -test: udpclient_test - ./udpclient_test +test: tunclient_test + ./tunclient_test run: helmetd ./helmetd diff --git a/Makefile.am b/Makefile.am index f7b8976..3681409 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,31 +2,32 @@ AUTOMAKE_OPTIONS = foreign no-dependencies no-installinfo subdir-objects CXXFLAGS = -std=c++23 -Wall -I. -pthread -D_GNU_SOURCE=1 -LDFLAGS = -pthread +LDFLAGS = -pthread LIBS = -Wl,--as-need -lprotobuf-lite sbin_PROGRAMS = helmetd helmetd_SOURCES = helmetd.cpp \ - server.cpp server.hpp \ + tunclient.cpp tunclient.hpp \ service.cpp service.hpp \ interface.cpp interface.hpp \ hello.pb.cc hello.pb.h \ udpclient.cpp udpclient.hpp \ - resolver.cpp resolver.hpp + resolver.cpp resolver.hpp \ + iprouter.cpp iprouter.hpp noinst_PROGRAMS = \ udpclient_test \ service_test \ - server_test + tunclient_test -server_test_SOURCES = server_test.cpp \ - server.cpp server.hpp \ +tunclient_test_SOURCES = tunclient_test.cpp \ + tunclient.cpp tunclient.hpp \ service.cpp service.hpp \ interface.cpp interface.hpp service_test_SOURCES = service_test.cpp \ - server.cpp server.hpp \ + tunclient.cpp tunclient.hpp \ service.cpp service.hpp \ interface.cpp interface.hpp @@ -36,8 +37,8 @@ udpclient_test_SOURCES = \ udpclient.cpp udpclient.hpp \ udpclient_test.cpp -test: udpclient_test - ./udpclient_test +test: tunclient_test + ./tunclient_test run: helmetd ./helmetd diff --git a/Makefile.in b/Makefile.in index 5cb0135..e937df3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -90,7 +90,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : sbin_PROGRAMS = helmetd$(EXEEXT) noinst_PROGRAMS = udpclient_test$(EXEEXT) service_test$(EXEEXT) \ - server_test$(EXEEXT) + tunclient_test$(EXEEXT) subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac @@ -106,19 +106,19 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" PROGRAMS = $(noinst_PROGRAMS) $(sbin_PROGRAMS) -am_helmetd_OBJECTS = helmetd.$(OBJEXT) server.$(OBJEXT) \ +am_helmetd_OBJECTS = helmetd.$(OBJEXT) tunclient.$(OBJEXT) \ service.$(OBJEXT) interface.$(OBJEXT) hello.pb.$(OBJEXT) \ - udpclient.$(OBJEXT) resolver.$(OBJEXT) + udpclient.$(OBJEXT) resolver.$(OBJEXT) iprouter.$(OBJEXT) helmetd_OBJECTS = $(am_helmetd_OBJECTS) helmetd_LDADD = $(LDADD) -am_server_test_OBJECTS = server_test.$(OBJEXT) server.$(OBJEXT) \ - service.$(OBJEXT) interface.$(OBJEXT) -server_test_OBJECTS = $(am_server_test_OBJECTS) -server_test_LDADD = $(LDADD) -am_service_test_OBJECTS = service_test.$(OBJEXT) server.$(OBJEXT) \ +am_service_test_OBJECTS = service_test.$(OBJEXT) tunclient.$(OBJEXT) \ service.$(OBJEXT) interface.$(OBJEXT) service_test_OBJECTS = $(am_service_test_OBJECTS) service_test_LDADD = $(LDADD) +am_tunclient_test_OBJECTS = tunclient_test.$(OBJEXT) \ + tunclient.$(OBJEXT) service.$(OBJEXT) interface.$(OBJEXT) +tunclient_test_OBJECTS = $(am_tunclient_test_OBJECTS) +tunclient_test_LDADD = $(LDADD) am_udpclient_test_OBJECTS = resolver.$(OBJEXT) udpclient.$(OBJEXT) \ udpclient_test.$(OBJEXT) udpclient_test_OBJECTS = $(am_udpclient_test_OBJECTS) @@ -163,10 +163,10 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(helmetd_SOURCES) $(server_test_SOURCES) \ - $(service_test_SOURCES) $(udpclient_test_SOURCES) -DIST_SOURCES = $(helmetd_SOURCES) $(server_test_SOURCES) \ - $(service_test_SOURCES) $(udpclient_test_SOURCES) +SOURCES = $(helmetd_SOURCES) $(service_test_SOURCES) \ + $(tunclient_test_SOURCES) $(udpclient_test_SOURCES) +DIST_SOURCES = $(helmetd_SOURCES) $(service_test_SOURCES) \ + $(tunclient_test_SOURCES) $(udpclient_test_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -244,7 +244,7 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = -pthread +LDFLAGS = -pthread LIBOBJS = @LIBOBJS@ LIBS = -Wl,--as-need -lprotobuf-lite LTLIBOBJS = @LTLIBOBJS@ @@ -313,20 +313,21 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign no-dependencies no-installinfo subdir-objects helmetd_SOURCES = helmetd.cpp \ - server.cpp server.hpp \ + tunclient.cpp tunclient.hpp \ service.cpp service.hpp \ interface.cpp interface.hpp \ hello.pb.cc hello.pb.h \ udpclient.cpp udpclient.hpp \ - resolver.cpp resolver.hpp + resolver.cpp resolver.hpp \ + iprouter.cpp iprouter.hpp -server_test_SOURCES = server_test.cpp \ - server.cpp server.hpp \ +tunclient_test_SOURCES = tunclient_test.cpp \ + tunclient.cpp tunclient.hpp \ service.cpp service.hpp \ interface.cpp interface.hpp service_test_SOURCES = service_test.cpp \ - server.cpp server.hpp \ + tunclient.cpp tunclient.hpp \ service.cpp service.hpp \ interface.cpp interface.hpp @@ -439,14 +440,14 @@ helmetd$(EXEEXT): $(helmetd_OBJECTS) $(helmetd_DEPENDENCIES) $(EXTRA_helmetd_DEP @rm -f helmetd$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(helmetd_OBJECTS) $(helmetd_LDADD) $(LIBS) -server_test$(EXEEXT): $(server_test_OBJECTS) $(server_test_DEPENDENCIES) $(EXTRA_server_test_DEPENDENCIES) - @rm -f server_test$(EXEEXT) - $(AM_V_CXXLD)$(CXXLINK) $(server_test_OBJECTS) $(server_test_LDADD) $(LIBS) - service_test$(EXEEXT): $(service_test_OBJECTS) $(service_test_DEPENDENCIES) $(EXTRA_service_test_DEPENDENCIES) @rm -f service_test$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(service_test_OBJECTS) $(service_test_LDADD) $(LIBS) +tunclient_test$(EXEEXT): $(tunclient_test_OBJECTS) $(tunclient_test_DEPENDENCIES) $(EXTRA_tunclient_test_DEPENDENCIES) + @rm -f tunclient_test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(tunclient_test_OBJECTS) $(tunclient_test_LDADD) $(LIBS) + udpclient_test$(EXEEXT): $(udpclient_test_OBJECTS) $(udpclient_test_DEPENDENCIES) $(EXTRA_udpclient_test_DEPENDENCIES) @rm -f udpclient_test$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(udpclient_test_OBJECTS) $(udpclient_test_LDADD) $(LIBS) @@ -829,8 +830,8 @@ uninstall-am: uninstall-sbinPROGRAMS .PRECIOUS: Makefile -test: udpclient_test - ./udpclient_test +test: tunclient_test + ./tunclient_test run: helmetd ./helmetd diff --git a/interface.cpp b/interface.cpp index 0c99a49..2431bd8 100644 --- a/interface.cpp +++ b/interface.cpp @@ -270,6 +270,19 @@ std::expected Interface::Down(void) { return {}; } +std::expected Interface::Read() { + char buffer[mtu]; + int rsize = 0; + if ((rsize = read(tunfd, buffer, sizeof(buffer))) < 0) { + int errnocopy = errno; + std::string error = std::strerror(errnocopy); + return std::unexpected("Read interface error: " + error); + } + std::string rdata; + rdata.append(buffer, rsize); + return rdata; +} + std::string Interface::Name() { return ifname; } @@ -282,6 +295,7 @@ Interface::~Interface() { close(tunfd); } + std::expected Interface::UpN(void) { int netlinkfd = 0; if ((netlinkfd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE)) < 0) { @@ -313,7 +327,6 @@ std::expected Interface::UpN(void) { return {}; } - std::expected Interface::SetIP4AddrMask(const std::string address, const int prefix) { int netlinkfd = 0; if ((netlinkfd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE)) < 0) { diff --git a/interface.hpp b/interface.hpp index e405d8a..2c0c38f 100644 --- a/interface.hpp +++ b/interface.hpp @@ -22,6 +22,8 @@ public: std::expected UpN(void); std::expected SetIP4AddrMask(const std::string address, const int prefix); + std::expected Read(); + ~Interface(); }; diff --git a/iprouter.cpp b/iprouter.cpp new file mode 100644 index 0000000..256bdbe --- /dev/null +++ b/iprouter.cpp @@ -0,0 +1,11 @@ + + +#include +#include + +#include + +std::expected Router::List() { + std::vector routes; + return routes; +} diff --git a/iprouter.hpp b/iprouter.hpp new file mode 100644 index 0000000..775c4bd --- /dev/null +++ b/iprouter.hpp @@ -0,0 +1,18 @@ + + +#include +#include +#include + +class Route { +public: + std::string dest; + int mask; +}; + +using Routes = std::vector; + +class Router { + std::expected List(); +}; + diff --git a/server.cpp b/server.cpp deleted file mode 100644 index 21ad508..0000000 --- a/server.cpp +++ /dev/null @@ -1,39 +0,0 @@ - -extern "C" { -#include -} - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -std::expected Server::Create(const std::string name, const std::string addr, const int prefix) { - auto createres = iface.Create(name); - if (!createres) { - return std::unexpected(createres.error()); - } - auto setaddrres = iface.SetIP4Address(addr); - if (!setaddrres) { - return std::unexpected(setaddrres.error()); - } - auto setprefixres = iface.SetIP4Netmask(24); - if (!setprefixres) { - return std::unexpected(setprefixres.error()); - } - auto setmtures = iface.SetMTU(1240); - if (!setmtures) { - return std::unexpected(setmtures.error()); - } - return {}; -} - diff --git a/server_test.cpp b/server_test.cpp deleted file mode 100644 index 9f0dc91..0000000 --- a/server_test.cpp +++ /dev/null @@ -1,25 +0,0 @@ - -#include -#include -#include -#include -#include -#include - - -#include - -using namespace std::chrono_literals; - - -int main(int argc, char** argv) { - Server srv; - auto createres = srv.Create("tun10", "10.1.2.1", 30); - if (!createres) { - std::cerr << "Error: " << createres.error() << std::endl; - return 1; - } - std::chrono::milliseconds timesleep(20s); - std::this_thread::sleep_for(timesleep); - return 0; -} diff --git a/tunclient.cpp b/tunclient.cpp new file mode 100644 index 0000000..23e530e --- /dev/null +++ b/tunclient.cpp @@ -0,0 +1,61 @@ + +extern "C" { +#include +#include +} + +#include +#include +#include +#include + + +#include +#include + + +std::expected TClient::Create(const std::string name, const std::string addr, const int prefix) { + auto createRes = iface.Create(name); + if (!createRes) { + return std::unexpected(createRes.error()); + } + auto setaddrRes = iface.SetIP4Address(addr); + if (!setaddrRes) { + return std::unexpected(setaddrRes.error()); + } + auto setprefixRes = iface.SetIP4Netmask(24); + if (!setprefixRes) { + return std::unexpected(setprefixRes.error()); + } + auto setmtuRes = iface.SetMTU(1240); + if (!setmtuRes) { + return std::unexpected(setmtuRes.error()); + } + auto upRes = iface.Up(); + if (!upRes) { + return std::unexpected(upRes.error()); + } + return {}; +} + +std::expected TClient::Run() { + while (true) { + auto readRes = iface.Read(); + if (!readRes) { + std::cerr << std::format("Error: {}\n", readRes.error()); + } + auto value = readRes.value(); + std::cerr << std::format("Packet size: {}\n", value.size()); + struct iphdr* iphdr = (struct iphdr*)(value.data()); + + struct in_addr src, dest; + src.s_addr = iphdr->saddr; + dest.s_addr = iphdr->daddr; + + std::cout << "Source IP: " << inet_ntoa(src) << std::endl; + std::cout << "Dest IP: " << inet_ntoa(dest) << std::endl; + std::cout << "Protocol: " << (int)iphdr->protocol << std::endl; + + } + return {}; +} diff --git a/server.hpp b/tunclient.hpp similarity index 80% rename from server.hpp rename to tunclient.hpp index f5583fd..a510f1d 100644 --- a/server.hpp +++ b/tunclient.hpp @@ -7,9 +7,10 @@ #include #include -class Server { +class TClient { private: Interface iface; public: std::expected Create(const std::string name, const std::string addr, const int prefix); + std::expected Run(); }; diff --git a/tunclient_test.cpp b/tunclient_test.cpp new file mode 100644 index 0000000..96d38e9 --- /dev/null +++ b/tunclient_test.cpp @@ -0,0 +1,31 @@ + +#include +#include +#include +#include +#include +#include + + +#include + +using namespace std::chrono_literals; + + +int main(int argc, char** argv) { + TClient cli; + auto createRes = cli.Create("tun10", "10.1.2.1", 30); + if (!createRes) { + std::cerr << "Error: " << createRes.error() << std::endl; + return 1; + } + + auto runRes = cli.Run(); + if (!runRes) { + std::cerr << "Error: " << runRes.error() << std::endl; + return 1; + } + //std::chrono::milliseconds timesleep(20s); + //std::this_thread::sleep_for(timesleep); + return 0; +} diff --git a/udpclient_test.cpp b/udpclient_test.cpp index edc6a63..e26420b 100644 --- a/udpclient_test.cpp +++ b/udpclient_test.cpp @@ -8,19 +8,15 @@ int main(int argc, char** argv) { UDPClient cli; std::string message("Hello"); - { - auto res = cli.Bind("www.gnu.org", 1025); - if (!res) { - std::cerr << std::format("Error: {}", res.error()) << std::endl; - return 1; - } + auto bindRes = cli.Bind("www.gnu.org", 1025); + if (!bindRes) { + std::cerr << std::format("Error: {}", bindRes.error()) << std::endl; + return 1; } - { - auto res = cli.Send(message); - if (!res) { - std::cerr << std::format("Error: {}", res.error()) << std::endl; - return 1; - } + auto sendRes = cli.Send(message); + if (!sendRes) { + std::cerr << std::format("Error: {}", sendRes.error()) << std::endl; + return 1; } return 0; }