Преглед на файлове

Make GUI work with new control client API, make control client look for user authtoken.secret if system unreadable.

Adam Ierymenko преди 11 години
родител
ревизия
f0223490be
променени са 9 файла, в които са добавени 185 реда и са изтрити 232 реда
  1. 35 28
      ZeroTierUI/ZeroTierUI.pro
  2. 11 1
      ZeroTierUI/aboutwindow.cpp
  3. 78 82
      ZeroTierUI/mainwindow.cpp
  4. 1 1
      ZeroTierUI/mainwindow.h
  5. 0 3
      ZeroTierUI/networkwidget.cpp
  6. 33 94
      ZeroTierUI/networkwidget.ui
  7. 3 2
      main.cpp
  8. 23 20
      node/Node.cpp
  9. 1 1
      node/Node.hpp

+ 35 - 28
ZeroTierUI/ZeroTierUI.pro

@@ -12,16 +12,21 @@ mac:QMAKE_INFO_PLIST = Info.plist
 mac:LIBS += -framework Cocoa
 mac:LIBS += -framework Cocoa
 
 
 SOURCES += main.cpp \
 SOURCES += main.cpp \
-    mainwindow.cpp \
-    aboutwindow.cpp \
+		mainwindow.cpp \
+		aboutwindow.cpp \
+		networkwidget.cpp \
+		installdialog.cpp \
+		licensedialog.cpp \
+		onetimedialog.cpp \
     ../node/C25519.cpp \
     ../node/C25519.cpp \
     ../node/CertificateOfMembership.cpp \
     ../node/CertificateOfMembership.cpp \
     ../node/Defaults.cpp \
     ../node/Defaults.cpp \
-    ../node/Demarc.cpp \
     ../node/EthernetTap.cpp \
     ../node/EthernetTap.cpp \
     ../node/HttpClient.cpp \
     ../node/HttpClient.cpp \
     ../node/Identity.cpp \
     ../node/Identity.cpp \
     ../node/InetAddress.cpp \
     ../node/InetAddress.cpp \
+    ../node/IpcConnection.cpp \
+    ../node/IpcListener.cpp \
     ../node/Logger.cpp \
     ../node/Logger.cpp \
     ../node/Multicaster.cpp \
     ../node/Multicaster.cpp \
     ../node/Network.cpp \
     ../node/Network.cpp \
@@ -35,24 +40,25 @@ SOURCES += main.cpp \
     ../node/Salsa20.cpp \
     ../node/Salsa20.cpp \
     ../node/Service.cpp \
     ../node/Service.cpp \
     ../node/SHA512.cpp \
     ../node/SHA512.cpp \
+    ../node/SocketManager.cpp \
     ../node/SoftwareUpdater.cpp \
     ../node/SoftwareUpdater.cpp \
     ../node/Switch.cpp \
     ../node/Switch.cpp \
     ../node/SysEnv.cpp \
     ../node/SysEnv.cpp \
+    ../node/TcpSocket.cpp \
     ../node/Topology.cpp \
     ../node/Topology.cpp \
     ../node/UdpSocket.cpp \
     ../node/UdpSocket.cpp \
     ../node/Utils.cpp \
     ../node/Utils.cpp \
     ../ext/lz4/lz4.c \
     ../ext/lz4/lz4.c \
-    ../ext/lz4/lz4hc.c \
-    networkwidget.cpp \
-    installdialog.cpp \
-    licensedialog.cpp \
-    onetimedialog.cpp
+    ../ext/lz4/lz4hc.c
 
 
 HEADERS  += mainwindow.h \
 HEADERS  += mainwindow.h \
-    aboutwindow.h \
-    ../node/Node.hpp \
-    ../node/Utils.hpp \
-    ../node/Defaults.hpp \
+		aboutwindow.h \
+		networkwidget.h \
+		installdialog.h \
+		mac_doprivileged.h \
+		licensedialog.h \
+		main.h \
+		onetimedialog.h \
     ../node/Address.hpp \
     ../node/Address.hpp \
     ../node/Array.hpp \
     ../node/Array.hpp \
     ../node/AtomicCounter.hpp \
     ../node/AtomicCounter.hpp \
@@ -61,14 +67,15 @@ HEADERS  += mainwindow.h \
     ../node/C25519.hpp \
     ../node/C25519.hpp \
     ../node/CertificateOfMembership.hpp \
     ../node/CertificateOfMembership.hpp \
     ../node/CMWC4096.hpp \
     ../node/CMWC4096.hpp \
-    ../node/Condition.hpp \
     ../node/Constants.hpp \
     ../node/Constants.hpp \
