From c979a695c5c58a62c7e3e08128860634b2fc421f Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 20 Nov 2013 16:16:30 -0500 Subject: UI work, add name to listnetworks output in control bus interface. --- node/NodeConfig.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'node/NodeConfig.cpp') diff --git a/node/NodeConfig.cpp b/node/NodeConfig.cpp index 027f65ce..d56c73ae 100644 --- a/node/NodeConfig.cpp +++ b/node/NodeConfig.cpp @@ -200,7 +200,7 @@ std::vector NodeConfig::execute(const char *command) _r->topology->eachPeer(_DumpPeerStatistics(r)); } else if (cmd[0] == "listnetworks") { Mutex::Lock _l(_networks_m); - _P("200 listnetworks "); + _P("200 listnetworks "); for(std::map< uint64_t,SharedPtr >::const_iterator nw(_networks.begin());nw!=_networks.end();++nw) { std::string tmp; std::set ips(nw->second->tap().ips()); @@ -211,8 +211,9 @@ std::vector NodeConfig::execute(const char *command) } SharedPtr nconf(nw->second->config2()); - _P("200 listnetworks %.16llx %s %s %s %s", + _P("200 listnetworks %.16llx %s %s %s %s %s", (unsigned long long)nw->first, + ((nconf) ? nconf->name().c_str() : "?"), Network::statusString(nw->second->status()), ((nconf) ? (nconf->isOpen() ? "public" : "private") : "?"), nw->second->tap().deviceName().c_str(), -- cgit v1.2.3 From 4296db235894f8d403fc656f76e2a3578ca2d597 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 21 Nov 2013 15:11:22 -0500 Subject: Add configuration age to listnetworks results and GUI. --- ZeroTierUI/aboutwindow.cpp | 13 +++++++ ZeroTierUI/aboutwindow.ui | 2 +- ZeroTierUI/mainwindow.cpp | 50 ++++++++++++++----------- ZeroTierUI/mainwindow.h | 4 +- ZeroTierUI/mainwindow.ui | 8 +--- ZeroTierUI/network.cpp | 5 ++- ZeroTierUI/network.h | 2 +- ZeroTierUI/network.ui | 92 +++++++++++++++++++++++++++++++++++----------- node/NodeConfig.cpp | 11 +++++- 9 files changed, 130 insertions(+), 57 deletions(-) (limited to 'node/NodeConfig.cpp') diff --git a/ZeroTierUI/aboutwindow.cpp b/ZeroTierUI/aboutwindow.cpp index 83d680b1..1a2b2290 100644 --- a/ZeroTierUI/aboutwindow.cpp +++ b/ZeroTierUI/aboutwindow.cpp @@ -1,11 +1,17 @@ #include "aboutwindow.h" #include "ui_aboutwindow.h" +#include +#include "../node/Defaults.hpp" + AboutWindow::AboutWindow(QWidget *parent) : QDialog(parent), ui(new Ui::AboutWindow) { ui->setupUi(this); +#ifndef __APPLE__ + ui->uninstallButton->hide(); +#endif } AboutWindow::~AboutWindow() @@ -15,4 +21,11 @@ AboutWindow::~AboutWindow() void AboutWindow::on_uninstallButton_clicked() { + // Apple only... other OSes have more intrinsic mechanisms for uninstalling. + QMessageBox::information( + this, + "Uninstalling ZeroTier One", + QString("Uninstalling ZeroTier One is easy!\n\nJust remove ZeroTier One from your Applications folder and the service will automatically shut down within a few seconds. Then, on your next reboot, all other support files will be automatically deleted.\n\nIf you wish to uninstall the service and support files now, you can run the 'uninstall.sh' script found in ") + ZeroTier::ZT_DEFAULTS.defaultHomePath.c_str() + " using the 'sudo' command in a terminal.", + QMessageBox::Ok, + QMessageBox::NoButton); } diff --git a/ZeroTierUI/aboutwindow.ui b/ZeroTierUI/aboutwindow.ui index 34ad0235..84aab434 100644 --- a/ZeroTierUI/aboutwindow.ui +++ b/ZeroTierUI/aboutwindow.ui @@ -11,7 +11,7 @@ - Dialog + About ZeroTier One diff --git a/ZeroTierUI/mainwindow.cpp b/ZeroTierUI/mainwindow.cpp index e427a6a1..6e972c73 100644 --- a/ZeroTierUI/mainwindow.cpp +++ b/ZeroTierUI/mainwindow.cpp @@ -52,9 +52,10 @@ MainWindow::MainWindow(QWidget *parent) : ui(new Ui::MainWindow) { ui->setupUi(this); - this->startTimer(1000); + this->startTimer(1000); // poll service every second this->setEnabled(false); // gets enabled when updates are received mainWindow = this; + this->cyclesSinceResponseFromService = 0; } MainWindow::~MainWindow() @@ -101,6 +102,11 @@ void MainWindow::timerEvent(QTimerEvent *event) zeroTierClient = new ZeroTier::Node::LocalClient(authToken.c_str(),0,&handleZTMessage,this); } + // TODO: do something more user-friendly here... or maybe try to restart + // the service? + if (++this->cyclesSinceResponseFromService == 3) + QMessageBox::critical(this,"No Response from Service","The ZeroTier One service does not appear to be running.",QMessageBox::Ok,QMessageBox::NoButton); + zeroTierClient->send("info"); zeroTierClient->send("listnetworks"); zeroTierClient->send("listpeers"); @@ -119,9 +125,7 @@ void MainWindow::customEvent(QEvent *event) if (hdr[0] != "200") return; - // Enable main window on valid communication with service - if (!this->isEnabled()) - this->setEnabled(true); + this->cyclesSinceResponseFromService = 0; if (hdr[1] == "info") { if (hdr.size() >= 3) @@ -134,8 +138,8 @@ void MainWindow::customEvent(QEvent *event) std::map< std::string,std::vector > byNwid; for(unsigned long i=1;iztMessage.size();++i) { std::vector l(ZeroTier::Node::LocalClient::splitLine(m->ztMessage[i])); - // 200 listnetworks - if ((l.size() == 8)&&(l[2].length() == 16)) + // 200 listnetworks + if ((l.size() == 9)&&(l[2].length() == 16)) byNwid[l[2]] = l; } @@ -149,10 +153,10 @@ void MainWindow::customEvent(QEvent *event) if (byNwid.count(i->first)) { std::vector &l = byNwid[i->first]; i->second.second->setNetworkName(l[3]); - i->second.second->setStatus(l[4]); - i->second.second->setNetworkType(l[5]); - i->second.second->setNetworkDeviceName(l[6]); - i->second.second->setIps(l[7]); + i->second.second->setStatus(l[4],l[5]); + i->second.second->setNetworkType(l[6]); + i->second.second->setNetworkDeviceName(l[7]); + i->second.second->setIps(l[8]); } else { delete ui->networkListWidget->takeItem(i->second.first); } @@ -163,10 +167,10 @@ void MainWindow::customEvent(QEvent *event) std::vector &l = i->second; Network *nw = new Network((QWidget *)0,i->first); nw->setNetworkName(l[3]); - nw->setStatus(l[4]); - nw->setNetworkType(l[5]); - nw->setNetworkDeviceName(l[6]); - nw->setIps(l[7]); + nw->setStatus(l[4],l[5]); + nw->setNetworkType(l[6]); + nw->setNetworkDeviceName(l[7]); + nw->setIps(l[8]); QListWidgetItem *item = new QListWidgetItem(); item->setSizeHint(nw->sizeHint()); ui->networkListWidget->addItem(item); @@ -186,13 +190,23 @@ void MainWindow::customEvent(QEvent *event) QString st(this->myAddress); st += " ("; st += this->myStatus; + st += ", v"; + st += this->myVersion; st += ", "; st += QString::number(this->numPeers); st += " peers)"; - while (st.size() < 38) + while (st.size() < 45) st += QChar::Space; ui->statusAndAddressButton->setText(st); } + + if (this->myStatus == "ONLINE") { + if (!this->isEnabled()) + this->setEnabled(true); + } else { + if (this->isEnabled()) + this->setEnabled(false); + } } void MainWindow::on_joinNetworkButton_clicked() @@ -217,12 +231,6 @@ void MainWindow::on_actionAbout_triggered() about->show(); } -void MainWindow::on_actionJoin_Network_triggered() -{ - // Does the same thing as clicking join button on main UI - on_joinNetworkButton_clicked(); -} - void MainWindow::on_networkIdLineEdit_textChanged(const QString &text) { QString newText; diff --git a/ZeroTierUI/mainwindow.h b/ZeroTierUI/mainwindow.h index ed11ff44..66a0b350 100644 --- a/ZeroTierUI/mainwindow.h +++ b/ZeroTierUI/mainwindow.h @@ -45,8 +45,7 @@ protected: private slots: void on_joinNetworkButton_clicked(); void on_actionAbout_triggered(); - void on_actionJoin_Network_triggered(); - void on_networkIdLineEdit_textChanged(const QString &arg1); + void on_networkIdLineEdit_textChanged(const QString &text); void on_statusAndAddressButton_clicked(); private: @@ -56,6 +55,7 @@ private: QString myStatus; QString myVersion; unsigned int numPeers; + unsigned int cyclesSinceResponseFromService; }; #endif // MAINWINDOW_H diff --git a/ZeroTierUI/mainwindow.ui b/ZeroTierUI/mainwindow.ui index 025ac6cd..c5103624 100644 --- a/ZeroTierUI/mainwindow.ui +++ b/ZeroTierUI/mainwindow.ui @@ -110,7 +110,7 @@ border: 0; - 0000000000 (OFFLINE, 0 peers) + 0000000000 (OFFLINE, v0.0.0, 0 peers) Qt::ToolButtonTextOnly @@ -203,7 +203,6 @@ File - @@ -215,11 +214,6 @@ About - - - Join Network - - Exit diff --git a/ZeroTierUI/network.cpp b/ZeroTierUI/network.cpp index 1631c816..e23bc6ba 100644 --- a/ZeroTierUI/network.cpp +++ b/ZeroTierUI/network.cpp @@ -28,9 +28,12 @@ Network::~Network() delete ui; } -void Network::setStatus(const std::string &status) +void Network::setStatus(const std::string &status,const std::string &age) { ui->statusLabel->setText(QString(status.c_str())); + if (status == "OK") + ui->ageLabel->setText(QString("(configuration is ") + age.c_str() + " seconds old)"); + else ui->ageLabel->setText(QString()); } void Network::setNetworkName(const std::string &name) diff --git a/ZeroTierUI/network.h b/ZeroTierUI/network.h index a47915e1..a50354af 100644 --- a/ZeroTierUI/network.h +++ b/ZeroTierUI/network.h @@ -17,7 +17,7 @@ public: explicit Network(QWidget *parent = 0,const std::string &nwid = std::string()); virtual ~Network(); - void setStatus(const std::string &status); + void setStatus(const std::string &status,const std::string &age); void setNetworkName(const std::string &name); void setNetworkType(const std::string &type); void setNetworkDeviceName(const std::string &dev); diff --git a/ZeroTierUI/network.ui b/ZeroTierUI/network.ui index 9ea3cb85..e6dc6524 100644 --- a/ZeroTierUI/network.ui +++ b/ZeroTierUI/network.ui @@ -174,28 +174,6 @@ - - - - - 0 - 0 - - - - - 75 - true - - - - ? - - - Qt::PlainText - - - @@ -222,6 +200,76 @@ + + + + + 0 + 0 + + + + + 12 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 75 + true + + + + ? + + + Qt::PlainText + + + + + + + + 0 + 0 + + + + + 10 + + + + (configuration is 0 seconds old) + + + Qt::PlainText + + + + + + diff --git a/node/NodeConfig.cpp b/node/NodeConfig.cpp index d56c73ae..ce5943c5 100644 --- a/node/NodeConfig.cpp +++ b/node/NodeConfig.cpp @@ -200,7 +200,7 @@ std::vector NodeConfig::execute(const char *command) _r->topology->eachPeer(_DumpPeerStatistics(r)); } else if (cmd[0] == "listnetworks") { Mutex::Lock _l(_networks_m); - _P("200 listnetworks "); + _P("200 listnetworks "); for(std::map< uint64_t,SharedPtr >::const_iterator nw(_networks.begin());nw!=_networks.end();++nw) { std::string tmp; std::set ips(nw->second->tap().ips()); @@ -211,10 +211,17 @@ std::vector NodeConfig::execute(const char *command) } SharedPtr nconf(nw->second->config2()); - _P("200 listnetworks %.16llx %s %s %s %s %s", + + long long age = (nconf) ? ((long long)Utils::now() - (long long)nconf->timestamp()) : (long long)0; + if (age < 0) + age = 0; + age /= 1000; + + _P("200 listnetworks %.16llx %s %s %lld %s %s %s", (unsigned long long)nw->first, ((nconf) ? nconf->name().c_str() : "?"), Network::statusString(nw->second->status()), + age, ((nconf) ? (nconf->isOpen() ? "public" : "private") : "?"), nw->second->tap().deviceName().c_str(), ((tmp.length() > 0) ? tmp.c_str() : "-")); -- cgit v1.2.3 From a22a3ed7e8754fbfb2f48e4a32b79d6b7468e25c Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 11 Dec 2013 13:00:18 -0800 Subject: Software update work... --- make-mac.mk | 2 +- node/Node.cpp | 6 ++++++ node/NodeConfig.cpp | 9 +++++++++ node/SoftwareUpdater.hpp | 14 ++++++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) (limited to 'node/NodeConfig.cpp') diff --git a/make-mac.mk b/make-mac.mk index 8b1d121b..9f0d7d8c 100644 --- a/make-mac.mk +++ b/make-mac.mk @@ -2,7 +2,7 @@ CC=clang CXX=clang++ INCLUDES= -DEFS= +DEFS=-DZT_AUTO_UPDATE LIBS=-lm # Uncomment for a release optimized universal binary build diff --git a/node/Node.cpp b/node/Node.cpp index 8c6ab49b..dd0e47ed 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -68,6 +68,7 @@ #include "CMWC4096.hpp" #include "SHA512.hpp" #include "Service.hpp" +#include "SoftwareUpdater.hpp" #ifdef __WINDOWS__ #include @@ -210,6 +211,7 @@ struct _NodeImpl #ifndef __WINDOWS__ delete renv.netconfService; #endif + delete renv.updater; delete renv.nc; delete renv.sysEnv; delete renv.topology; @@ -429,6 +431,10 @@ Node::ReasonForTermination Node::run() return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,foo); } _r->node = this; +#ifdef ZT_AUTO_UPDATE + if (ZT_DEFAULTS.updateLatestNfoURL.length()) + _r->updater = new SoftwareUpdater(_r); +#endif // Bind local port for core I/O if (!_r->demarc->bindLocalUdp(impl->port)) { diff --git a/node/NodeConfig.cpp b/node/NodeConfig.cpp index ce5943c5..770f1f6f 100644 --- a/node/NodeConfig.cpp +++ b/node/NodeConfig.cpp @@ -56,6 +56,7 @@ #include "Poly1305.hpp" #include "SHA512.hpp" #include "Node.hpp" +#include "SoftwareUpdater.hpp" namespace ZeroTier { @@ -184,6 +185,7 @@ std::vector NodeConfig::execute(const char *command) _P("200 help join "); _P("200 help leave "); _P("200 help terminate []"); + _P("200 help updatecheck"); } else if (cmd[0] == "info") { bool isOnline = false; uint64_t now = Utils::now(); @@ -268,6 +270,13 @@ std::vector NodeConfig::execute(const char *command) if (cmd.size() > 1) _r->node->terminate(Node::NODE_NORMAL_TERMINATION,cmd[1].c_str()); else _r->node->terminate(Node::NODE_NORMAL_TERMINATION,(const char *)0); + } else if (cmd[0] == "updatecheck") { + if (_r->updater) { + _P("200 checking for software updates now at: %s",ZT_DEFAULTS.updateLatestNfoURL.c_str()); + _r->updater->checkNow(); + } else { + _P("500 software updates are not enabled"); + } } else { _P("404 %s No such command. Use 'help' for help.",cmd[0].c_str()); } diff --git a/node/SoftwareUpdater.hpp b/node/SoftwareUpdater.hpp index bfcdf395..5e47bbea 100644 --- a/node/SoftwareUpdater.hpp +++ b/node/SoftwareUpdater.hpp @@ -74,12 +74,26 @@ public: } } + /** + * Check for updates now regardless of last check time or version + */ + inline void checkNow() + { + Mutex::Lock _l(_lock); + if (_status == UPDATE_STATUS_IDLE) { + _lastUpdateAttempt = Utils::now(); + _status = UPDATE_STATUS_GETTING_NFO; + HttpClient::GET(ZT_DEFAULTS.updateLatestNfoURL,HttpClient::NO_HEADERS,ZT_UPDATE_HTTP_TIMEOUT,&_cbHandleGetLatestVersionInfo,this); + } + } + /** * Pack three-component version into a 64-bit integer * * @param vmaj Major version (0..65535) * @param vmin Minor version (0..65535) * @param rev Revision (0..65535) + * @return Version packed into an easily comparable 64-bit integer */ static inline uint64_t packVersion(unsigned int vmaj,unsigned int vmin,unsigned int rev) throw() -- cgit v1.2.3