Browse Source

CLI communication now working.

Adam Ierymenko 12 years ago
parent
commit
c9c63074bb
5 changed files with 41 additions and 33 deletions
  1. 6 6
      cli.cpp
  2. 20 8
      node/NodeConfig.cpp
  3. 0 13
      node/NodeConfig.hpp
  4. 14 5
      node/UdpSocket.cpp
  5. 1 1
      node/UdpSocket.hpp

+ 6 - 6
cli.cpp

@@ -37,6 +37,7 @@
 #include "node/Constants.hpp"
 #include "node/Utils.hpp"
 #include "node/Thread.hpp"
+#include "node/Condition.hpp"
 
 using namespace ZeroTier;
 
@@ -51,14 +52,15 @@ static void printHelp(FILE *out,const char *exename)
 	fprintf(out,"Use the 'help' command to get help from ZeroTier One itself."ZT_EOL_S);
 }
 
-static volatile uint64_t lastResultTime = 0ULL;
 static volatile unsigned int numResults = 0;
+static Condition doneCondition;
 
 static void resultHandler(void *arg,unsigned long id,const char *line)
 {
-	lastResultTime = Utils::now();
 	++numResults;
-	fprintf(stdout,"%s"ZT_EOL_S,line);
+	if (strlen(line))
+		fprintf(stdout,"%s"ZT_EOL_S,line);
+	else doneCondition.signal();
 }
 
 int main(int argc,char **argv)
@@ -118,9 +120,7 @@ int main(int argc,char **argv)
 	Node::LocalClient client(authToken.c_str(),&resultHandler,(void *)0);
 	client.send(command.c_str());
 
-	lastResultTime = Utils::now();
-	while ((Utils::now() - lastResultTime) < 300)
-		Thread<void>::sleep(50);
+	doneCondition.wait(1000);
 
 	if (!numResults) {
 		fprintf(stdout,"ERROR: no results received. Is ZeroTier One running?"ZT_EOL_S);

+ 20 - 8
node/NodeConfig.cpp

@@ -97,11 +97,11 @@ public:
 	{
 		InetAddress v4(p->ipv4ActivePath(_now));
 		InetAddress v6(p->ipv6ActivePath(_now));
-		_P("200 listpeers %s %s %s %u",
+		_P("200 listpeers %s %s %s %d",
 			p->address().toString().c_str(),
 			((v4) ? v4.toString().c_str() : "(none)"),
 			((v6) ? v6.toString().c_str() : "(none)"),
-			(((v4)||(v6)) ? p->latency() : 0));
+			(((v4)||(v6)) ? (int)p->latency() : -1));
 	}
 
 private:
@@ -129,11 +129,20 @@ std::vector<std::string> NodeConfig::execute(const char *command)
 		_r->topology->eachPeer(_DumpPeerStatistics(r));
 	} else if (cmd[0] == "listnetworks") {
 		Mutex::Lock _l(_networks_m);
+		_P("200 listnetworks <nwid> <type> <dev> <ips>");
 		for(std::map< uint64_t,SharedPtr<Network> >::const_iterator nw(_networks.begin());nw!=_networks.end();++nw) {
-			_P("200 listnetworks %llu %s %s",
-				nw->first,
+			std::string tmp;
+			std::set<InetAddress> ips(nw->second->tap().ips());
+			for(std::set<InetAddress>::iterator i(ips.begin());i!=ips.end();++i) {
+				if (tmp.length())
+					tmp.push_back(',');
+				tmp.append(i->toString());
+			}
+			_P("200 listnetworks %.16llx %s %s %s",
+				(unsigned long long)nw->first,
+				(nw->second->isOpen() ? "public" : "private"),
 				nw->second->tap().deviceName().c_str(),
-				(nw->second->isOpen() ? "public" : "private"));
+				tmp.c_str());
 		}
 	} else if (cmd[0] == "join") {
 		_P("404 join Not implemented yet.");
@@ -143,6 +152,8 @@ std::vector<std::string> NodeConfig::execute(const char *command)
 		_P("404 %s No such command. Use 'help' for help.",cmd[0].c_str());
 	}
 
+	r.push_back(std::string()); // terminate with empty line
+
 	return r;
 }
 