-    ../node/Demarc.hpp \
+    ../node/Defaults.hpp \
     ../node/Dictionary.hpp \
     ../node/Dictionary.hpp \
     ../node/EthernetTap.hpp \
     ../node/EthernetTap.hpp \
     ../node/HttpClient.hpp \
     ../node/HttpClient.hpp \
     ../node/Identity.hpp \
     ../node/Identity.hpp \
     ../node/InetAddress.hpp \
     ../node/InetAddress.hpp \
+    ../node/IpcConnection.hpp \
+    ../node/IpcListener.hpp \
     ../node/Logger.hpp \
     ../node/Logger.hpp \
     ../node/MAC.hpp \
     ../node/MAC.hpp \
     ../node/Multicaster.hpp \
     ../node/Multicaster.hpp \
@@ -76,10 +83,12 @@ HEADERS  += mainwindow.h \
     ../node/Mutex.hpp \
     ../node/Mutex.hpp \
     ../node/Network.hpp \
     ../node/Network.hpp \
     ../node/NetworkConfig.hpp \
     ../node/NetworkConfig.hpp \
+    ../node/Node.hpp \
     ../node/NodeConfig.hpp \
     ../node/NodeConfig.hpp \
     ../node/NonCopyable.hpp \
     ../node/NonCopyable.hpp \
     ../node/Packet.hpp \
     ../node/Packet.hpp \
     ../node/PacketDecoder.hpp \
     ../node/PacketDecoder.hpp \
+    ../node/Path.hpp \
     ../node/Peer.hpp \
     ../node/Peer.hpp \
     ../node/Poly1305.hpp \
     ../node/Poly1305.hpp \
     ../node/RuntimeEnvironment.hpp \
     ../node/RuntimeEnvironment.hpp \
@@ -87,28 +96,26 @@ HEADERS  += mainwindow.h \
     ../node/Service.hpp \
     ../node/Service.hpp \
     ../node/SHA512.hpp \
     ../node/SHA512.hpp \
     ../node/SharedPtr.hpp \
     ../node/SharedPtr.hpp \
+    ../node/Socket.hpp \
+    ../node/SocketManager.hpp \
     ../node/SoftwareUpdater.hpp \
     ../node/SoftwareUpdater.hpp \
     ../node/Switch.hpp \
     ../node/Switch.hpp \
     ../node/SysEnv.hpp \
     ../node/SysEnv.hpp \
+    ../node/TcpSocket.hpp \
     ../node/Thread.hpp \
     ../node/Thread.hpp \
     ../node/Topology.hpp \
     ../node/Topology.hpp \
     ../node/UdpSocket.hpp \
     ../node/UdpSocket.hpp \
+    ../node/Utils.hpp \
     ../ext/lz4/lz4.h \
     ../ext/lz4/lz4.h \
-    ../ext/lz4/lz4hc.h \
-    networkwidget.h \
-    installdialog.h \
-    mac_doprivileged.h \
-    licensedialog.h \
-    main.h \
-    onetimedialog.h
+    ../ext/lz4/lz4hc.h
 
 
 FORMS    += mainwindow.ui \
 FORMS    += mainwindow.ui \
-    aboutwindow.ui \
-    networkwidget.ui \
-    installdialog.ui \
-    licensedialog.ui \
-    quickstartdialog.ui \
-    onetimedialog.ui
+		aboutwindow.ui \
+		networkwidget.ui \
+		installdialog.ui \
+		licensedialog.ui \
+		quickstartdialog.ui \
+		onetimedialog.ui
 
 
 RESOURCES += \
 RESOURCES += \
 		resources.qrc
 		resources.qrc
@@ -117,4 +124,4 @@ mac:OBJECTIVE_SOURCES += \
 		mac_doprivileged.mm
 		mac_doprivileged.mm
 
 
 OTHER_FILES += \
 OTHER_FILES += \
-    stylesheet.css
+		stylesheet.css

+ 11 - 1
ZeroTierUI/aboutwindow.cpp

@@ -39,7 +39,17 @@ AboutWindow::AboutWindow(QWidget *parent) :
 	ui(new Ui::AboutWindow)
 	ui(new Ui::AboutWindow)
 {
 {
 	ui->setupUi(this);
 	ui->setupUi(this);
-	ui->aboutTextLabel->setText(QString("ZeroTier One\nVersion ")+ZeroTier::Node::versionString()+"\nQt Graphical User Interface\n\n(c)2011-2014 ZeroTier Networks LLC\n\nReleased under the terms of the GNU\nGeneral Public License v3.0, see: http://gplv3.fsf.org for terms.\n\nAuthor(s): Adam Ierymenko");
+	ui->aboutTextLabel->setText(QString("ZeroTier One\nVersion ")+ZeroTier::Node::versionString()+"\nDesktop Graphical User Interface\n\n(c)2011-2014 ZeroTier Networks LLC\n\nReleased under the terms of the GNU\nGeneral Public License v3.0, see: http://gplv3.fsf.org for terms.\n\nAuthor(s): Adam Ierymenko");
+
+#ifdef __WINDOWS__
+	QWidgetList widgets = this->findChildren<QWidget*>();
+	foreach(QWidget *widget, widgets) {
+		QFont font(widget->font());
+		font.setPointSizeF(font.pointSizeF() * 0.75);
+		widget->setFont(font);
+	}
+	this->raise();
+#endif
 }
 }
 
 
 AboutWindow::~AboutWindow()
 AboutWindow::~AboutWindow()

