Ver Fonte

Add port and control port command line options to daemon and command line client, add new supernode keys to Defaults.

Adam Ierymenko há 12 anos atrás
pai
commit
300588c5e8
8 ficheiros alterados com 78 adições e 47 exclusões
  1. 9 4
      cli.cpp
  2. 24 2
      main.cpp
  3. 2 2
      node/Constants.hpp
  4. 4 6
      node/Defaults.cpp
  5. 28 26
      node/Node.cpp
  6. 7 4
      node/Node.hpp
  7. 2 2
      node/NodeConfig.cpp
  8. 2 1
      node/NodeConfig.hpp

+ 9 - 4
cli.cpp

@@ -45,9 +45,10 @@ static void printHelp(FILE *out,const char *exename)
 {
 	fprintf(out,"Usage: %s [-switches] <command>"ZT_EOL_S,exename);
 	fprintf(out,ZT_EOL_S);
-	fprintf(out,"Switches:"ZT_EOL_S);
-	fprintf(out,"  -t<token>        - Specify token on command line"ZT_EOL_S);
-	fprintf(out,"  -T<file>         - Read token from file"ZT_EOL_S);
+	fprintf(out,"Available switches:"ZT_EOL_S);
+	fprintf(out," -c<port>         - Communicate with daemon over this local port"ZT_EOL_S);
+	fprintf(out," -t<token>        - Specify token on command line"ZT_EOL_S);
+	fprintf(out," -T<file>         - 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<argc;++i) {
 		if ((argv[i][0] == '-')&&(!pastSwitches)) {
 			if (strlen(argv[i]) <= 1) {
@@ -80,6 +82,9 @@ int main(int argc,char **argv)
 				return -1;
 			}
 			switch(argv[i][1]) {
+				case 'c':
+					controlPort = Utils::strToUInt(argv[i] + 2);
+					break;
 				case 't':
 					authToken.assign(argv[i] + 2);
 					break;
@@ -129,7 +134,7 @@ int main(int argc,char **argv)
 		return -2;
 	}
 
-	Node::LocalClient client(authToken.c_str(),&resultHandler,(void *)0);
+	Node::LocalClient client(authToken.c_str(),controlPort,&resultHandler,(void *)0);
 	client.send(command.c_str());
 
 	doneCondition.wait(1000);

+ 24 - 2
main.cpp

@@ -60,7 +60,13 @@ static Node *node = (Node *)0;
 
 static void printHelp(const char *cn,FILE *out)
 {
-	fprintf(out,"ZeroTier One version %d.%d.%d"ZT_EOL_S"(c)2012-2013 ZeroTier Networks LLC"ZT_EOL_S"Licensed under the GNU General Public License v3"ZT_EOL_S""ZT_EOL_S"Usage: %s [home directory]"ZT_EOL_S,Node::versionMajor(),Node::versionMinor(),Node::versionRevision(),cn);
+	fprintf(out,"ZeroTier One version %d.%d.%d"ZT_EOL_S"(c)2012-2013 ZeroTier Networks LLC"ZT_EOL_S,Node::versionMajor(),Node::versionMinor(),Node::versionRevision());
+	fprintf(out,"Licensed under the GNU General Public License v3"ZT_EOL_S""ZT_EOL_S);
+	fprintf(out,"Usage: %s [-switches] [home directory]"ZT_EOL_S""ZT_EOL_S,cn);
+	fprintf(out,"Available switches:"ZT_EOL_S);
+	fprintf(out," -h                - Display this help"ZT_EOL_S);
+	fprintf(out," -p<port>          - Bind to this port for network I/O"ZT_EOL_S);
+	fprintf(out," -c<port>          - 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<argc;++i) {
 		if (argv[i][0] == '-') {
 			switch(argv[i][1]) {
+				case 'p':
+					port = Utils::strToUInt(argv[i] + 2);
+					if (port > 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:

+ 2 - 2
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

+ 4 - 6
node/Defaults.cpp

@@ -50,30 +50,28 @@ static inline std::map< Identity,std::vector<InetAddress> > _mkSupernodeMap()
 	std::vector<InetAddress> 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;
 }

+ 28 - 26
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)

+ 7 - 4
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"

+ 2 - 2
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];

+ 2 - 1
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();