@@ -154,8 +165,9 @@ std::vector< Buffer<ZT_NODECONFIG_MAX_PACKET_SIZE> > NodeConfig::encodeControlMe
 	std::vector< Buffer<ZT_NODECONFIG_MAX_PACKET_SIZE> > packets;
 	Buffer<ZT_NODECONFIG_MAX_PACKET_SIZE> packet;
 
-	packet.setSize(16); // HMAC and IV
+	packet.setSize(16); // room for HMAC and IV
 	packet.append((uint32_t)(conversationId & 0xffffffff));
+
 	for(unsigned int i=0;i<payload.size();++i) {
 		packet.append(payload[i]); // will throw if too big
 		packet.append((unsigned char)0);
@@ -174,7 +186,7 @@ std::vector< Buffer<ZT_NODECONFIG_MAX_PACKET_SIZE> > NodeConfig::encodeControlMe
 
 			packets.push_back(packet);
 
-			packet.setSize(16); // HMAC and IV
+			packet.setSize(16); // room for HMAC and IV
 			packet.append((uint32_t)(conversationId & 0xffffffff));
 		}
 	}
@@ -211,7 +223,7 @@ bool NodeConfig::decodeControlMessagePacket(const void *key,const void *data,uns
 			unsigned int eos = i;
 			while ((eos < pll)&&(pl[eos]))
 				++eos;
-			if (eos > i) {
+			if (eos >= i) {
 				payload.push_back(std::string(pl + i,eos - i));
 				i = eos + 1;
 			} else break;

+ 0 - 13
node/NodeConfig.hpp

@@ -52,19 +52,6 @@ class RuntimeEnvironment;
 
 /**
  * Node configuration endpoint
- *
- * Packet format for local UDP configuration packets:
- *  [16] first 16 bytes of HMAC-SHA-256 of payload
- *  [ -- begin HMAC'ed envelope -- ]
- *  [8] random initialization vector
- *  [ -- begin cryptographic envelope -- ]
- *  [4] arbitrary tag, echoed in response
- *  [...] payload
- *
- * For requests, the payload consists of a single ASCII command. For
- * responses, the payload consists of one or more response lines delimited
- * by NULL (0) characters. The tag field is replicated in the result
- * packet.
  */
 class NodeConfig
 {

+ 14 - 5
node/UdpSocket.cpp

@@ -125,7 +125,13 @@ UdpSocket::UdpSocket(
 
 UdpSocket::~UdpSocket()
 {
-	close(_sock);
+	int s = _sock;
+	_sock = 0;
+	if (s > 0) {
+		::shutdown(s,SHUT_RDWR);
+		::close(s);
+	}
+	Thread<UdpSocket>::join(_thread);
 }
 
 bool UdpSocket::send(const InetAddress &to,const void *data,unsigned int len,int hopLimit)
@@ -148,19 +154,22 @@ bool UdpSocket::send(const InetAddress &to,const void *data,unsigned int len,int
 void UdpSocket::threadMain()
 	throw()
 {
-	char buf[32768];
+	char buf[65536];
 	InetAddress from;
 	socklen_t salen;
 	int n;
 
-	for(;;) {
+	while (_sock > 0) {
 		salen = from.saddrSpaceLen();
 		n = (int)recvfrom(_sock,buf,sizeof(buf),0,from.saddr(),&salen);
 		if (n < 0) {
 			if ((errno != EINTR)&&(errno != ETIMEDOUT))
 				break;
-		} else if (n > 0)
-			_packetHandler(this,_arg,from,buf,(unsigned int)n);
+		} else if (n > 0) {
+			try {
+				_packetHandler(this,_arg,from,buf,(unsigned int)n);
+			} catch ( ... ) {} // should never be thrown from here anyway...
+		}
 	}
 }
 

+ 1 - 1
node/UdpSocket.hpp

@@ -98,7 +98,7 @@ private:
 	void (*_packetHandler)(UdpSocket *,void *,const InetAddress &,const void *,unsigned int);
 	void *_arg;
 	int _localPort;
-	int _sock;
+	volatile int _sock;
 	bool _v6;
 	Mutex _sendLock;
 };