+ 78 - 82
ZeroTierUI/mainwindow.cpp

@@ -63,32 +63,32 @@
 #endif
 #endif
 
 
 // Globally visible
 // Globally visible
-ZeroTier::Node::LocalClient *zeroTierClient = (ZeroTier::Node::LocalClient *)0;
+ZeroTier::Node::NodeControlClient *zeroTierClient = (ZeroTier::Node::NodeControlClient *)0;
 
 
 // Main window instance for app
 // Main window instance for app
 QMainWindow *mainWindow = (MainWindow *)0;
 QMainWindow *mainWindow = (MainWindow *)0;
 
 
 // Handles message from ZeroTier One service
 // Handles message from ZeroTier One service
-static void handleZTMessage(void *arg,unsigned long id,const char *line)
+static void handleZTMessage(void *arg,const char *line)
 {
 {
-	static std::map< unsigned long,std::vector<std::string> > ztReplies;
+	static std::vector<std::string> ztReplies;
 	static QMutex ztReplies_m;
 	static QMutex ztReplies_m;
 
 
 	ztReplies_m.lock();
 	ztReplies_m.lock();
-	if (*line) {
-		ztReplies[id].push_back(std::string(line));
-		ztReplies_m.unlock();
-	} else { // empty lines conclude transmissions
-		std::map< unsigned long,std::vector<std::string> >::iterator r(ztReplies.find(id));
-		if (r != ztReplies.end()) {
+
+	if (line) {
+		if ((line[0] == '.')&&(line[1] == (char)0)) {
 			// The message is packed into an event and sent to the main window where
 			// The message is packed into an event and sent to the main window where
 			// the actual parsing code lives.
 			// the actual parsing code lives.
-			MainWindow::ZTMessageEvent *event = new MainWindow::ZTMessageEvent(r->second);
-			ztReplies.erase(r);
-			ztReplies_m.unlock();
+			MainWindow::ZTMessageEvent *event = new MainWindow::ZTMessageEvent(ztReplies);
+			ztReplies.clear();
 			QCoreApplication::postEvent(mainWindow,event); // must post since this may be another thread
 			QCoreApplication::postEvent(mainWindow,event); // must post since this may be another thread
-		} else ztReplies_m.unlock();
+		} else if (line[0]) {
+			ztReplies.push_back(std::string(line));
+		}
 	}
 	}
+
+	ztReplies_m.unlock();
 }
 }
 
 
 MainWindow::MainWindow(QWidget *parent) :
 MainWindow::MainWindow(QWidget *parent) :
@@ -136,7 +136,7 @@ MainWindow::~MainWindow()
 {
 {
 	delete ui;
 	delete ui;
 	delete zeroTierClient;
 	delete zeroTierClient;
-	zeroTierClient = (ZeroTier::Node::LocalClient *)0;
+	zeroTierClient = (ZeroTier::Node::NodeControlClient *)0;
 	mainWindow = (MainWindow *)0;
 	mainWindow = (MainWindow *)0;
 }
 }
 
 
@@ -147,75 +147,72 @@ void MainWindow::timerEvent(QTimerEvent *event) // event can be null since code
 	if (this->pollServiceTimerId < 0)
 	if (this->pollServiceTimerId < 0)
 		return;
 		return;
 
 
