diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b983a4bc..82d0207a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,13 +43,20 @@ jobs: # git config --global core.eol lf - name: checkout uses: actions/checkout@v3 - - name: Install Rust + - name: Install Rust aarch64 uses: actions-rs/toolchain@v1 with: toolchain: stable target: aarch64-apple-darwin override: true components: rustfmt, clippy + - name: Install Rust x86_64 + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: x86_64-apple-darwin + override: true + components: rustfmt, clippy - name: Set up cargo cache uses: Swatinem/rust-cache@v2 continue-on-error: false diff --git a/tcp-proxy/Makefile b/tcp-proxy/Makefile index c14ce272..f98a927b 100644 --- a/tcp-proxy/Makefile +++ b/tcp-proxy/Makefile @@ -1,9 +1,15 @@ CXX=$(shell which clang++ g++ c++ 2>/dev/null | head -n 1) -INCLUDES?=-I../ext/prometheus-cpp-lite-1.0/core/include -I../ext/prometheus-cpp-lite-1.0/simpleapi/include +INCLUDES?=-isystem ../ext/prometheus-cpp-lite-1.0/core/include -isystem ../ext/prometheus-cpp-lite-1.0/simpleapi/include -isystem ../ext/ -all: - $(CXX) -O3 -fno-rtti $(INCLUDES) -std=c++11 -pthread -frtti -o tcp-proxy tcp-proxy.cpp ../node/Metrics.cpp +OBJS=Metrics.o \ + ../node/Metrics.o \ + ../osdep/OSUtils.o + +CXXFLAGS=-O3 -fno-rtti $(INCLUDES) -std=c++17 -pthread -frtti + +all: $(OBJS) tcp-proxy.o + $(CXX) -O3 -fno-rtti $(INCLUDES) -std=c++17 -pthread -frtti -o tcp-proxy tcp-proxy.o $(OBJS) clean: - rm -f *.o tcp-proxy *.dSYM + rm -f $(OBJS) tcp-proxy.o tcp-proxy *.dSYM diff --git a/tcp-proxy/Metrics.cpp b/tcp-proxy/Metrics.cpp new file mode 100644 index 00000000..bd4c3470 --- /dev/null +++ b/tcp-proxy/Metrics.cpp @@ -0,0 +1,27 @@ +#include + + +namespace ZeroTier { + namespace Metrics { + // prometheus::simpleapi::gauge_metric_t tcp_connections + // {"tcp_connections", "TCP connections"}; + + // prometheus::simpleapi::counter_metric_t udp_open_failed + // {"udp_open_failed", "UDP open failed"}; + + // prometheus::simpleapi::counter_metric_t tcp_opened + // {"tcp_opened", "TCP opened"}; + // prometheus::simpleapi::counter_metric_t tcp_closed + // {"tcp_closed", "TCP closed"}; + + // prometheus::simpleapi::counter_metric_t tcp_bytes_in + // {"tcp_byes_in", "TCP bytes in"}; + // prometheus::simpleapi::counter_metric_t tcp_bytes_out + // {"tcp_byes_out", "TCP bytes out"}; + + // prometheus::simpleapi::counter_metric_t udp_bytes_in + // {"udp_bytes_in", "UDP bytes in"}; + // prometheus::simpleapi::counter_metric_t udp_bytes_out + // {"udp_bytes_out", "UDP bytes out"}; + } +} \ No newline at end of file diff --git a/tcp-proxy/Metrics.hpp b/tcp-proxy/Metrics.hpp new file mode 100644 index 00000000..024b688a --- /dev/null +++ b/tcp-proxy/Metrics.hpp @@ -0,0 +1,23 @@ +#ifndef _TCP_PROXY_METRICS_H_ +#define _TCP_PROXY_METRICS_H_ + +#include "../node/Metrics.hpp" + +namespace ZeroTier { + namespace Metrics { + // extern prometheus::simpleapi::gauge_metric_t tcp_connections; + + // extern prometheus::simpleapi::counter_metric_t udp_open_failed; + + // extern prometheus::simpleapi::counter_metric_t tcp_opened; + // extern prometheus::simpleapi::counter_metric_t tcp_closed; + + // extern prometheus::simpleapi::counter_metric_t tcp_bytes_in; + // extern prometheus::simpleapi::counter_metric_t tcp_bytes_out; + + // extern prometheus::simpleapi::counter_metric_t udp_bytes_in; + // extern prometheus::simpleapi::counter_metric_t udp_bytes_out; + } +} + +#endif // _TCP_PROXY_METRICS_H_ \ No newline at end of file diff --git a/tcp-proxy/tcp-proxy.cpp b/tcp-proxy/tcp-proxy.cpp index 44bc5eab..2d0e85c0 100644 --- a/tcp-proxy/tcp-proxy.cpp +++ b/tcp-proxy/tcp-proxy.cpp @@ -42,12 +42,15 @@ #include #include "../osdep/Phy.hpp" +#include "../osdep/OSUtils.hpp" -#include "../node/Metrics.hpp" +#include "Metrics.hpp" #define ZT_TCP_PROXY_CONNECTION_TIMEOUT_SECONDS 300 #define ZT_TCP_PROXY_TCP_PORT 443 +#define HOMEDIR "/var/lib/zt-tcp-proxy" + using namespace ZeroTier; /* @@ -127,6 +130,8 @@ struct TcpProxyService if (!*uptr) return; if ((from->sa_family == AF_INET)&&(len >= 16)&&(len < 2048)) { + // Metrics::udp_bytes_in += len; + Client &c = *((Client *)*uptr); c.lastActivity = time((time_t *)0); @@ -171,6 +176,7 @@ struct TcpProxyService Client &c = clients[sockN]; PhySocket *udp = getUnusedUdp((void *)&c); if (!udp) { + // Metrics::udp_open_failed++; phy->close(sockN); clients.erase(sockN); printf("** TCP rejected, no more UDP ports to assign\n"); @@ -184,6 +190,8 @@ struct TcpProxyService c.newVersion = false; *uptrN = (void *)&c; printf("<< TCP from %s -> %.16llx\n",inet_ntoa(reinterpret_cast(from)->sin_addr),(unsigned long long)&c); + // Metrics::tcp_opened++; + // Metrics::tcp_connections++; } void phyOnTcpClose(PhySocket *sock,void **uptr) @@ -194,6 +202,7 @@ struct TcpProxyService phy->close(c.udp); clients.erase(sock); printf("** TCP %.16llx closed\n",(unsigned long long)*uptr); + // Metrics::tcp_closed++; } void phyOnTcpData(PhySocket *sock,void **uptr,void *data,unsigned long len) @@ -201,6 +210,8 @@ struct TcpProxyService Client &c = *((Client *)*uptr); c.lastActivity = time((time_t *)0); + // Metrics::tcp_bytes_in += len; + for(unsigned long i=0;i= sizeof(c.tcpReadBuf)) { phy->close(sock); @@ -246,6 +257,7 @@ struct TcpProxyService if ((ntohs(dest.sin_port) > 1024)&&(payloadLen >= 16)) { phy->udpSend(c.udp,(const struct sockaddr *)&dest,payload,payloadLen); printf(">> TCP %.16llx to %s:%d\n",(unsigned long long)*uptr,inet_ntoa(dest.sin_addr),(int)ntohs(dest.sin_port)); + // Metrics::udp_bytes_out += payloadLen; } } @@ -261,6 +273,7 @@ struct TcpProxyService if (c.tcpWritePtr) { long n = phy->streamSend(sock,c.tcpWriteBuf,c.tcpWritePtr); if (n > 0) { + // Metrics::tcp_bytes_out += n; memmove(c.tcpWriteBuf,c.tcpWriteBuf + n,c.tcpWritePtr -= (unsigned long)n); if (!c.tcpWritePtr) phy->setNotifyWritable(sock,false); @@ -278,8 +291,11 @@ struct TcpProxyService toClose.push_back(c->second.udp); } } - for(std::vector::iterator s(toClose.begin());s!=toClose.end();++s) + for(std::vector::iterator s(toClose.begin());s!=toClose.end();++s) { phy->close(*s); + // Metrics::tcp_closed++; + // Metrics::tcp_connections--; + } } }; @@ -289,16 +305,37 @@ int main(int argc,char **argv) signal(SIGHUP,SIG_IGN); srand(time((time_t *)0)); + // if (!OSUtils::fileExists(HOMEDIR)) { + // if (!OSUtils::mkdir(HOMEDIR)) { + // fprintf(stderr,"%s: fatal error: unable to create %s\n",argv[0],HOMEDIR); + // return 1; + // } + // } + + // prometheus::simpleapi::saver.set_registry(prometheus::simpleapi::registry_ptr); + // prometheus::simpleapi::saver.set_delay(std::chrono::seconds(5)); + // prometheus::simpleapi::saver.set_out_file(HOMEDIR "/metrics.json"); + TcpProxyService svc; Phy phy(&svc,false,true); svc.phy = &phy; svc.udpPortCounter = 1023; + uint16_t listenPort = ZT_TCP_PROXY_TCP_PORT; + if (argc > 1) { + listenPort = (uint16_t)atoi(argv[1]); + } + + if (listenPort == 0) { + fprintf(stderr,"%s: fatal error: invalid port number\n",argv[0]); + return 1; + } + { struct sockaddr_in laddr; memset(&laddr,0,sizeof(laddr)); laddr.sin_family = AF_INET; - laddr.sin_port = htons(ZT_TCP_PROXY_TCP_PORT); + laddr.sin_port = htons(listenPort); if (!phy.tcpListen((const struct sockaddr *)&laddr)) { fprintf(stderr,"%s: fatal error: unable to bind TCP port %d\n",argv[0],ZT_TCP_PROXY_TCP_PORT); return 1;