From 300588c5e86689b56d66555f8aefa9868d170361 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 17 Sep 2013 14:47:48 -0400 Subject: Add port and control port command line options to daemon and command line client, add new supernode keys to Defaults. --- cli.cpp | 13 +++++++++---- main.cpp | 26 ++++++++++++++++++++++++-- node/Constants.hpp | 4 ++-- node/Defaults.cpp | 10 ++++------ node/Node.cpp | 54 +++++++++++++++++++++++++++-------------------------- node/Node.hpp | 11 +++++++---- node/NodeConfig.cpp | 4 ++-- node/NodeConfig.hpp | 3 ++- 8 files changed, 78 insertions(+), 47 deletions(-) diff --git a/cli.cpp b/cli.cpp index 3121c7d4..66dbd6f3 100644 --- a/cli.cpp +++ b/cli.cpp @@ -45,9 +45,10 @@ static void printHelp(FILE *out,const char *exename) { fprintf(out,"Usage: %s [-switches] "ZT_EOL_S,exename); fprintf(out,ZT_EOL_S); - fprintf(out,"Switches:"ZT_EOL_S); - fprintf(out," -t - Specify token on command line"ZT_EOL_S); - fprintf(out," -T - Read token from file"ZT_EOL_S); + fprintf(out,"Available switches:"ZT_EOL_S); + fprintf(out," -c - Communicate with daemon over this local port"ZT_EOL_S); + fprintf(out," -t - Specify token on command line"ZT_EOL_S); + fprintf(out," -T - Read token from file"ZT_EOL_S); fprintf(out,ZT_EOL_S); fprintf(out,"Use the 'help' command to get help from ZeroTier One itself."ZT_EOL_S); } @@ -73,6 +74,7 @@ int main(int argc,char **argv) std::string authToken; std::string command; bool pastSwitches = false; + unsigned int controlPort = 0; for(int i=1;i - Bind to this port for network I/O"ZT_EOL_S); + fprintf(out," -c - Bind to this port for local control packets"ZT_EOL_S); } #ifdef __UNIX_LIKE__ @@ -114,9 +120,25 @@ int main(int argc,char **argv) #endif const char *homeDir = (const char *)0; + unsigned int port = 0; + unsigned int controlPort = 0; for(int i=1;i 65535) { + printHelp(argv[0],stderr); + return -1; + } + break; + case 'c': + controlPort = Utils::strToUInt(argv[i] + 2); + if (controlPort > 65535) { + printHelp(argv[0],stderr); + return -1; + } + break; case 'h': case '?': default: @@ -142,7 +164,7 @@ int main(int argc,char **argv) int exitCode = 0; - node = new Node(homeDir); + node = new Node(homeDir,port,controlPort); const char *termReason = (char *)0; switch(node->run()) { case Node::NODE_UNRECOVERABLE_ERROR: diff --git a/node/Constants.hpp b/node/Constants.hpp index 8357bb5e..67d404b7 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -131,12 +131,12 @@ error_no_ZT_ARCH_defined; /** * Default local UDP port */ -#define ZT_DEFAULT_UDP_PORT 8993 +#define ZT_DEFAULT_UDP_PORT 9993 /** * Local control port, also used for multiple invocation check */ -#define ZT_CONTROL_UDP_PORT 39393 +#define ZT_DEFAULT_CONTROL_UDP_PORT 39393 /** * Default payload MTU for UDP packets diff --git a/node/Defaults.cpp b/node/Defaults.cpp index d50e1840..733832f3 100644 --- a/node/Defaults.cpp +++ b/node/Defaults.cpp @@ -50,30 +50,28 @@ static inline std::map< Identity,std::vector > _mkSupernodeMap() std::vector addrs; // Nothing special about a supernode... except that they are - // designated as such. + // designated as such and trusted to provide WHOIS lookup. -#if 0 // cthulhu.zerotier.com - New York, New York, USA addrs.clear(); - if (!id.fromString("271ee006a0:1:AgGXs3I+9CWrEmGMxc50x3E+trwtaa2ZMXDU6ezz92fFJXzlhRKGUY/uAToHDdH9XiLxtcA+kUQAZdC4Dy2xtqXxjw==:QgH5Nlx4oWEGVrwhNocqem+3VNd4qzt7RLrmuvqZvKPRS9R70LJYJQLlKZj0ri55Pzg+Mlwy4a4nAgfnRAWA+TW6R0EjSmq72MG585XGNfWBVk3LxMvxlNWErnVNFr2BQS9yzVp4pRjPLdCW4RB3dwEHBUgJ78rwMxQ6IghVCl8CjkDapg==")) + if (!id.fromString("a0fa79d81c:2:0bb348bb38883a29054659a37c204f2c0b082985cb51b36fad31366dfedd616c20aacc5e33ceee2b054670639563238c4fe50bb8716c1ac7996762c0eaefbb23:b7e91f4c77815327c59ff0979f33861e665d002a357448572954c85919be61f768ee6a4d4e42318ffd9cfcc08cadedcd0277a33a950e316a1d7b5bf082919400c44cad1e725fc2035e2d7087d0c8bf51adc5875b643d759a475f899cfbf3e1a4")) throw std::runtime_error("invalid identity in Defaults"); addrs.push_back(InetAddress("198.199.73.93",ZT_DEFAULT_UDP_PORT)); sn[id] = addrs; // nyarlathotep.zerotier.com - San Francisco, California, USA addrs.clear(); - if (!id.fromString("fa9be4008b:1:AwCHXEi/PJuhtOPUZxnBSMiuGvj6XeRMWu9R9aLR3JD1qluADLQzUPSP2+81Dqvgi2wkQ2cqEpOlDPeUCvtlZwdXEA==:QgH4usG/wzsoUCtO2LL3qkwugtoXEz1PUJbmUzY8vbwzc5bckmVPjMqb4q2CF71+QVPV1K6shIV2EKkBMRSS/D/44EGEwC6tjFGZqmmogaC0P1uQeukTAF4qta46YgC4YQx54/Vd/Yfl8n1Bwmgm0gBB4W1ZQir3p+wp37MGlEN0rlXxqA==")) + if (!id.fromString("1521e171ab:2:43bcdc31f2d75667163f3384bc8866e95ce39b4735999e7760494f6480e0fb70f45675f887f8fdfe50e47b082f3fcfc589381f78b3d3bd1dcbf888ccf14d7935:5026836a5732ed890e778f46ded38410dda51c448f82ab76dd0d2c0152bddd5f05fee2fedf8c9f4ccf1f6181f2cdc1f723c59a143a9928c560b2da652f656507f490acfe70e8f5b2a2bba0eca4ea85b03ce00480afd00d49fc756a03bb740592")) throw std::runtime_error("invalid identity in Defaults"); addrs.push_back(InetAddress("198.199.97.220",ZT_DEFAULT_UDP_PORT)); sn[id] = addrs; // shub-niggurath.zerotier.com - Amsterdam, Netherlands addrs.clear(); - if (!id.fromString("48099ecd05:1:AwHO7o1FdDj1nEArfchTDa6EG7Eh2GLdiH86BhcoNv0BHJN4tmrf0Y7/2SZiQFpTTwJf93iph84Dci5+k52u/qkHTQ==:QgGbir8CNxBFFPPj8Eo3Bnp2UmbnZxu/pOq3Ke0WaLBBhHzVuwM+88g7CaDxbZ0AY2VkFc9hmE3VG+xi7g0H86yfVUIBHZnb7N+DCtf8/mphZIHNgmasakRi4hU11kGyLi1nTVTnrmCfAb7w+8SCp64Q5RNvBC/Pvz7pxSwSdjIHkVqRaeo=")) + if (!id.fromString("11c3bddb9a:2:27e1c10a937dde0d6013e7a93755040ff93a98f5bcad809722a6dcde0b255f07da523f9eae818079be0deccbd4572d2e746fe7b8ba8ae6a7a15bdf0456062c37:5f0a7ea9615388a5532c8ce58f9352ba8950c8b3db261d60c02e1ed5a1a42a5e79bc757b38d8a94d00d8e738a6a33cd9b1586022bdff77c9c49ae16609cf5d03f0f60e36a67467c01870ccf26f61793853b93fb6eab53f65f20f623898e9d28d")) throw std::runtime_error("invalid identity in Defaults"); addrs.push_back(InetAddress("198.211.127.172",ZT_DEFAULT_UDP_PORT)); sn[id] = addrs; -#endif return sn; } diff --git a/node/Node.cpp b/node/Node.cpp index c3771df0..3da98223 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -88,6 +88,7 @@ struct _LocalClientImpl UdpSocket *sock; void (*resultHandler)(void *,unsigned long,const char *); void *arg; + unsigned int controlPort; InetAddress localDestAddr; Mutex inUseLock; }; @@ -111,7 +112,7 @@ static void _CBlocalClientHandler(UdpSocket *sock,void *arg,const InetAddress &r } catch ( ... ) {} } -Node::LocalClient::LocalClient(const char *authToken,void (*resultHandler)(void *,unsigned long,const char *),void *arg) +Node::LocalClient::LocalClient(const char *authToken,unsigned int controlPort,void (*resultHandler)(void *,unsigned long,const char *),void *arg) throw() : _impl((void *)0) { @@ -138,8 +139,9 @@ Node::LocalClient::LocalClient(const char *authToken,void (*resultHandler)(void impl->sock = sock; impl->resultHandler = resultHandler; impl->arg = arg; + impl->controlPort = (controlPort) ? controlPort : (unsigned int)ZT_DEFAULT_CONTROL_UDP_PORT; impl->localDestAddr = InetAddress::LO4; - impl->localDestAddr.setPort(ZT_CONTROL_UDP_PORT); + impl->localDestAddr.setPort(impl->controlPort); _impl = impl; } else delete impl; } @@ -183,6 +185,8 @@ unsigned long Node::LocalClient::send(const char *command) struct _NodeImpl { RuntimeEnvironment renv; + unsigned int port; + unsigned int controlPort; std::string reasonForTerminationStr; volatile Node::ReasonForTermination reasonForTermination; volatile bool started; @@ -272,7 +276,7 @@ static void _netconfServiceMessageHandler(void *renv,Service &svc,const Dictiona } #endif // !__WINDOWS__ -Node::Node(const char *hp) +Node::Node(const char *hp,unsigned int port,unsigned int controlPort) throw() : _impl(new _NodeImpl) { @@ -280,6 +284,8 @@ Node::Node(const char *hp) if ((hp)&&(strlen(hp) > 0)) impl->renv.homePath = hp; else impl->renv.homePath = ZT_DEFAULTS.defaultHomePath; + impl->port = (port) ? port : (unsigned int)ZT_DEFAULT_UDP_PORT; + impl->controlPort = (controlPort) ? controlPort : (unsigned int)ZT_DEFAULT_CONTROL_UDP_PORT; impl->reasonForTermination = Node::NODE_RUNNING; impl->started = false; impl->running = false; @@ -327,7 +333,7 @@ Node::ReasonForTermination Node::run() return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"could not write identity.public (home path not writable?)"); } } else { - LOG("no identity found, generating one... this might take a few seconds..."); + LOG("no identity found or identity invalid, generating one... this might take a few seconds..."); _r->identity.generate(); LOG("generated new identity: %s",_r->identity.address().toString().c_str()); idser = _r->identity.toString(true); @@ -365,36 +371,29 @@ Node::ReasonForTermination Node::run() } Utils::lockDownFile(configAuthTokenPath.c_str(),false); - // Create the core objects in RuntimeEnvironment: node config, demarcation - // point, switch, network topology database, and system environment - // watcher. + // Create the objects that make up runtime state. _r->multicaster = new Multicaster(); _r->sw = new Switch(_r); _r->demarc = new Demarc(_r); _r->topology = new Topology(_r,(_r->homePath + ZT_PATH_SEPARATOR_S + "peer.db").c_str()); _r->sysEnv = new SysEnv(_r); try { - _r->nc = new NodeConfig(_r,configAuthToken.c_str()); + _r->nc = new NodeConfig(_r,configAuthToken.c_str(),impl->controlPort); } catch (std::exception &exc) { - // An exception here currently means that another instance of ZeroTier - // One is running. - return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,(std::string("another instance of ZeroTier One appears to be running, or local control UDP port cannot be bound: ") + exc.what()).c_str()); + char foo[1024]; + Utils::snprintf(foo,sizeof(foo),"unable to bind to local control port %u: is another instance of ZeroTier One already running?",impl->controlPort); + return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,foo); } _r->node = this; - // TODO: make configurable - bool boundPort = false; - for(unsigned int p=ZT_DEFAULT_UDP_PORT;p<(ZT_DEFAULT_UDP_PORT + 128);++p) { - if (_r->demarc->bindLocalUdp(p)) { - boundPort = true; - break; - } + // Bind local port for core I/O + if (!_r->demarc->bindLocalUdp(impl->port)) { + char foo[1024]; + Utils::snprintf(foo,sizeof(foo),"unable to bind to global I/O port %u: is another instance of ZeroTier One already running?",impl->controlPort); + return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,foo); } - if (!boundPort) - return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"could not bind any local UDP ports"); - // TODO: bootstrap off network so we don't have to update code for - // changes in supernodes. + // Set initial supernode list _r->topology->setSupernodes(ZT_DEFAULTS.supernodes); } catch (std::bad_alloc &exc) { return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"memory allocation failure"); @@ -404,6 +403,8 @@ Node::ReasonForTermination Node::run() return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"unknown exception during initialization"); } + // Start external service subprocesses, which is only used by special nodes + // right now and isn't available on Windows. #ifndef __WINDOWS__ try { std::string netconfServicePath(_r->homePath + ZT_PATH_SEPARATOR_S + "services.d" + ZT_PATH_SEPARATOR_S + "netconf.service"); @@ -416,6 +417,7 @@ Node::ReasonForTermination Node::run() } #endif + // Core I/O loop try { uint64_t lastNetworkAutoconfCheck = 0; uint64_t lastPingCheck = 0; @@ -614,9 +616,9 @@ const unsigned char EMBEDDED_VERSION_STAMP[20] = { extern "C" { -ZeroTier::Node *zeroTierCreateNode(const char *hp) +ZeroTier::Node *zeroTierCreateNode(const char *hp,unsigned int port,unsigned int controlPort) { - return new ZeroTier::Node(hp); + return new ZeroTier::Node(hp,port,controlPort); } void zeroTierDeleteNode(ZeroTier::Node *n) @@ -624,9 +626,9 @@ void zeroTierDeleteNode(ZeroTier::Node *n) delete n; } -ZeroTier::Node::LocalClient *zeroTierCreateLocalClient(const char *authToken,void (*resultHandler)(void *,unsigned long,const char *),void *arg) +ZeroTier::Node::LocalClient *zeroTierCreateLocalClient(const char *authToken,unsigned int controlPort,void (*resultHandler)(void *,unsigned long,const char *),void *arg) { - return new ZeroTier::Node::LocalClient(authToken,resultHandler,arg); + return new ZeroTier::Node::LocalClient(authToken,controlPort,resultHandler,arg); } void zeroTierDeleteLocalClient(ZeroTier::Node::LocalClient *lc) diff --git a/node/Node.hpp b/node/Node.hpp index 8e9f2777..238b5fce 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -50,9 +50,10 @@ public: * Create a new node config client * * @param authToken Authentication token + * @param controlPort Control port or 0 for 39393 (default) * @param resultHandler Function to call when commands provide results */ - LocalClient(const char *authToken,void (*resultHandler)(void *,unsigned long,const char *),void *arg) + LocalClient(const char *authToken,unsigned int controlPort,void (*resultHandler)(void *,unsigned long,const char *),void *arg) throw(); ~LocalClient(); @@ -95,8 +96,10 @@ public: * The node is not executed until run() is called. * * @param hp Home directory path + * @param port Port to bind for talking to the ZT1 network or 0 for 9993 (default) + * @param controlPort Port to bind locally for control packets or 0 for 39393 (default) */ - Node(const char *hp) + Node(const char *hp,unsigned int port,unsigned int controlPort) throw(); ~Node(); @@ -170,10 +173,10 @@ extern "C" { // Functions with C-style linkage for easy DLL symbol table // lookup. These just create instances of Node and LocalClient. -ZeroTier::Node *zeroTierCreateNode(const char *hp); +ZeroTier::Node *zeroTierCreateNode(const char *hp,unsigned int port,unsigned int controlPort); void zeroTierDeleteNode(ZeroTier::Node *n); -ZeroTier::Node::LocalClient *zeroTierCreateLocalClient(const char *authToken,void (*resultHandler)(void *,unsigned long,const char *),void *arg); +ZeroTier::Node::LocalClient *zeroTierCreateLocalClient(const char *authToken,unsigned int controlPort,void (*resultHandler)(void *,unsigned long,const char *),void *arg); void zeroTierDeleteLocalClient(ZeroTier::Node::LocalClient *lc); } // extern "C" diff --git a/node/NodeConfig.cpp b/node/NodeConfig.cpp index 823e2798..bc1be763 100644 --- a/node/NodeConfig.cpp +++ b/node/NodeConfig.cpp @@ -62,10 +62,10 @@ namespace ZeroTier { -NodeConfig::NodeConfig(const RuntimeEnvironment *renv,const char *authToken) +NodeConfig::NodeConfig(const RuntimeEnvironment *renv,const char *authToken,unsigned int controlPort) throw(std::runtime_error) : _r(renv), - _controlSocket(true,ZT_CONTROL_UDP_PORT,false,&_CBcontrolPacketHandler,this) + _controlSocket(true,controlPort,false,&_CBcontrolPacketHandler,this) { { unsigned int csk[64]; diff --git a/node/NodeConfig.hpp b/node/NodeConfig.hpp index b9858e4f..a2da444f 100644 --- a/node/NodeConfig.hpp +++ b/node/NodeConfig.hpp @@ -59,9 +59,10 @@ public: /** * @param renv Runtime environment * @param authToken Configuration authentication token + * @param controlPort Control port for local control packet I/O * @throws std::runtime_error Unable to bind to local control port */ - NodeConfig(const RuntimeEnvironment *renv,const char *authToken) + NodeConfig(const RuntimeEnvironment *renv,const char *authToken,unsigned int controlPort) throw(std::runtime_error); ~NodeConfig(); -- cgit v1.2.3