+	// Show quick start dialog on first launch, then reset timer to normal rate
 	if (this->firstTimerTick) {
 	if (this->firstTimerTick) {
 		this->firstTimerTick = false;
 		this->firstTimerTick = false;
 		this->killTimer(this->pollServiceTimerId);
 		this->killTimer(this->pollServiceTimerId);
-
 		if (!settings->value("shown_quickStart",false).toBool()) {
 		if (!settings->value("shown_quickStart",false).toBool()) {
 			on_actionQuick_Start_triggered();
 			on_actionQuick_Start_triggered();
 			settings->setValue("shown_quickStart",true);
 			settings->setValue("shown_quickStart",true);
 			settings->sync();
 			settings->sync();
 		}
 		}
-
-		this->pollServiceTimerId = this->startTimer(1500);
+		this->pollServiceTimerId = this->startTimer(2000);
 	}
 	}
 
 
 	if (!zeroTierClient) {
 	if (!zeroTierClient) {
-		std::string authToken;
-		if (!ZeroTier::Utils::readFile(ZeroTier::Node::LocalClient::authTokenDefaultUserPath().c_str(),authToken)) {
 #ifdef __APPLE__
 #ifdef __APPLE__
-			if (QFile::exists("/Library/Application Support/ZeroTier/One/zerotier-one")) {
-				// Authorize user by copying auth token into local home directory
-				QMessageBox::information(this,"Authorization Needed","Administrator privileges are required to allow the current user to control ZeroTier One on this computer. (You only have to do this once.)",QMessageBox::Ok,QMessageBox::NoButton);
-
-				std::string homePath(QDir::homePath().toStdString());
-				QString zt1Caches(QDir::homePath() + "/Library/Caches/ZeroTier/One");
-				QDir::root().mkpath(zt1Caches);
-				std::string tmpPath((zt1Caches + "/auth.sh").toStdString());
-
-				FILE *scr = fopen(tmpPath.c_str(),"w");
-				if (!scr) {
-					QMessageBox::critical(this,"Cannot Authorize","Unable to authorize this user to administrate ZeroTier One. (Cannot write to temporary Library/Caches/ZeroTier/One folder.)",QMessageBox::Ok,QMessageBox::NoButton);
-					QApplication::exit(1);
-					return;
-				}
-
-				fprintf(scr,"#!/bin/bash\n");
-				fprintf(scr,"export PATH=\"/bin:/usr/bin:/sbin:/usr/sbin\"\n");
-				fprintf(scr,"if [ -f '/Library/Application Support/ZeroTier/One/authtoken.secret' ]; then\n");
-				fprintf(scr,"  mkdir -p '%s/Library/Application Support/ZeroTier/One'\n",homePath.c_str());
-				fprintf(scr,"  chown %d '%s/Library/Application Support/ZeroTier'\n",(int)getuid(),homePath.c_str());
-				fprintf(scr,"  chgrp %d '%s/Library/Application Support/ZeroTier'\n",(int)getgid(),homePath.c_str());
-				fprintf(scr,"  chmod 0700 '%s/Library/Application Support/ZeroTier'\n",homePath.c_str());
-				fprintf(scr,"  chown %d '%s/Library/Application Support/ZeroTier/One'\n",(int)getuid(),homePath.c_str());
-				fprintf(scr,"  chgrp %d '%s/Library/Application Support/ZeroTier/One'\n",(int)getgid(),homePath.c_str());
-				fprintf(scr,"  chmod 0700 '%s/Library/Application Support/ZeroTier/One'\n",homePath.c_str());
-				fprintf(scr,"  cp -f '/Library/Application Support/ZeroTier/One/authtoken.secret' '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",homePath.c_str());
-				fprintf(scr,"  chown %d '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",(int)getuid(),homePath.c_str());
-				fprintf(scr,"  chgrp %d '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",(int)getgid(),homePath.c_str());
-				fprintf(scr,"  chmod 0600 '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",homePath.c_str());
-				fprintf(scr,"fi\n");
-				fprintf(scr,"exit 0\n");
-
-				fclose(scr);
-				chmod(tmpPath.c_str(),0755);
-
-				macExecutePrivilegedShellCommand((std::string("'")+tmpPath+"' >>/dev/null 2>&1").c_str());
-
-				unlink(tmpPath.c_str());
+		if ((!QFile::exists(ZeroTier::Node::NodeControlClient::authTokenDefaultUserPath()))&&(QFile::exists("/Library/Application Support/ZeroTier/One/zerotier-one"))) {
+			// Authorize user by copying auth token into local home directory
+			QMessageBox::information(this,"Authorization Needed","Administrator privileges are required to allow the current user to control ZeroTier One on this computer. (You only have to do this once.)",QMessageBox::Ok,QMessageBox::NoButton);
+
+			std::string homePath(QDir::homePath().toStdString());
+			QString zt1Caches(QDir::homePath() + "/Library/Caches/ZeroTier/One");
+			QDir::root().mkpath(zt1Caches);
+			std::string tmpPath((zt1Caches + "/auth.sh").toStdString());
+
+			FILE *scr = fopen(tmpPath.c_str(),"w");
+			if (!scr) {
+				QMessageBox::critical(this,"Cannot Authorize","Unable to authorize this user to administrate ZeroTier One. (Cannot write to temporary Library/Caches/ZeroTier/One folder.)",QMessageBox::Ok,QMessageBox::NoButton);
+				QApplication::exit(1);
+				return;
 			}
 			}
-#endif
 
 
-			if (!ZeroTier::Utils::readFile(ZeroTier::Node::LocalClient::authTokenDefaultUserPath().c_str(),authToken)) {
-				if (!ZeroTier::Utils::readFile(ZeroTier::Node::LocalClient::authTokenDefaultSystemPath().c_str(),authToken)) {
-					QMessageBox::critical(this,"Cannot Authorize","Unable to authorize this user to administrate ZeroTier One. (Did you enter your password correctly?)",QMessageBox::Ok,QMessageBox::NoButton);
-					QApplication::exit(1);
-					return;
-				}
+			fprintf(scr,"#!/bin/bash\n");
+			fprintf(scr,"export PATH=\"/bin:/usr/bin:/sbin:/usr/sbin\"\n");
+			fprintf(scr,"if [ -f '/Library/Application Support/ZeroTier/One/authtoken.secret' ]; then\n");
+			fprintf(scr,"  mkdir -p '%s/Library/Application Support/ZeroTier/One'\n",homePath.c_str());
+			fprintf(scr,"  chown %d '%s/Library/Application Support/ZeroTier'\n",(int)getuid(),homePath.c_str());
+			fprintf(scr,"  chgrp %d '%s/Library/Application Support/ZeroTier'\n",(int)getgid(),homePath.c_str());
+			fprintf(scr,"  chmod 0700 '%s/Library/Application Support/ZeroTier'\n",homePath.c_str());
+			fprintf(scr,"  chown %d '%s/Library/Application Support/ZeroTier/One'\n",(int)getuid(),homePath.c_str());
+			fprintf(scr,"  chgrp %d '%s/Library/Application Support/ZeroTier/One'\n",(int)getgid(),homePath.c_str());
+			fprintf(scr,"  chmod 0700 '%s/Library/Application Support/ZeroTier/One'\n",homePath.c_str());
+			fprintf(scr,"  cp -f '/Library/Application Support/ZeroTier/One/authtoken.secret' '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",homePath.c_str());
+			fprintf(scr,"  chown %d '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",(int)getuid(),homePath.c_str());
+			fprintf(scr,"  chgrp %d '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",(int)getgid(),homePath.c_str());
+			fprintf(scr,"  chmod 0600 '%s/Library/Application Support/ZeroTier/One/authtoken.secret'\n",homePath.c_str());
+			fprintf(scr,"fi\n");
+			fprintf(scr,"exit 0\n");
+
+			fclose(scr);
+			chmod(tmpPath.c_str(),0755);
+
+			macExecutePrivilegedShellCommand((std::string("'")+tmpPath+"' >>/dev/null 2>&1").c_str());
+
+			unlink(tmpPath.c_str());
+		}
+#endif // __APPLE__
+
+		try {
+			zeroTierClient = new ZeroTier::Node::NodeControlClient((const char *)0,&handleZTMessage,this);
+			const char *err = zeroTierClient->error();
+			if (err) {
+				delete zeroTierClient;
+				zeroTierClient = (ZeroTier::Node::NodeControlClient *)0;
 			}
 			}
+		} catch ( ... ) {
+			zeroTierClient = (ZeroTier::Node::NodeControlClient *)0;
 		}
 		}
-
-		zeroTierClient = new ZeroTier::Node::LocalClient(authToken.c_str(),0,&handleZTMessage,this);
 	}
 	}
 
 
 	if (++this->cyclesSinceResponseFromService >= 3) {
 	if (++this->cyclesSinceResponseFromService >= 3) {
@@ -227,9 +224,11 @@ void MainWindow::timerEvent(QTimerEvent *event) // event can be null since code
 		ui->networkListWidget->setVisible(false);
 		ui->networkListWidget->setVisible(false);
 	}
 	}
 
 
