diff options
author | Joseph Henry <josephjah@gmail.com> | 2017-03-24 17:00:14 -0700 |
---|---|---|
committer | Joseph Henry <josephjah@gmail.com> | 2017-03-24 17:00:14 -0700 |
commit | 683ba79ff0ed4b80c6240fa84d43838027449acd (patch) | |
tree | 6a413fa8ce975bdb5595e9c32a606a4615fad98d | |
parent | 0c69fc719f692141b0c3d41a100de7cb253c2ef7 (diff) | |
download | infinitytier-683ba79ff0ed4b80c6240fa84d43838027449acd.tar.gz infinitytier-683ba79ff0ed4b80c6240fa84d43838027449acd.zip |
Added ButtFlare stub code
-rw-r--r-- | make-mac.mk | 4 | ||||
-rw-r--r-- | objects.mk | 3 | ||||
-rw-r--r-- | service/ButtFlare.cpp | 194 | ||||
-rw-r--r-- | service/ButtFlare.hpp | 94 | ||||
-rw-r--r-- | service/OneService.cpp | 12 |
5 files changed, 306 insertions, 1 deletions
diff --git a/make-mac.mk b/make-mac.mk index 8ff1b772..e84f0746 100644 --- a/make-mac.mk +++ b/make-mac.mk @@ -37,6 +37,10 @@ ifeq ($(ZT_ENABLE_CLUSTER),1) DEFS+=-DZT_ENABLE_CLUSTER endif +ifeq ($(ZT_ENABLE_BUTTFLARE),1) + DEFS+=-DZT_ENABLE_BUTTFLARE +endif + # Build miniupnpc and nat-pmp as included libraries -- extra defs are required for these sources DEFS+=-DMACOSX -DZT_USE_MINIUPNPC -DMINIUPNP_STATICLIB -D_DARWIN_C_SOURCE -DMINIUPNPC_SET_SOCKET_TIMEOUT -DMINIUPNPC_GET_SRC_ADDR -D_BSD_SOURCE -D_DEFAULT_SOURCE -DOS_STRING=\"Darwin/15.0.0\" -DMINIUPNPC_VERSION_STRING=\"2.0\" -DUPNP_VERSION_STRING=\"UPnP/1.1\" -DENABLE_STRNATPMPERR OBJS+=ext/libnatpmp/natpmp.o ext/libnatpmp/getgateway.o ext/miniupnpc/connecthostport.o ext/miniupnpc/igd_desc_parse.o ext/miniupnpc/minisoap.o ext/miniupnpc/minissdpc.o ext/miniupnpc/miniupnpc.o ext/miniupnpc/miniwget.o ext/miniupnpc/minixml.o ext/miniupnpc/portlistingparse.o ext/miniupnpc/receivedata.o ext/miniupnpc/upnpcommands.o ext/miniupnpc/upnpdev.o ext/miniupnpc/upnperrors.o ext/miniupnpc/upnpreplyparse.o osdep/PortMapper.o @@ -31,4 +31,5 @@ OBJS=\ osdep/Http.o \ osdep/OSUtils.o \ service/ClusterGeoIpService.o \ - service/SoftwareUpdater.o + service/SoftwareUpdater.o \ + service/ButtFlare.o diff --git a/service/ButtFlare.cpp b/service/ButtFlare.cpp new file mode 100644 index 00000000..cda92913 --- /dev/null +++ b/service/ButtFlare.cpp @@ -0,0 +1,194 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "../osdep/Thread.hpp" +#include "ButtFlare.hpp" + +namespace ZeroTier { + + typedef void PhySocket; + + ButtFlare::ButtFlare( + void (*handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int), void *arg) + : + _handler(handler), + _phy(this,false,true), + _enabled(true), + _run(true) + { + // HTTP listen socket + struct sockaddr_in in4; + memset(&in4,0,sizeof(in4)); + in4.sin_family = AF_INET; + in4.sin_addr.s_addr = Utils::hton((uint32_t)(0x7f000001)); // right now we just listen for TCP @127.0.0.1 + in4.sin_port = Utils::hton((uint16_t)http_listen_port); + _tcpHttpListenSocket = _phy.tcpListen((const struct sockaddr *)&in4,this); + // SSL listen socket + in4.sin_port = Utils::hton((uint16_t)ssl_listen_port); + _tcpSSLListenSocket = _phy.tcpListen((const struct sockaddr *)&in4,this); + + /* + struct sockaddr_in6 in6; + memset((void *)&in6,0,sizeof(in6)); + in6.sin6_family = AF_INET6; + in6.sin6_port = in4.sin_port; + if (_allowManagementFrom.size() == 0) + in6.sin6_addr.s6_addr[15] = 1; // IPv6 localhost == ::1 + _v6TcpControlSocket = _phy.tcpListen((const struct sockaddr *)&in6,this); + + // We must bind one of IPv4 or IPv6 -- support either failing to support hosts that + // have only IPv4 or only IPv6 stacks. + if ((_v4TcpControlSocket)||(_v6TcpControlSocket)) { + _ports[0] = _primaryPort; + break; + } else { + if (_v4TcpControlSocket) + _phy.close(_v4TcpControlSocket,false); + if (_v6TcpControlSocket) + _phy.close(_v6TcpControlSocket,false); + _primaryPort = 0; + } + */ + + if(!_tcpHttpListenSocket) + printf("Error binding on port %d for HTTP listen socket\n", http_listen_port); + if(!_tcpSSLListenSocket) + printf("Error binding on port %d for SSL listen socket\n", ssl_listen_port); + _thread = Thread::start(this); + } + + ButtFlare::~ButtFlare() + { + _run = false; + _phy.whack(); + _phy.whack(); // TODO: Rationale? + Thread::join(_thread); + _phy.close(_tcpHttpListenSocket,false); + _phy.close(_tcpSSLListenSocket,false); + } + void ButtFlare::threadMain() + throw() + { + while(_run) { + _phy.poll(50); // in ms + } + } + + void ButtFlare::phyOnTcpData(PhySocket *sock,void **uptr,void *data,unsigned long len) + { + TcpConnection *conn = cmap[sock]; + unsigned char *buf = (unsigned char*)data; + std::string host = ""; + + for(int i=0; i<len; i++) { printf("buf[%d] = %d, (char) = %c\n", i, buf[i], (char*)buf[i]); } + printf("phyOnTcpData(len=%lu)\n", len); + + if(conn == NULL) { + printf("No existing connection for this socket\n"); + return; + } + if(!conn->destination_sock) { // no connection yet + + // Determine if HTTP or TLS/SSL + if(buf[0] == 22 && len > 100) // naive and incomplete way of checking for TLS, just for stub code + { + printf("TLS/SSL\n"); + host = "127.0.0.1"; + } + else + { + printf("HTTP\n"); + host = "127.0.0.1"; + } + + if(host != "") + { + bool connected; + struct sockaddr_in in4; + memset(&in4,0,sizeof(in4)); + in4.sin_family = AF_INET; + in4.sin_addr.s_addr = Utils::hton((uint32_t)(0x7f000001)); // right now we just listen for TCP @127.0.0.1 + in4.sin_port = Utils::hton((uint16_t)http_listen_port); + conn->destination_sock = _phy.tcpConnect((const struct sockaddr *)&in4, connected, this); + + if(!connected) { + printf("instant connect has occured\n"); + } + if(!conn->destination_sock) { + printf("there was an error connecting to the remote host\n"); + } + } + } + else // connection already established, just forward the data + { + int n = _phy.streamSend(conn->destination_sock, buf, len); + printf("wrote %d bytes (%p -> %p)\n", conn->origin_sock, conn->destination_sock); + } + } + + void ButtFlare::phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *localAddr,const struct sockaddr *from,void *data,unsigned long len) + { + } + void ButtFlare::phyOnTcpWritable(PhySocket *sock,void **uptr) + { + } + void ButtFlare::phyOnFileDescriptorActivity(PhySocket *sock,void **uptr,bool readable,bool writable) + { + } + + void ButtFlare::phyOnTcpConnect(PhySocket *sock,void **uptr,bool success) + { + printf("phyOnTcpConnect()\n"); + } + + void ButtFlare::phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from) + { + TcpConnection *conn = new TcpConnection(); + conn->origin_sock = sockN; + cmap[sockN]=conn; // add new connection + } + + void ButtFlare::phyOnUnixClose(PhySocket *sock,void **uptr) + { + } + void ButtFlare::phyOnUnixData(PhySocket *sock,void **uptr,void *data,ssize_t len) + { + } + void ButtFlare::phyOnUnixWritable(PhySocket *sock,void **uptr,bool lwip_invoked) + { + } + + + void ButtFlare::phyOnTcpClose(PhySocket *sock,void **uptr) + { + TcpConnection *conn = cmap[sock]; + if(conn == NULL) { + printf("No existing connection for this sock. Only closing origin sock\n"); + // _phy.close(sock); + return; + } + else + { + // Close both ends + // _phy.close(conn->destination_sock); + // _phy.close(conn->origin_sock); + } + } +} + +//#endif
\ No newline at end of file diff --git a/service/ButtFlare.hpp b/service/ButtFlare.hpp new file mode 100644 index 00000000..6e8f0955 --- /dev/null +++ b/service/ButtFlare.hpp @@ -0,0 +1,94 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ZT_BUTTFLARE_HPP +#define ZT_BUTTFLARE_HPP + +#include "../node/InetAddress.hpp" +#include "../osdep/Phy.hpp" + +namespace ZeroTier { + + typedef void PhySocket; + class ButtFlare; + + struct TcpConnection + { + enum { + TCP_HTTP_INCOMING, + TCP_HTTP_OUTGOING, + TCP_TUNNEL_OUTGOING + } type; + + InetAddress from; + InetAddress realhost; + + PhySocket *origin_sock; + PhySocket *destination_sock; + }; + + class ButtFlare + { + friend class Phy<ButtFlare *>; + + public: + ButtFlare( + void (*handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int), + void *arg); + + ~ButtFlare(); + + // Send incoming data to intended host + void phyOnTcpData(PhySocket *sock,void **uptr,void *data,unsigned long len); + + void phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *localAddr,const struct sockaddr *from,void *data,unsigned long len); + void phyOnTcpWritable(PhySocket *sock,void **uptr); + void phyOnFileDescriptorActivity(PhySocket *sock,void **uptr,bool readable,bool writable); + + // Establish outgoing connection to intended host + void phyOnTcpConnect(PhySocket *sock,void **uptr,bool success); + // Accept connection + void phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from); + // Handle the closure of a Unix Domain socket + void phyOnUnixClose(PhySocket *sock,void **uptr); + void phyOnUnixData(PhySocket *sock,void **uptr,void *data,ssize_t len); + void phyOnUnixWritable(PhySocket *sock,void **uptr,bool lwip_invoked); + + // Handle the closure of a TCP connection + void phyOnTcpClose(PhySocket *sock,void **uptr); + + void threadMain() + throw(); + + void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int); + + private: + int http_listen_port = 80; + int ssl_listen_port = 8899; + + volatile bool _enabled; + volatile bool _run; + + Thread _thread; + Phy<ButtFlare*> _phy; + PhySocket *_tcpHttpListenSocket, *_tcpSSLListenSocket; + std::map<PhySocket*, TcpConnection*> cmap; + }; +} + +#endif
\ No newline at end of file diff --git a/service/OneService.cpp b/service/OneService.cpp index 1c2fa05d..14f637b4 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -67,6 +67,10 @@ #include <ifaddrs.h> #endif +#ifdef ZT_ENABLE_BUTTFLARE +#include "ButtFlare.hpp" +#endif + #ifdef ZT_USE_SYSTEM_HTTP_PARSER #include <http_parser.h> #else @@ -474,6 +478,10 @@ public: unsigned int _clusterMemberId; #endif +#ifdef ZT_ENABLE_BUTTFLARE + ButtFlare *butt; +#endif + // Set to false to force service to stop volatile bool _run; Mutex _run_m; @@ -1914,6 +1922,10 @@ public: try { char friendlyName[128]; Utils::snprintf(friendlyName,sizeof(friendlyName),"ZeroTier One [%.16llx]",nwid); + +#ifdef ZT_ENABLE_BUTTFLARE + butt = new ButtFlare(StapFrameHandler, (void *)this); +#endif n.tap = new EthernetTap( _homePath.c_str(), MAC(nwc->mac), |