-	zeroTierClient->send("info");
-	zeroTierClient->send("listnetworks");
-	zeroTierClient->send("listpeers");
+	if (zeroTierClient) {
+		zeroTierClient->send("info");
+		zeroTierClient->send("listnetworks");
+		zeroTierClient->send("listpeers");
+	}
 }
 }
 
 
 void MainWindow::customEvent(QEvent *event)
 void MainWindow::customEvent(QEvent *event)
@@ -237,15 +236,14 @@ void MainWindow::customEvent(QEvent *event)
 	ZTMessageEvent *m = (ZTMessageEvent *)event; // only one custom event type so far
 	ZTMessageEvent *m = (ZTMessageEvent *)event; // only one custom event type so far
 	if (m->ztMessage.size() == 0)
 	if (m->ztMessage.size() == 0)
 		return;
 		return;
-
-	this->cyclesSinceResponseFromService = 0;
-
-	std::vector<std::string> hdr(ZeroTier::Node::LocalClient::splitLine(m->ztMessage[0]));
+	std::vector<std::string> hdr(ZeroTier::Node::NodeControlClient::splitLine(m->ztMessage[0]));
 	if (hdr.size() < 2)
 	if (hdr.size() < 2)
 		return;
 		return;
 	if (hdr[0] != "200")
 	if (hdr[0] != "200")
 		return;
 		return;
 
 
+	this->cyclesSinceResponseFromService = 0;
+
 	if (hdr[1] == "info") {
 	if (hdr[1] == "info") {
 		if (hdr.size() >= 3)
 		if (hdr.size() >= 3)
 			this->myAddress = hdr[2].c_str();
 			this->myAddress = hdr[2].c_str();
@@ -256,7 +254,7 @@ void MainWindow::customEvent(QEvent *event)
 	} else if (hdr[1] == "listnetworks") {
 	} else if (hdr[1] == "listnetworks") {
 		std::map< std::string,std::vector<std::string> > newNetworks;
 		std::map< std::string,std::vector<std::string> > newNetworks;
 		for(unsigned long i=1;i<m->ztMessage.size();++i) {
 		for(unsigned long i=1;i<m->ztMessage.size();++i) {
-			std::vector<std::string> l(ZeroTier::Node::LocalClient::splitLine(m->ztMessage[i]));
+			std::vector<std::string> l(ZeroTier::Node::NodeControlClient::splitLine(m->ztMessage[i]));
 			// 200 listnetworks <nwid> <name> <status> <config age> <type> <dev> <ips>
 			// 200 listnetworks <nwid> <name> <status> <config age> <type> <dev> <ips>
 			if ((l.size() == 9)&&(l[2].length() == 16))
 			if ((l.size() == 9)&&(l[2].length() == 16))
 				newNetworks[l[2]] = l;
 				newNetworks[l[2]] = l;
@@ -309,12 +307,10 @@ void MainWindow::customEvent(QEvent *event)
 		}
 		}
 	} else if (hdr[1] == "listpeers") {
 	} else if (hdr[1] == "listpeers") {
 		this->numPeers = 0;
 		this->numPeers = 0;
-		for(unsigned long i=1;i<m->ztMessage.size();++i) {
-			std::vector<std::string> l(ZeroTier::Node::LocalClient::splitLine(m->ztMessage[i]));
-			if ((l.size() >= 5)&&((l[3] != "-")||(l[4] != "-")))
-				++this->numPeers; // number of direct peers online -- check for active IPv4 and/or IPv6 address
-		}
-	}
+		for(unsigned long i=1;i<m->ztMessage.size();++i)
+			++this->numPeers;
+	} else
+		return;
 
 
 	if (!ui->networkListWidget->count()) {
 	if (!ui->networkListWidget->count()) {
 		ui->noNetworksLabel->setText("You Have Not Joined Any Networks");
 		ui->noNetworksLabel->setText("You Have Not Joined Any Networks");
@@ -335,7 +331,7 @@ void MainWindow::customEvent(QEvent *event)
 	st += this->myVersion;
 	st += this->myVersion;
 	st += ", ";
 	st += ", ";
 	st += QString::number(this->numPeers);
 	st += QString::number(this->numPeers);
-	st += " direct links to peers";
+	st += " peers";
 	ui->statusLabel->setText(st);
 	ui->statusLabel->setText(st);
 }
 }
 
 

+ 1 - 1
ZeroTierUI/mainwindow.h

@@ -49,7 +49,7 @@ class MainWindow;
 
 
 // Globally visible instance of local client for communicating with ZT1
 // Globally visible instance of local client for communicating with ZT1
 // Can be null if not connected, or will point to current
 // Can be null if not connected, or will point to current
-extern ZeroTier::Node::LocalClient *zeroTierClient;
+extern ZeroTier::Node::NodeControlClient *zeroTierClient;
 
 
 // Globally visible pointer to main app window
 // Globally visible pointer to main app window
 extern QMainWindow *mainWindow;
 extern QMainWindow *mainWindow;

+ 0 - 3
ZeroTierUI/networkwidget.cpp

@@ -80,9 +80,6 @@ NetworkWidget::~NetworkWidget()
 void NetworkWidget::setStatus(const std::string &status,const std::string &age)
 void NetworkWidget::setStatus(const std::string &status,const std::string &age)
 {
 {
 	ui->statusLabel->setText(QString(status.c_str()));
 	ui->statusLabel->setText(QString(status.c_str()));
-	if (status == "OK")
-		ui->ageLabel->setText(QString("[") + age.c_str() + "s ago]");
-	else ui->ageLabel->setText(QString());
 }
 }
 
 
 void NetworkWidget::setNetworkName(const std::string &name)
 void NetworkWidget::setNetworkName(const std::string &name)

+ 33 - 94
ZeroTierUI/networkwidget.ui

@@ -178,12 +178,6 @@
       </item>
       </item>
       <item>
       <item>
        <widget class="QWidget" name="networkStatsWidget" native="true">
        <widget class="QWidget" name="networkStatsWidget" native="true">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-          <horstretch>0</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
         <layout class="QFormLayout" name="formLayout">
         <layout class="QFormLayout" name="formLayout">
          <property name="fieldGrowthPolicy">
          <property name="fieldGrowthPolicy">
           <enum>QFormLayout::ExpandingFieldsGrow</enum>
           <enum>QFormLayout::ExpandingFieldsGrow</enum>
@@ -232,6 +226,12 @@
          </item>
          </item>
          <item row="2" column="1">
          <item row="2" column="1">
           <widget class="QLabel" name="networkTypeLabel">
           <widget class="QLabel" name="networkTypeLabel">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
            <property name="font">
            <property name="font">
             <font>
             <font>
              <pointsize>12</pointsize>
              <pointsize>12</pointsize>
@@ -280,101 +280,40 @@
            </property>
            </property>
           </widget>
           </widget>
          </item>
          </item>
-         <item row="3" column="1">
-          <widget class="QWidget" name="widget" native="true">
+         <item row="4" column="1">
+          <widget class="QLabel" name="deviceLabel">
            <property name="sizePolicy">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
             <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
              <horstretch>0</horstretch>
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
             </sizepolicy>
            </property>
            </property>
-           <layout class="QHBoxLayout" name="horizontalLayout_3">
-            <property name="spacing">
-             <number>12</number>
-            </property>
-            <property name="leftMargin">
-             <number>0</number>
-            </property>
-            <property name="topMargin">
-             <number>0</number>
-            </property>
-            <property name="rightMargin">
-             <number>0</number>
-            </property>
-            <property name="bottomMargin">
-             <number>0</number>
-            </property>
-            <item>
-             <widget class="QLabel" name="statusLabel">
-              <property name="sizePolicy">
-               <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-                <horstretch>0</horstretch>
-                <verstretch>0</verstretch>
-               </sizepolicy>
-              </property>
-              <property name="font">
-               <font>
-                <pointsize>12</pointsize>
-                <weight>75</weight>
-                <bold>true</bold>
-               </font>
-              </property>
-              <property name="statusTip">
-               <string>Status of this network.</string>
-              </property>
-              <property name="text">
-               <string>?</string>
-              </property>
-              <property name="textFormat">
-               <enum>Qt::PlainText</enum>
-              </property>
-             </widget>
-            </item>
-            <item>
-             <widget class="QLabel" name="ageLabel">
-              <property name="sizePolicy">
-               <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
-                <horstretch>0</horstretch>
-                <verstretch>0</verstretch>
-               </sizepolicy>
-              </property>
-              <property name="font">
-               <font>
-                <pointsize>10</pointsize>
-               </font>
-              </property>
-              <property name="statusTip">
-               <string>How recently did this network refresh its settings?</string>
-              </property>
-              <property name="text">
-               <string>[0s ago]</string>
-              </property>
-              <property name="textFormat">
-               <enum>Qt::PlainText</enum>
-              </property>
-              <property name="textInteractionFlags">
-               <set>Qt::NoTextInteraction</set>
-              </property>
-             </widget>
-            </item>
-            <item>
-             <spacer name="horizontalSpacer_2">
-              <property name="orientation">
-               <enum>Qt::Horizontal</enum>
-              </property>
-              <property name="sizeHint" stdset="0">
-               <size>
-                <width>40</width>
-                <height>1</height>
-               </size>
-              </property>
-             </spacer>
-            </item>
-           </layout>
+           <property name="font">
+            <font>
+             <pointsize>12</pointsize>
+             <weight>75</weight>
+             <bold>true</bold>
+            </font>
+           </property>
+           <property name="statusTip">
+            <string>The name of the network device on your system.</string>
+           </property>
+           <property name="text">
+            <string>?</string>
+           </property>
+           <property name="textFormat">
+            <enum>Qt::PlainText</enum>
+           </property>
           </widget>
           </widget>
          </item>
          </item>
-         <item row="4" column="1">
-          <widget class="QLabel" name="deviceLabel">
+         <item row="3" column="1">
+          <widget class="QLabel" name="statusLabel">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
            <property name="font">
            <property name="font">
             <font>
             <font>
              <pointsize>12</pointsize>
              <pointsize>12</pointsize>
@@ -383,7 +322,7 @@
             </font>
             </font>
            </property>
            </property>
            <property name="statusTip">
            <property name="statusTip">
-            <string>The name of the network device on your system.</string>
+            <string>Status of this network.</string>
            </property>
            </property>
            <property name="text">
            <property name="text">
             <string>?</string>
             <string>?</string>

+ 3 - 2
main.cpp

@@ -161,8 +161,9 @@ static int main(int argc,char **argv)
 	try {
 	try {
 		volatile bool done = false;
 		volatile bool done = false;
 		Node::NodeControlClient client(hp,&_CBresultHandler,(void *)&done);
 		Node::NodeControlClient client(hp,&_CBresultHandler,(void *)&done);
-		if (client.error()) {
-			fprintf(stderr,"%s: fatal error: unable to connect (is ZeroTier One running?)"ZT_EOL_S,argv[0]);
+		const char *err = client.error();
+		if (err) {
+			fprintf(stderr,"%s: fatal error: unable to connect (is ZeroTier One running?) (%s)"ZT_EOL_S,argv[0],err);
 			return 1;
 			return 1;
 		}
 		}
 		client.send(query.c_str());
 		client.send(query.c_str());

+ 23 - 20
node/Node.cpp

@@ -109,27 +109,30 @@ Node::NodeControlClient::NodeControlClient(const char *hp,void (*resultHandler)(
 	std::string at;
 	std::string at;
 	if (authToken)
 	if (authToken)
 		at = authToken;
 		at = authToken;
-	else if (!Utils::readFile((std::string(hp) + ZT_PATH_SEPARATOR_S + "authtoken.secret").c_str(),at))
-		impl->err = "no authentication token specified and authtoken.secret not readable";
-	else {
-		std::string myid;
-		if (Utils::readFile((std::string(hp) + ZT_PATH_SEPARATOR_S + "identity.public").c_str(),myid)) {
-			std::string myaddr(myid.substr(0,myid.find(':')));
-			if (myaddr.length() != 10)
-				impl->err = "invalid address extracted from identity.public";
-			else {
-				try {
-					impl->resultHandler = resultHandler;
-					impl->arg = arg;
-					impl->ipcc = new IpcConnection((std::string(ZT_IPC_ENDPOINT_BASE) + myaddr).c_str(),&_CBipcResultHandler,_impl);
-					impl->ipcc->printf("auth %s"ZT_EOL_S,at.c_str());
-				} catch ( ... ) {
-					impl->ipcc = (IpcConnection *)0;
-					impl->err = "failure connecting to running ZeroTier One service";
-				}
-			}
-		} else impl->err = "unable to read identity.public";
+	else if (!Utils::readFile(authTokenDefaultSystemPath(),at)) {
+		if (!Utils::readFile(authTokenDefaultUserPath(),at)) {
+			impl->err = "no authentication token specified and authtoken.secret not readable";
+			return;
+		}
 	}
 	}
+
+	std::string myid;
+	if (Utils::readFile((std::string(hp) + ZT_PATH_SEPARATOR_S + "identity.public").c_str(),myid)) {
+		std::string myaddr(myid.substr(0,myid.find(':')));
+		if (myaddr.length() != 10)
+			impl->err = "invalid address extracted from identity.public";
+		else {
+			try {
+				impl->resultHandler = resultHandler;
+				impl->arg = arg;
+				impl->ipcc = new IpcConnection((std::string(ZT_IPC_ENDPOINT_BASE) + myaddr).c_str(),&_CBipcResultHandler,_impl);
+				impl->ipcc->printf("auth %s"ZT_EOL_S,at.c_str());
+			} catch ( ... ) {
+				impl->ipcc = (IpcConnection *)0;
+				impl->err = "failure connecting to running ZeroTier One service";
+			}
+		}
+	} else impl->err = "unable to read identity.public";
 }
 }
 
 
 Node::NodeControlClient::~NodeControlClient()
 Node::NodeControlClient::~NodeControlClient()

+ 1 - 1
node/Node.hpp

@@ -58,7 +58,7 @@ public:
 		 *
 		 *
 		 * Initialization may fail. Call error() to check.
 		 * Initialization may fail. Call error() to check.
 		 *
 		 *
-		 * @param hp Home path of ZeroTier One instance
+		 * @param hp Home path of ZeroTier One instance or NULL for default system home path
 		 * @param resultHandler Function to call when commands provide results
 		 * @param resultHandler Function to call when commands provide results
 		 * @param arg First argument to result handler
 		 * @param arg First argument to result handler
 		 * @param authToken Authentication token or NULL (default) to read from authtoken.secret in home path
 		 * @param authToken Authentication token or NULL (default) to read from authtoken.secret in home path