Compare commits

...
78 Commits
Author SHA1 Message Date
Adam Ierymenko dd404b8ba3 VERSION 0.8.0
This version introduces a major new feature requested by several users,
both via the user survey and otherwise: TCP tunneling.

If you are not able to communicate over UDP/9993, ZeroTier One will switch to
TCP connections to ZeroTier's supernodes. This is always slower than UDP, but
will allow you to communicate behind all but the most extremely restrictive
firewalls. This TCP traffic travels over port 443 and looks like HTTPS (SSL)
traffic (though it isn't), since that port is almost always open.

This also fixes several minor bugs and attempts to improve the robustness of
Windows tap driver management. Several users have reported spurious issues
with the Windows tap device, though I was unable to reproduce any of these with
clean VMs. (Tried Windows 7 and 8.1, both x86 and x64. No luck.) But I tried
to beef up the tap code anyway in the hopes of catching it. It now tries a lot
harder to make sure the tap is up and running.

There was some significant under the hood refactoring in support of TCP, so
this was a non-trivial change.

I bumped the version to 0.8 to indicate that more and more features are being
crossed off the list as we approach 1.0 and exit from beta. After this, the next
major feature will be LAN announcement to find direct paths to peers on the
same physical LAN. But assuming that 0.8.0 goes smoothly, I am going to divert
attention to the web site. A new design is coming that is much cleaner, sharper,
and easier to use.

Thank you all for all your excellent feedback! We're well on the way to a killer
product that makes conventional VPNs and other kludges obsolete.
2014-04-08 22:38:51 -07:00
Adam Ierymenko 1c636afe3f Fix typo. 2014-04-08 16:43:36 -07:00
Adam Ierymenko 48a1799f49 More Windows tap cleanup... seems solid. We'll see. 2014-04-08 16:10:48 -07:00
Adam Ierymenko bf24de43fe Windows tap: be REAL REAL REAL PARANOID. Wake up sheeple. 2014-04-08 15:47:33 -07:00
Adam Ierymenko 76d9ea911d Another Qt build fix... need the right tap driver in build just to make symbols work even though UI doesn't use that code. 2014-04-08 14:16:45 -07:00
Adam Ierymenko ff773def26 Remove EthernetTap.cpp from UI build project. 2014-04-08 13:59:31 -07:00
Adam Ierymenko 5abfb11813 Some installer stuff, complete refactoring of Windows side of newly split tap driver. Seems to work. Now to see if the cleanup we did here gets rid of the zombie tap device issue on Windows. 2014-04-08 12:00:21 -07:00
Adam Ierymenko 0b8d6c7f4a Builds and runs on Unix with EthernetTap changes, now for Windows... and for what we did this for: a refactor of the Windows tap connector. 2014-04-07 15:39:33 -07:00
Adam Ierymenko 6c60305a96 Split EthernetTap into subclasses, work in progress... 2014-04-07 14:47:39 -07:00
Adam Ierymenko 19c4d82512 Intaller upgrade and stuff, fix to Windows service for new Node API changes. 2014-04-04 16:59:02 -07:00
Adam Ierymenko e11149bcae Fix network widget spacer issue on Windows. 2014-04-04 12:25:48 -07:00
Adam Ierymenko fe85426df6 A few more tweaks to TCP failover... seems to be switching back and forth pretty well now! 2014-04-03 17:12:34 -07:00
Adam Ierymenko 158002d2d1 Tweak some timings and stuff. 2014-04-03 16:19:41 -07:00
Adam Ierymenko c96d3ebf8c Such ping logic. So edge case. 2014-04-03 14:36:52 -07:00
Adam Ierymenko b1088a6bd7 Make Unix domain sockets mode 0777 so that properly authorized non-privileged users can access them (if they have auth token). 2014-04-02 17:21:26 -07:00
Adam Ierymenko f0223490be Make GUI work with new control client API, make control client look for user authtoken.secret if system unreadable. 2014-04-02 17:12:04 -07:00
Adam Ierymenko 81e5690410 More tweaks to TCP failover logic. Such edge case. 2014-04-02 17:32:47 -04:00
Adam Ierymenko 700a450806 More tweaks to algorithm for determining when to fail over to TCP, and stop supernodes from resynchronizing unless explicitly ordered. 2014-04-01 18:39:10 -07:00
Adam Ierymenko 0e1fc06a6f The remove paths on send fail thing in Peer.cpp was not well thought out, and there is no point in mallocing the TCP write buffer. 2014-04-01 15:55:05 -07:00
Adam Ierymenko c3b41c289d Resynchronize on startup. 2014-04-01 14:12:54 -07:00
Adam Ierymenko 6ab95e0391 Get : out of Path.toString() since this will conflict with : in IPv6 IPs. 2014-04-01 08:52:52 -07:00
Adam Ierymenko 67b3fa9311 Clean up main.o in Linux make clean. 2014-03-31 22:38:46 -07:00
Adam Ierymenko 316e8d1939 Build fix. 2014-03-31 22:30:08 -07:00
Adam Ierymenko f13493edb2 Oops... turns out we need to differentiate incoming from outgoing TCP and indeed learn incoming TCP paths. Otherwise the recipient of a TCP connection does not know to reply via TCP! Heh. 2014-03-31 22:23:55 -07:00
Adam Ierymenko 595b386afc Increase maximum packet fragments to make room for huge multicasts with certificates of membership tagged onto them. This likely will not actually increase the number of fragments in practice much, since these are then subsequently compressed. But the buffer needs to be allocated with room for them, otherwise these packets get dropped with a range_error exception internally. 2014-03-31 14:53:33 -07:00
Adam Ierymenko 8e587ae481 Clean dead paths from peers. 2014-03-31 11:41:14 -07:00
Adam Ierymenko acb056e3b1 Small readability fix. 2014-03-28 21:04:15 -07:00
Adam Ierymenko 5ef2c6fd6f Add TCP/443 to all supernodes in Defaults. 2014-03-28 15:51:19 -07:00
Adam Ierymenko 1a0572d7e7 Remove UDP-breaking debug code. 2014-03-28 13:58:18 -07:00
Adam Ierymenko 7957ab6b1d Windows uses exceptfds to report failed async connect() in select(). TCP now done on Windows (I think). 2014-03-28 13:37:21 -07:00
Adam Ierymenko e8b613e625 TCP connections work on Windows now. 2014-03-28 12:26:33 -07:00
Adam Ierymenko 9c68a343f6 Reduce some TRACE noise. 2014-03-27 18:57:20 -07:00
Adam Ierymenko 881ff08269 Make multiple attempts to open the tap device on Windows. 2014-03-27 18:50:10 -07:00
Adam Ierymenko e3239d23f4 Windows build fix. 2014-03-27 18:39:58 -07:00
Adam Ierymenko f9c92b0351 Build fix from merge. 2014-03-27 18:24:57 -07:00
Adam Ierymenko b73c36acbf Merge branch 'adamierymenko-dev' of ssh://shub-niggurath.zerotier.com:222/git/ZeroTierOne into adamierymenko-dev 2014-03-27 18:23:02 -07:00
Adam Ierymenko 181369964f Make TCP optional, rename port constant. 2014-03-27 18:22:53 -07:00
Adam Ierymenko d2c5d71502 Finally fixed TCP sockets. 2014-03-27 17:42:02 -07:00
Adam Ierymenko c231510f8b More TCP-related fixes and tweaks to ping timing, resynchronize, and startup. 2014-03-27 17:02:52 -07:00
Adam Ierymenko 2ac56fd120 Fix TCP connection accumulation problem, still having issues with TCP tunneling. 2014-03-26 17:59:45 -07:00
Adam Ierymenko e6b23059ac Change the way TCP failover is invoked. 2014-03-26 16:44:58 -07:00
Adam Ierymenko 04169b5150 If I want it to pick the first, actually picking the first is helpful. 2014-03-26 15:44:24 -07:00
Adam Ierymenko daaec84c6b Add TCP channel support for supernode list, make Peer pick the first path if all paths are equally dead. 2014-03-26 15:35:15 -07:00
Adam Ierymenko 73c1d43f2f Crank down default multicast preload and max balance just a little bit... should not impact non-lame protocols. 2014-03-25 21:48:16 -07:00
Adam Ierymenko ab5a460177 Apply multicast rate limits on a network to ourselves and do not send multicasts that would exceed limits, for GitHub issue #55 2014-03-25 21:38:54 -07:00
Adam Ierymenko 67a85221d5 WINDOWS IS SUFFERING 2014-03-25 17:31:03 -07:00
Adam Ierymenko 328be8f846 Make Windows build, add (untested) Windows named pipe based IPC code. 2014-03-25 08:37:08 -07:00
Adam Ierymenko d9b91758e0 Fix command line interface. 2014-03-21 14:58:35 -07:00
Adam Ierymenko 4e26ade2df Fix deadlock in refactored code. 2014-03-21 14:31:10 -07:00
Adam Ierymenko 8d3eb1a258 A few renamings to be consistent. 2014-03-21 14:18:35 -07:00
Adam Ierymenko 33ad3deaee Builds with new Path code. 2014-03-21 13:46:55 -07:00
Adam Ierymenko ba3f04deed Work in progress: refactoring paths, adding TCP fallback. 2014-03-20 20:07:35 -07:00
Adam Ierymenko 45e823d27c Reworking of paths in Peer work-in-progress, and TCP connect support in SocketManager. Also add FD_SETSIZE checking for the default select implementation of sockets. 2014-03-20 18:49:33 -07:00
Adam Ierymenko 70b736f440 Put mac back to release default build flags. 2014-03-20 14:44:13 -07:00
Adam Ierymenko 97e6b38144 MULTICAST_FRAME TRACE improvements. 2014-03-20 14:24:15 -07:00
Adam Ierymenko 7a45ff460d More deadlock fixes in new I/O. 2014-03-20 14:00:05 -07:00
Adam Ierymenko 6f5a4d7e29 Fix blocking socket issues in new socket I/O code. 2014-03-20 13:21:58 -07:00
Adam Ierymenko 4d0ad9abb6 Fix TRACE bug and new UDP socket code issue. 2014-03-19 23:10:34 -07:00
Adam Ierymenko 15e8c18106 Bug fixes. 2014-03-19 22:01:32 -07:00
Adam Ierymenko 1c555e4b96 command bus fix 2014-03-19 16:59:23 -07:00
Adam Ierymenko 6fdb360e2a More IPC work. 2014-03-19 16:05:03 -07:00
Adam Ierymenko 0d847d9410 More build fixes. 2014-03-19 15:29:00 -07:00
Adam Ierymenko abc82d6a52 IPC changes and SocketManager changes all build! 2014-03-19 13:56:48 -07:00
Adam Ierymenko acf7d70d24 Integrate IPC stuff into NodeConfig. 2014-03-19 08:20:09 -07:00
Adam Ierymenko 3be4c38946 IPC stuff for Unix. 2014-03-18 18:44:44 -07:00
Adam Ierymenko 6a1bd52854 New IPC work... 2014-03-18 17:19:32 -07:00
Adam Ierymenko 0b75992737 Everything but the local config bus... blech. 2014-03-18 14:33:57 -07:00
Adam Ierymenko 91fef21973 More ripping out of old condition stuff. 2014-03-18 12:21:22 -07:00
Adam Ierymenko dc0f3559be Rip out old condition and Demarc stuff... 2014-03-18 12:00:15 -07:00
Adam Ierymenko bb25128406 TCP socket. 2014-03-18 11:53:53 -07:00
Adam Ierymenko bf5d8de999 More new socket I/O work... 2014-03-17 16:29:53 -07:00
Adam Ierymenko 1a0a6755b1 UDP socket implementation. 2014-03-17 16:18:44 -07:00
Adam Ierymenko 8adbbe092d Drop old Demarc.cpp code. 2014-03-17 15:15:02 -07:00
Adam Ierymenko bd749e040d Compile fixes. 2014-03-17 15:14:22 -07:00
Adam Ierymenko 7e80d7e551 Bunch of work in progress on new socket multiplexer and plumbing for TCP jailbreaking... Don't try to build, won't yet. 2014-03-17 09:05:43 -07:00
Adam Ierymenko ce09d00679 Security improvements to Linux build flags mirroring OSX improvements. 2014-03-11 11:50:04 -07:00
Adam Ierymenko dbd7a06ea9 Enable PIE to allow ASLR (security) 2014-03-11 10:56:38 -07:00
Adam Ierymenko 74c2e644a9 Change -O4 to -O3 -flto on OSX for new clang (should work with older one too) 2014-03-11 10:18:39 -07:00
60 changed files with 5655 additions and 4042 deletions

No files matched your search

+38 -30
View File
@@ -12,16 +12,20 @@ mac:QMAKE_INFO_PLIST = Info.plist
mac:LIBS += -framework Cocoa
SOURCES += main.cpp \
mainwindow.cpp \
aboutwindow.cpp \
mainwindow.cpp \
aboutwindow.cpp \
networkwidget.cpp \
installdialog.cpp \
licensedialog.cpp \
onetimedialog.cpp \
../node/C25519.cpp \
../node/CertificateOfMembership.cpp \
../node/Defaults.cpp \
../node/Demarc.cpp \
../node/EthernetTap.cpp \
../node/HttpClient.cpp \
../node/Identity.cpp \
../node/InetAddress.cpp \
../node/IpcConnection.cpp \
../node/IpcListener.cpp \
../node/Logger.cpp \
../node/Multicaster.cpp \
../node/Network.cpp \
@@ -35,24 +39,25 @@ SOURCES += main.cpp \
../node/Salsa20.cpp \
../node/Service.cpp \
../node/SHA512.cpp \
../node/SocketManager.cpp \
../node/SoftwareUpdater.cpp \
../node/Switch.cpp \
../node/SysEnv.cpp \
../node/TcpSocket.cpp \
../node/Topology.cpp \
../node/UdpSocket.cpp \
../node/Utils.cpp \
../ext/lz4/lz4.c \
../ext/lz4/lz4hc.c \
networkwidget.cpp \
installdialog.cpp \
licensedialog.cpp \
onetimedialog.cpp
../ext/lz4/lz4hc.c
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/Array.hpp \
../node/AtomicCounter.hpp \
@@ -61,14 +66,14 @@ HEADERS += mainwindow.h \
../node/C25519.hpp \
../node/CertificateOfMembership.hpp \
../node/CMWC4096.hpp \
../node/Condition.hpp \
../node/Constants.hpp \
../node/Demarc.hpp \
../node/Defaults.hpp \
../node/Dictionary.hpp \
../node/EthernetTap.hpp \
../node/HttpClient.hpp \
../node/Identity.hpp \
../node/InetAddress.hpp \
../node/IpcConnection.hpp \
../node/IpcListener.hpp \
../node/Logger.hpp \
../node/MAC.hpp \
../node/Multicaster.hpp \
@@ -76,10 +81,12 @@ HEADERS += mainwindow.h \
../node/Mutex.hpp \
../node/Network.hpp \
../node/NetworkConfig.hpp \
../node/Node.hpp \
../node/NodeConfig.hpp \
../node/NonCopyable.hpp \
../node/Packet.hpp \
../node/PacketDecoder.hpp \
../node/Path.hpp \
../node/Peer.hpp \
../node/Poly1305.hpp \
../node/RuntimeEnvironment.hpp \
@@ -87,28 +94,29 @@ HEADERS += mainwindow.h \
../node/Service.hpp \
../node/SHA512.hpp \
../node/SharedPtr.hpp \
../node/Socket.hpp \
../node/SocketManager.hpp \
../node/SoftwareUpdater.hpp \
../node/Switch.hpp \
../node/SysEnv.hpp \
../node/TcpSocket.hpp \
../node/Thread.hpp \
../node/Topology.hpp \
../node/UdpSocket.hpp \
../node/Utils.hpp \
../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
win32:SOURCES += ../node/WindowsEthernetTap.cpp
mac:SOURCES += ../node/UnixEthernetTap.cpp
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.qrc
@@ -117,4 +125,4 @@ mac:OBJECTIVE_SOURCES += \
mac_doprivileged.mm
OTHER_FILES += \
stylesheet.css
stylesheet.css
+11 -1
View File
@@ -39,7 +39,17 @@ AboutWindow::AboutWindow(QWidget *parent) :
ui(new Ui::AboutWindow)
{
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()
+76 -80
View File
@@ -63,32 +63,32 @@
#endif
// Globally visible
ZeroTier::Node::LocalClient *zeroTierClient = (ZeroTier::Node::LocalClient *)0;
ZeroTier::Node::NodeControlClient *zeroTierClient = (ZeroTier::Node::NodeControlClient *)0;
// Main window instance for app
QMainWindow *mainWindow = (MainWindow *)0;
// 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;
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 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
} else ztReplies_m.unlock();
} else if (line[0]) {
ztReplies.push_back(std::string(line));
}
}
ztReplies_m.unlock();
}
MainWindow::MainWindow(QWidget *parent) :
@@ -136,7 +136,7 @@ MainWindow::~MainWindow()
{
delete ui;
delete zeroTierClient;
zeroTierClient = (ZeroTier::Node::LocalClient *)0;
zeroTierClient = (ZeroTier::Node::NodeControlClient *)0;
mainWindow = (MainWindow *)0;
}
@@ -147,75 +147,72 @@ void MainWindow::timerEvent(QTimerEvent *event) // event can be null since code
if (this->pollServiceTimerId < 0)
return;
// Show quick start dialog on first launch, then reset timer to normal rate
if (this->firstTimerTick) {
this->firstTimerTick = false;
this->killTimer(this->pollServiceTimerId);
if (!settings->value("shown_quickStart",false).toBool()) {
on_actionQuick_Start_triggered();
settings->setValue("shown_quickStart",true);
settings->sync();
}
this->pollServiceTimerId = this->startTimer(1500);
this->pollServiceTimerId = this->startTimer(2000);
}
if (!zeroTierClient) {
std::string authToken;
if (!ZeroTier::Utils::readFile(ZeroTier::Node::LocalClient::authTokenDefaultUserPath().c_str(),authToken)) {
#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);
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());
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());
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__
zeroTierClient = new ZeroTier::Node::LocalClient(authToken.c_str(),0,&handleZTMessage,this);
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;
}
}
if (++this->cyclesSinceResponseFromService >= 3) {
@@ -227,9 +224,11 @@ void MainWindow::timerEvent(QTimerEvent *event) // event can be null since code
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)
@@ -237,15 +236,14 @@ void MainWindow::customEvent(QEvent *event)
ZTMessageEvent *m = (ZTMessageEvent *)event; // only one custom event type so far
if (m->ztMessage.size() == 0)
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)
return;
if (hdr[0] != "200")
return;
this->cyclesSinceResponseFromService = 0;
if (hdr[1] == "info") {
if (hdr.size() >= 3)
this->myAddress = hdr[2].c_str();
@@ -256,7 +254,7 @@ void MainWindow::customEvent(QEvent *event)
} else if (hdr[1] == "listnetworks") {
std::map< std::string,std::vector<std::string> > newNetworks;
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>
if ((l.size() == 9)&&(l[2].length() == 16))
newNetworks[l[2]] = l;
@@ -309,12 +307,10 @@ void MainWindow::customEvent(QEvent *event)
}
} else if (hdr[1] == "listpeers") {
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()) {
ui->noNetworksLabel->setText("You Have Not Joined Any Networks");
@@ -335,7 +331,7 @@ void MainWindow::customEvent(QEvent *event)
st += this->myVersion;
st += ", ";
st += QString::number(this->numPeers);
st += " direct links to peers";
st += " peers";
ui->statusLabel->setText(st);
}
+1 -1
View File
@@ -49,7 +49,7 @@ class MainWindow;
// Globally visible instance of local client for communicating with ZT1
// 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
extern QMainWindow *mainWindow;
-3
View File
@@ -80,9 +80,6 @@ NetworkWidget::~NetworkWidget()
void NetworkWidget::setStatus(const std::string &status,const std::string &age)
{
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)
+47 -95
View File
@@ -178,12 +178,6 @@
</item>
<item>
<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">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
@@ -232,6 +226,12 @@
</item>
<item row="2" column="1">
<widget class="QLabel" name="networkTypeLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
@@ -265,6 +265,32 @@
</property>
</widget>
</item>
<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">
<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 row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="font">
@@ -280,101 +306,14 @@
</property>
</widget>
</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">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</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>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="deviceLabel">
<property name="font">
<font>
<pointsize>12</pointsize>
@@ -396,6 +335,19 @@
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
+9 -11
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DOCUMENT Type="Advanced Installer" CreateVersion="10.9" version="10.9.1" Modules="professional" RootPath="." Language="en" Id="{DC564647-6BF0-4550-87F4-89C938D0159C}">
<DOCUMENT Type="Advanced Installer" CreateVersion="10.9" version="11.0" Modules="professional" RootPath="." Language="en" Id="{DC564647-6BF0-4550-87F4-89C938D0159C}">
<COMPONENT cid="caphyon.advinst.msicomp.ProjectOptionsComponent">
<ROW Name="HiddenItems" Value="UpdaterComponent;SerValComponent;PreReqComponent;MsiMergeModsComponent;MsiRegsComponent;MsiExtComponent;MsiAssemblyComponent;ActSyncAppComponent;MsiThemeComponent;BackgroundImagesComponent;DictionaryComponent;MsiEnvComponent;CPLAppletComponent;MsiClassComponent;WebApplicationsComponent;MsiOdbcDataSrcComponent;MsiAppSearchComponent"/>
</COMPONENT>
@@ -9,6 +9,7 @@
<ROW Property="AI_PRODUCTNAME_ARP" Value="ZeroTier One"/>
<ROW Property="AI_UNINSTALLER" Value="msiexec.exe"/>
<ROW Property="ALLUSERS" Value="1"/>
<ROW Property="ARPCOMMENTS" Value="This installer database contains the logic and data required to install [|ProductName]."/>
<ROW Property="ARPCONTACT" Value="contact@zerotier.com"/>
<ROW Property="ARPNOMODIFY" MultiBuildValue="DefaultBuild:1"/>
<ROW Property="ARPNOREPAIR" Value="1"/>
@@ -19,10 +20,10 @@
<ROW Property="CTRLS" Value="2"/>
<ROW Property="MSIFASTINSTALL" MultiBuildValue="DefaultBuild:2"/>
<ROW Property="Manufacturer" Value="ZeroTier Networks LLC"/>
<ROW Property="ProductCode" Value="1033:{BD9C5F66-3A4F-4C4E-8799-D976A8DB81E5} " Type="16"/>
<ROW Property="ProductCode" Value="1033:{AA711430-ADF1-44ED-9561-6D32F005009C} " Type="16"/>
<ROW Property="ProductLanguage" Value="1033"/>
<ROW Property="ProductName" Value="ZeroTier One"/>
<ROW Property="ProductVersion" Value="0.7.2" Type="32"/>
<ROW Property="ProductVersion" Value="0.8.0" Type="32"/>
<ROW Property="REBOOT" MultiBuildValue="DefaultBuild:ReallySuppress"/>
<ROW Property="RUNAPPLICATION" Value="1" Type="4"/>
<ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND"/>
@@ -99,7 +100,7 @@
<ROW Path="&lt;AI_DICTS&gt;ui_en.ail"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.DigCertStoreComponent">
<ROW TimeStampUrl="http://timestamp.digicert.com" SignerDescription="ZeroTier One" SignOptions="7" SignTool="0" Thumbprint="5809bb3255b4f32dd93619c1cf26a7df6c282a89 Subject: ZeroTier Networks LLC&#10;Issuer: DigiCert High Assurance Code Signing CA-1&#10;Valid from 12/23/2013 to 02/02/2015"/>
<ROW TimeStampUrl="http://timestamp.verisign.com/scripts/timstamp.dll" SignerDescription="ZeroTier One" SignOptions="7" SignTool="0" Thumbprint="5809bb3255b4f32dd93619c1cf26a7df6c282a89 Subject: ZeroTier Networks LLC&#10;Issuer: DigiCert High Assurance Code Signing CA-1&#10;Valid from 12/23/2013 to 02/02/2015"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.FragmentComponent">
<ROW Fragment="CommonUI.aip" Path="&lt;AI_FRAGS&gt;CommonUI.aip"/>
@@ -183,7 +184,6 @@
<ROW Action="AI_RESTORE_LOCATION" Type="65" Source="aicustact.dll" Target="RestoreLocation"/>
<ROW Action="AI_RemoveExternalUIStub" Type="1" Source="ExternalUICleaner.dll" Target="RemoveExternalUIStub"/>
<ROW Action="AI_ResolveKnownFolders" Type="1" Source="aicustact.dll" Target="AI_ResolveKnownFolders"/>
<ROW Action="AI_ResolveLocalizedCredentials" Type="1" Source="aicustact.dll" Target="GetLocalizedCredentials"/>
<ROW Action="AI_SHOW_LOG" Type="65" Source="aicustact.dll" Target="LaunchLogFile" WithoutSeq="true"/>
<ROW Action="AI_STORE_LOCATION" Type="51" Source="ARPINSTALLLOCATION" Target="[APPDIR]"/>
<ROW Action="AI_XmlCommit" Type="11777" Source="xmlCfg.dll" Target="OnXmlCommit" WithoutSeq="true"/>
@@ -209,8 +209,7 @@
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=&quot;&quot;" Sequence="749"/>
<ROW Action="AI_STORE_LOCATION" Condition="(Not Installed) OR REINSTALL" Sequence="1504"/>
<ROW Action="AI_PREPARE_UPGRADE" Condition="AI_UPGRADE=&quot;No&quot; AND (Not Installed)" Sequence="1399"/>
<ROW Action="AI_ResolveKnownFolders" Sequence="53"/>
<ROW Action="AI_ResolveLocalizedCredentials" Sequence="52"/>
<ROW Action="AI_ResolveKnownFolders" Sequence="52"/>
<ROW Action="AI_PrepareShortcutFlags" Condition="(VersionNT &gt; 501) AND ((NOT Installed) OR (Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;)))" Sequence="4501"/>
<ROW Action="AI_XmlInstall" Condition="(REMOVE &lt;&gt; &quot;ALL&quot;)" Sequence="5102"/>
<ROW Action="AI_DATA_SETTER" Condition="(REMOVE &lt;&gt; &quot;ALL&quot;)" Sequence="5101"/>
@@ -228,8 +227,7 @@
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=&quot;&quot;" Sequence="749"/>
<ROW Action="AI_ResolveKnownFolders" Sequence="53"/>
<ROW Action="AI_ResolveLocalizedCredentials" Sequence="52"/>
<ROW Action="AI_ResolveKnownFolders" Sequence="52"/>
<ROW Action="AI_DpiContentScale" Sequence="51"/>
<ROW Action="AI_BACKUP_AI_SETUPEXEPATH" Sequence="99"/>
<ROW Action="AI_RESTORE_AI_SETUPEXEPATH" Condition="AI_SETUPEXEPATH_ORIGINAL" Sequence="101"/>
@@ -293,10 +291,10 @@
<ROW XmlAttribute="xsischemaLocation" XmlElement="swidsoftware_identification_tag" Name="xsi:schemaLocation" Flags="14" Order="3" Value="http://standards.iso.org/iso/19770/-2/2008/schema.xsd software_identification_tag.xsd"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.XmlElementComponent">
<ROW XmlElement="swidbuild" ParentElement="swidnumeric" Name="swid:build" Order="2" Flags="14" Text="2"/>
<ROW XmlElement="swidbuild" ParentElement="swidnumeric" Name="swid:build" Order="2" Flags="14" Text="0"/>
<ROW XmlElement="swidentitlement_required_indicator" ParentElement="swidsoftware_identification_tag" Name="swid:entitlement_required_indicator" Order="0" Flags="14" Text="false"/>
<ROW XmlElement="swidmajor" ParentElement="swidnumeric" Name="swid:major" Order="0" Flags="14" Text="0"/>
<ROW XmlElement="swidminor" ParentElement="swidnumeric" Name="swid:minor" Order="1" Flags="14" Text="7"/>
<ROW XmlElement="swidminor" ParentElement="swidnumeric" Name="swid:minor" Order="1" Flags="14" Text="8"/>
<ROW XmlElement="swidname" ParentElement="swidproduct_version" Name="swid:name" Order="0" Flags="14" Text="[ProductVersion]"/>
<ROW XmlElement="swidname_1" ParentElement="swidsoftware_creator" Name="swid:name" Order="0" Flags="14" Text="ZeroTier Networks LLC"/>
<ROW XmlElement="swidname_2" ParentElement="swidsoftware_licensor" Name="swid:name" Order="0" Flags="14" Text="ZeroTier Networks LLC"/>
+79 -124
View File
@@ -59,9 +59,9 @@
#include "node/Defaults.hpp"
#include "node/Utils.hpp"
#include "node/Node.hpp"
#include "node/Condition.hpp"
#include "node/C25519.hpp"
#include "node/Identity.hpp"
#include "node/Thread.hpp"
using namespace ZeroTier;
@@ -93,13 +93,13 @@ static void printHelp(const char *cn,FILE *out)
fprintf(out,"Available switches:"ZT_EOL_S);
fprintf(out," -h - Display this help"ZT_EOL_S);
fprintf(out," -v - Show version"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);
fprintf(out," -p<port> - Port for UDP (default: 9993)"ZT_EOL_S);
fprintf(out," -t<port> - Port for TCP (default: disabled)"ZT_EOL_S);
#ifdef __UNIX_LIKE__
fprintf(out," -d - Fork and run as daemon (Unix-ish OSes)"ZT_EOL_S);
#endif
fprintf(out," -q - Send a query to a running service (zerotier-cli)"ZT_EOL_S);
fprintf(out," -i - Run idtool command (zerotier-idtool)"ZT_EOL_S);
fprintf(out," -i - Generate and manage identities (zerotier-idtool)"ZT_EOL_S);
#ifdef __WINDOWS__
fprintf(out," -C - Run from command line instead of as service (Windows)"ZT_EOL_S);
fprintf(out," -I - Install Windows service (Windows)"ZT_EOL_S);
@@ -110,111 +110,68 @@ static void printHelp(const char *cn,FILE *out)
namespace ZeroTierCLI { // ---------------------------------------------------
static void printHelp(FILE *out,const char *exename)
static void printHelp(FILE *out,const char *cn)
{
fprintf(out,"Usage: %s [-switches] <command>"ZT_EOL_S,exename);
fprintf(out,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);
fprintf(out,"Usage: %s <command> (use 'help' for help)"ZT_EOL_S,cn);
}
static volatile unsigned int numResults = 0;
static Condition doneCondition;
static void resultHandler(void *arg,unsigned long id,const char *line)
static void _CBresultHandler(void *arg,const char *line)
{
++numResults;
if (strlen(line))
fprintf(stdout,"%s"ZT_EOL_S,line);
else doneCondition.signal();
if (line) {
if ((line[0] == '.')&&(line[1] == (char)0))
*((bool *)arg) = true;
else fprintf(stdout,"%s"ZT_EOL_S,line);
}
}
// Runs instead of rest of main() if process is called zerotier-cli or if
// -q is specified as an option.
#ifdef __WINDOWS__
static int main(int argc,_TCHAR* argv[])
#else
static int main(int argc,char **argv)
#endif
{
if (argc <= 1) {
if (argc < 2) {
printHelp(stdout,argv[0]);
return -1;
return 1;
}
std::string authToken;
std::string command;
bool pastSwitches = false;
unsigned int controlPort = 0;
const char *hp = (const char *)0;
std::string query;
for(int i=1;i<argc;++i) {
if ((argv[i][0] == '-')&&(!pastSwitches)) {
if (strlen(argv[i]) <= 1) {
printHelp(stdout,argv[0]);
return -1;
}
if (argv[i][0] == '-') {
switch(argv[i][1]) {
case 'q': // does nothing, for invocation without binary path name aliasing
if (argv[i][2]) {
printHelp(argv[0],stderr);
return 0;
}
break;
case 'c':
controlPort = Utils::strToUInt(argv[i] + 2);
break;
case 't':
authToken.assign(argv[i] + 2);
break;
case 'T':
if (!Utils::readFile(argv[i] + 2,authToken)) {
fprintf(stdout,"FATAL ERROR: unable to read token from '%s'"ZT_EOL_S,argv[i] + 2);
return -2;
}
case 'q': // ignore -q since it's used to invoke this
break;
case 'h':
printHelp(stdout,argv[0]);
return 0;
default:
return -1;
printHelp(stdout,argv[0]);
return 1;
}
} else {
pastSwitches = true;
if (command.length())
command.push_back(' ');
command.append(argv[i]);
if (query.length())
query.push_back(' ');
query.append(argv[i]);
}
}
if (!command.length()) {
if (!query.length()) {
printHelp(stdout,argv[0]);
return -1;
return 1;
}
if (!authToken.length()) {
if (!Utils::readFile(Node::LocalClient::authTokenDefaultUserPath().c_str(),authToken)) {
if (!Utils::readFile(Node::LocalClient::authTokenDefaultSystemPath().c_str(),authToken)) {
fprintf(stdout,"FATAL ERROR: no token specified on command line and could not read '%s' or '%s'"ZT_EOL_S,Node::LocalClient::authTokenDefaultSystemPath().c_str(),Node::LocalClient::authTokenDefaultUserPath().c_str());
return -2;
}
try {
volatile bool done = false;
Node::NodeControlClient client(hp,&_CBresultHandler,(void *)&done);
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;
}
}
if (!authToken.length()) {
fprintf(stdout,"FATAL ERROR: could not find auth token"ZT_EOL_S);
return -2;
}
Node::LocalClient client(authToken.c_str(),controlPort,&resultHandler,(void *)0);
client.send(command.c_str());
doneCondition.wait(1000);
if (!numResults) {
fprintf(stdout,"ERROR: no results received. Is ZeroTier One running?"ZT_EOL_S);
return -1;
client.send(query.c_str());
while (!done)
Thread::sleep(100); // ghetto
} catch ( ... ) {
fprintf(stderr,"%s: fatal error: unable to connect (is ZeroTier One running?)"ZT_EOL_S,argv[0]);
return 1;
}
return 0;
@@ -250,8 +207,6 @@ static Identity getIdFromArg(char *arg)
return Identity();
}
// Runs instead of rest of main() if process is called zerotier-idtool or if
// -i is specified as an option.
#ifdef __WINDOWS__
static int main(int argc,_TCHAR* argv[])
#else
@@ -259,8 +214,8 @@ static int main(int argc,char **argv)
#endif
{
if (argc < 2) {
printHelp(stderr,argv[0]);
return -1;
printHelp(stdout,argv[0]);
return 1;
}
if (!strcmp(argv[1],"generate")) {
@@ -270,85 +225,85 @@ static int main(int argc,char **argv)
if (argc >= 3) {
if (!Utils::writeFile(argv[2],idser)) {
fprintf(stderr,"Error writing to %s"ZT_EOL_S,argv[2]);
return -1;
return 1;
} else printf("%s written"ZT_EOL_S,argv[2]);
if (argc >= 4) {
idser = id.toString(false);
if (!Utils::writeFile(argv[3],idser)) {
fprintf(stderr,"Error writing to %s"ZT_EOL_S,argv[3]);
return -1;
return 1;
} else printf("%s written"ZT_EOL_S,argv[3]);
}
} else printf("%s",idser.c_str());
} else if (!strcmp(argv[1],"validate")) {
if (argc < 3) {
printHelp(stderr,argv[0]);
return -1;
printHelp(stdout,argv[0]);
return 1;
}
Identity id = getIdFromArg(argv[2]);
if (!id) {
fprintf(stderr,"Identity argument invalid or file unreadable: %s"ZT_EOL_S,argv[2]);
return -1;
return 1;
}
if (!id.locallyValidate()) {
fprintf(stderr,"%s FAILED validation."ZT_EOL_S,argv[2]);
return -1;
return 1;
} else printf("%s is a valid identity"ZT_EOL_S,argv[2]);
} else if (!strcmp(argv[1],"getpublic")) {
if (argc < 3) {
printHelp(stderr,argv[0]);
return -1;
printHelp(stdout,argv[0]);
return 1;
}
Identity id = getIdFromArg(argv[2]);
if (!id) {
fprintf(stderr,"Identity argument invalid or file unreadable: %s"ZT_EOL_S,argv[2]);
return -1;
return 1;
}
printf("%s",id.toString(false).c_str());
} else if (!strcmp(argv[1],"sign")) {
if (argc < 4) {
printHelp(stderr,argv[0]);
return -1;
printHelp(stdout,argv[0]);
return 1;
}
Identity id = getIdFromArg(argv[2]);
if (!id) {
fprintf(stderr,"Identity argument invalid or file unreadable: %s"ZT_EOL_S,argv[2]);
return -1;
return 1;
}
if (!id.hasPrivate()) {
fprintf(stderr,"%s does not contain a private key (must use private to sign)"ZT_EOL_S,argv[2]);
return -1;
return 1;
}
std::string inf;
if (!Utils::readFile(argv[3],inf)) {
fprintf(stderr,"%s is not readable"ZT_EOL_S,argv[3]);
return -1;
return 1;
}
C25519::Signature signature = id.sign(inf.data(),(unsigned int)inf.length());
printf("%s",Utils::hex(signature.data,(unsigned int)signature.size()).c_str());
} else if (!strcmp(argv[1],"verify")) {
if (argc < 4) {
printHelp(stderr,argv[0]);
return -1;
printHelp(stdout,argv[0]);
return 1;
}
Identity id = getIdFromArg(argv[2]);
if (!id) {
fprintf(stderr,"Identity argument invalid or file unreadable: %s"ZT_EOL_S,argv[2]);
return -1;
return 1;
}
std::string inf;
if (!Utils::readFile(argv[3],inf)) {
fprintf(stderr,"%s is not readable"ZT_EOL_S,argv[3]);
return -1;
return 1;
}
std::string signature(Utils::unhex(argv[4]));
@@ -356,17 +311,16 @@ static int main(int argc,char **argv)
printf("%s signature valid"ZT_EOL_S,argv[3]);
} else {
fprintf(stderr,"%s signature check FAILED"ZT_EOL_S,argv[3]);
return -1;
return 1;
}
} else {
printHelp(stderr,argv[0]);
return -1;
printHelp(stdout,argv[0]);
return 1;
}
return 0;
}
} // namespace ZeroTierIdTool ------------------------------------------------
#ifdef __UNIX_LIKE__
@@ -521,8 +475,8 @@ int main(int argc,char **argv)
return ZeroTierIdTool::main(argc,argv);
const char *homeDir = (const char *)0;
unsigned int port = 0;
unsigned int controlPort = 0;
unsigned int udpPort = ZT_DEFAULT_UDP_PORT;
unsigned int tcpPort = 0;
#ifdef __UNIX_LIKE__
bool runAsDaemon = false;
#endif
@@ -533,9 +487,16 @@ int main(int argc,char **argv)
if (argv[i][0] == '-') {
switch(argv[i][1]) {
case 'p':
port = Utils::strToUInt(argv[i] + 2);
if (port > 65535) {
printHelp(argv[0],stderr);
udpPort = Utils::strToUInt(argv[i] + 2);
if (udpPort > 65535) {
printHelp(argv[0],stdout);
return 1;
}
break;
case 't':
tcpPort = Utils::strToUInt(argv[i] + 2);
if (tcpPort > 65535) {
printHelp(argv[0],stdout);
return 1;
}
break;
@@ -547,21 +508,14 @@ int main(int argc,char **argv)
case 'v':
printf("%s"ZT_EOL_S,Node::versionString());
return 0;
case 'c':
controlPort = Utils::strToUInt(argv[i] + 2);
if (controlPort > 65535) {
printHelp(argv[0],stderr);
return 1;
}
break;
case 'q':
if (argv[i][2]) {
printHelp(argv[0],stderr);
printHelp(argv[0],stdout);
return 0;
} else return ZeroTierCLI::main(argc,argv);
case 'i':
if (argv[i][2]) {
printHelp(argv[0],stderr);
printHelp(argv[0],stdout);
return 0;
} else return ZeroTierIdTool::main(argc,argv);
#ifdef __WINDOWS__
@@ -613,12 +567,12 @@ int main(int argc,char **argv)
case 'h':
case '?':
default:
printHelp(argv[0],stderr);
printHelp(argv[0],stdout);
return 0;
}
} else {
if (homeDir) {
printHelp(argv[0],stderr);
printHelp(argv[0],stdout);
return 0;
}
homeDir = argv[i];
@@ -680,8 +634,9 @@ int main(int argc,char **argv)
#endif
int exitCode = 0;
bool needsReset = false;
try {
node = new Node(homeDir,port,controlPort);
node = new Node(homeDir,udpPort,tcpPort,needsReset);
switch(node->run()) {
#ifdef __WINDOWS__
case Node::NODE_RESTART_FOR_UPGRADE: {
+10 -11
View File
@@ -18,15 +18,18 @@ endif
#DEFS+=-DZT_TRACE -DZT_LOG_STDOUT
# Uncomment for a release optimized build
CFLAGS=-Wall -O3 -fvisibility=hidden -fstack-protector -pthread $(INCLUDES) -DNDEBUG $(DEFS)
CFLAGS=-Wall -O3 -fPIE -fvisibility=hidden -fstack-protector -pthread $(INCLUDES) -DNDEBUG $(DEFS)
LDFLAGS=-pie -Wl,-z,relro,-z,now
STRIP=strip --strip-all
# Uncomment for a debug build
#CFLAGS=-Wall -g -pthread $(INCLUDES) -DZT_TRACE $(DEFS)
#CFLAGS=-Wall -g -pthread $(INCLUDES) -DZT_TRACE -DZT_LOG_STDOUT $(DEFS)
#LDFLAGS=
#STRIP=echo
# Uncomment for gprof profile build
#CFLAGS=-Wall -g -pg -pthread $(INCLUDES) $(DEFS)
#LDFLAGS=
#STRIP=echo
CXXFLAGS=$(CFLAGS) -fno-rtti
@@ -35,25 +38,21 @@ include objects.mk
all: one
one: $(OBJS)
$(CXX) $(CXXFLAGS) -o zerotier-one main.cpp $(OBJS) $(LIBS)
one: $(OBJS) main.o
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-one main.o $(OBJS) $(LIBS)
$(STRIP) zerotier-one
ln -sf zerotier-one zerotier-cli
ln -sf zerotier-one zerotier-idtool
selftest: $(OBJS)
$(CXX) $(CXXFLAGS) -o zerotier-selftest selftest.cpp $(OBJS) $(LIBS)
selftest: $(OBJS) selftest.o
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LIBS)
$(STRIP) zerotier-selftest
idtool: $(OBJS)
$(CXX) $(CXXFLAGS) -o zerotier-idtool idtool.cpp $(OBJS) $(LIBS)
$(STRIP) zerotier-idtool
installer: one FORCE
./buildinstaller.sh
clean:
rm -rf $(OBJS) zerotier-* build-* ZeroTierOneInstaller-*
rm -rf $(OBJS) *.o node/*.o zerotier-* build-* ZeroTierOneInstaller-*
official: FORCE
make -j 4 ZT_OFFICIAL_RELEASE=1
+1 -1
View File
@@ -23,7 +23,7 @@ endif
#DEFS+=-DZT_TRACE -DZT_LOG_STDOUT
# Uncomment for a release optimized universal binary build
CFLAGS=-arch i386 -arch x86_64 -Wall -O4 -fstack-protector -pthread -mmacosx-version-min=10.6 -DNDEBUG -Wno-unused-private-field $(INCLUDES) $(DEFS)
CFLAGS=-arch i386 -arch x86_64 -Wall -O3 -flto -fPIE -fvectorize -fstack-protector -pthread -mmacosx-version-min=10.6 -DNDEBUG -Wno-unused-private-field $(INCLUDES) $(DEFS)
STRIP=strip
# Uncomment for a debug build
-141
View File
@@ -1,141 +0,0 @@
/*
* ZeroTier One - Global Peer to Peer Ethernet
* Copyright (C) 2011-2014 ZeroTier Networks LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* ZeroTier may be used and distributed under the terms of the GPLv3, which
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form, please contact ZeroTier Networks
* LLC. Start here: http://www.zerotier.com/
*/
#ifndef ZT_CONDITION_HPP
#define ZT_CONDITION_HPP
#include "Constants.hpp"
#include "NonCopyable.hpp"
#ifdef __WINDOWS__
#include <Windows.h>
#include <stdlib.h>
#include "Utils.hpp"
namespace ZeroTier {
class Condition : NonCopyable
{
public:
Condition()
throw()
{
_sem = CreateSemaphore(NULL,0,1,NULL);
}
~Condition()
{
CloseHandle(_sem);
}
inline void wait() const
throw()
{
WaitForSingleObject(_sem,INFINITE);
}
inline void wait(unsigned long ms) const
throw()
{
WaitForSingleObject(_sem,(DWORD)ms);
}
inline void signal() const
throw()
{
ReleaseSemaphore(_sem,1,NULL);
}
private:
HANDLE _sem;
};
} // namespace ZeroTier
#else // !__WINDOWS__
#include <time.h>
#include <stdlib.h>
#include <pthread.h>
#include "Utils.hpp"
namespace ZeroTier {
class Condition : NonCopyable
{
public:
Condition()
throw()
{
pthread_mutex_init(&_mh,(const pthread_mutexattr_t *)0);
pthread_cond_init(&_cond,(const pthread_condattr_t *)0);
}
~Condition()
{
pthread_cond_destroy(&_cond);
pthread_mutex_destroy(&_mh);
}
inline void wait() const
throw()
{
pthread_mutex_lock(const_cast <pthread_mutex_t *>(&_mh));
pthread_cond_wait(const_cast <pthread_cond_t *>(&_cond),const_cast <pthread_mutex_t *>(&_mh));
pthread_mutex_unlock(const_cast <pthread_mutex_t *>(&_mh));
}
inline void wait(unsigned long ms) const
throw()
{
uint64_t when = Utils::now() + (uint64_t)ms;
struct timespec ts;
ts.tv_sec = (unsigned long)(when / 1000);
ts.tv_nsec = (unsigned long)(when % 1000) * 1000000;
pthread_mutex_lock(const_cast <pthread_mutex_t *>(&_mh));
pthread_cond_timedwait(const_cast <pthread_cond_t *>(&_cond),const_cast <pthread_mutex_t *>(&_mh),&ts);
pthread_mutex_unlock(const_cast <pthread_mutex_t *>(&_mh));
}
inline void signal() const
throw()
{
pthread_cond_signal(const_cast <pthread_cond_t *>(&_cond));
}
private:
pthread_cond_t _cond;
pthread_mutex_t _mh;
};
} // namespace ZeroTier
#endif // !__WINDOWS__
#endif
+26 -11
View File
@@ -114,15 +114,10 @@ error_no_byte_order_defined;
#define ZT_ADDRESS_RESERVED_PREFIX 0xff
/**
* Default local UDP port
* Default local port for ZeroTier UDP traffic
*/
#define ZT_DEFAULT_UDP_PORT 9993
/**
* Local control port, also used for multiple invocation check
*/
#define ZT_DEFAULT_CONTROL_UDP_PORT 39393
/**
* Default payload MTU for UDP packets
*
@@ -163,7 +158,7 @@ error_no_byte_order_defined;
* The actual spec allows 16, but this is the most we'll support right
* now. Packets with more than this many fragments are dropped.
*/
#define ZT_MAX_PACKET_FRAGMENTS 3
#define ZT_MAX_PACKET_FRAGMENTS 4
/**
* Timeout for receipt of fragmented packets in ms
@@ -268,7 +263,7 @@ error_no_byte_order_defined;
#define ZT_NETWORK_FINGERPRINT_CHECK_DELAY 5000
/**
* Delay between pings (actually HELLOs) to direct links
* Delay between ordinary case pings of direct links
*/
#define ZT_PEER_DIRECT_PING_DELAY 120000
@@ -278,7 +273,7 @@ error_no_byte_order_defined;
* This should be lower than the UDP conversation entry timeout in most
* stateful firewalls.
*/
#define ZT_FIREWALL_OPENER_DELAY 50000
#define ZT_FIREWALL_OPENER_DELAY 30000
/**
* Delay between requests for updated network autoconf information
@@ -295,14 +290,34 @@ error_no_byte_order_defined;
*
* This is the shortest of the check delays/periods.
*/
#define ZT_MIN_SERVICE_LOOP_INTERVAL ZT_NETWORK_FINGERPRINT_CHECK_DELAY
#define ZT_MIN_SERVICE_LOOP_INTERVAL 5000
/**
* Activity timeout for links
*
* A link that hasn't spoken in this long is simply considered inactive.
*/
#define ZT_PEER_LINK_ACTIVITY_TIMEOUT ((ZT_PEER_DIRECT_PING_DELAY * 2) + 1000)
#define ZT_PEER_PATH_ACTIVITY_TIMEOUT ((ZT_PEER_DIRECT_PING_DELAY * 2) + 10000)
/**
* Close TCP tunnels if unused for this long
*/
#define ZT_TCP_TUNNEL_ACTIVITY_TIMEOUT (ZT_PEER_PATH_ACTIVITY_TIMEOUT + 10000)
/**
* Try TCP tunnels if nothing received for this long
*/
#define ZT_TCP_TUNNEL_FAILOVER_TIMEOUT 5000
/**
* Try to ping supernodes this often until we get something from somewhere
*/
#define ZT_STARTUP_AGGRO 5000
/**
* Time since a ping was sent to be considered unanswered
*/
#define ZT_PING_UNANSWERED_AFTER 2500
/**
* Stop relaying via peers that have not responded to direct sends in this long
+13 -8
View File
@@ -43,11 +43,11 @@ namespace ZeroTier {
const Defaults ZT_DEFAULTS;
static inline std::map< Identity,std::vector<InetAddress> > _mkSupernodeMap()
static inline std::map< Identity,std::vector< std::pair<InetAddress,bool> > > _mkSupernodeMap()
{
std::map< Identity,std::vector<InetAddress> > sn;
std::map< Identity,std::vector< std::pair<InetAddress,bool> > > sn;
Identity id;
std::vector<InetAddress> addrs;
std::vector< std::pair<InetAddress,bool> > addrs;
// Nothing special about a supernode... except that they are
// designated as such and trusted to provide WHOIS lookup.
@@ -56,35 +56,40 @@ static inline std::map< Identity,std::vector<InetAddress> > _mkSupernodeMap()
addrs.clear();
if (!id.fromString("8acf059fe3:0:482f6ee5dfe902319b419de5bdc765209c0ecda38c4d6e4fcf0d33658398b4527dcd22f93112fb9befd02fd78bf7261b333fc105d192a623ca9e50fc60b374a5"))
throw std::runtime_error("invalid identity in Defaults");
addrs.push_back(InetAddress("162.243.77.111",ZT_DEFAULT_UDP_PORT));
addrs.push_back(std::pair<InetAddress,bool>(InetAddress("162.243.77.111",ZT_DEFAULT_UDP_PORT),false));
addrs.push_back(std::pair<InetAddress,bool>(InetAddress("162.243.77.111",443),true));
sn[id] = addrs;
// nyarlathotep.zerotier.com - San Francisco, California, USA
addrs.clear();
if (!id.fromString("7e19876aba:0:2a6e2b2318930f60eb097f70d0f4b028b2cd6d3d0c63c014b9039ff35390e41181f216fb2e6fa8d95c1ee9667156411905c3dccfea78d8c6dfafba688170b3fa"))
throw std::runtime_error("invalid identity in Defaults");
addrs.push_back(InetAddress("198.199.97.220",ZT_DEFAULT_UDP_PORT));
addrs.push_back(std::pair<InetAddress,bool>(InetAddress("198.199.97.220",ZT_DEFAULT_UDP_PORT),false));
addrs.push_back(std::pair<InetAddress,bool>(InetAddress("198.199.97.220",443),true));
sn[id] = addrs;
// shub-niggurath.zerotier.com - Amsterdam, Netherlands
addrs.clear();
if (!id.fromString("36f63d6574:0:67a776487a1a99b32f413329f2b67c43fbf6152e42c6b66e89043e69d93e48314c7d709b58a83016bd2612dd89400b856e18c553da94892f7d3ca16bf2c92c24"))
throw std::runtime_error("invalid identity in Defaults");
addrs.push_back(InetAddress("198.211.127.172",ZT_DEFAULT_UDP_PORT));
addrs.push_back(std::pair<InetAddress,bool>(InetAddress("198.211.127.172",ZT_DEFAULT_UDP_PORT),false));
addrs.push_back(std::pair<InetAddress,bool>(InetAddress("198.211.127.172",443),true));
sn[id] = addrs;
// mi-go.zerotier.com - Singapore
addrs.clear();
if (!id.fromString("abbb7f4622:0:89d2c6b2062b10f4ce314dfcb914c082566247090a6f74c8ba1c15c63b205f540758f0abae85287397152c9d8cf463cfe51e7a480946cd6a31495b24ca13253c"))
throw std::runtime_error("invalid identity in Defaults");
addrs.push_back(InetAddress("128.199.254.204",ZT_DEFAULT_UDP_PORT));
addrs.push_back(std::pair<InetAddress,bool>(InetAddress("128.199.254.204",ZT_DEFAULT_UDP_PORT),false));
addrs.push_back(std::pair<InetAddress,bool>(InetAddress("128.199.254.204",443),true));
sn[id] = addrs;
// shoggoth.zerotier.com - Tokyo, Japan
addrs.clear();
if (!id.fromString("48e8f875cb:0:5ca54f55e1094f65589f3e6d74158b6964d418ddac3570757128f1c6a2498322d92fcdcd47de459f4d1f9b38df2afd0c7b3fc247ba3d773c38ba35288f24988e"))
throw std::runtime_error("invalid identity in Defaults");
addrs.push_back(InetAddress("108.61.200.101",ZT_DEFAULT_UDP_PORT));
addrs.push_back(std::pair<InetAddress,bool>(InetAddress("108.61.200.101",ZT_DEFAULT_UDP_PORT),false));
addrs.push_back(std::pair<InetAddress,bool>(InetAddress("108.61.200.101",443),true));
sn[id] = addrs;
return sn;
+2 -2
View File
@@ -64,9 +64,9 @@ public:
const std::string defaultHomePath;
/**
* Supernodes on the ZeroTier network
* Supernodes on the ZeroTier network (identity, address/tcp?)
*/
const std::map< Identity,std::vector<InetAddress> > supernodes;
const std::map< Identity,std::vector< std::pair<InetAddress,bool> > > supernodes;
/**
* Identities permitted to sign software updates
-216
View File
@@ -1,216 +0,0 @@
/*
* ZeroTier One - Global Peer to Peer Ethernet
* Copyright (C) 2011-2014 ZeroTier Networks LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* ZeroTier may be used and distributed under the terms of the GPLv3, which
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form, please contact ZeroTier Networks
* LLC. Start here: http://www.zerotier.com/
*/
#include <vector>
#include "Constants.hpp"
#ifdef __WINDOWS__
#include <WinSock2.h>
#include <Windows.h>
#endif
#include "Demarc.hpp"
#include "RuntimeEnvironment.hpp"
#include "Logger.hpp"
#include "UdpSocket.hpp"
#include "InetAddress.hpp"
#include "Switch.hpp"
#include "Buffer.hpp"
#include "CMWC4096.hpp"
namespace ZeroTier {
const Demarc::Port Demarc::ANY_PORT = (Port)0xffffffffffffffffULL;
const Demarc::Port Demarc::NULL_PORT = (Port)0;
Demarc::Demarc(const RuntimeEnvironment *renv) :
_r(renv)
{
}
Demarc::~Demarc()
{
for(std::map< Port,DemarcPortObj >::iterator pe(_ports.begin());pe!=_ports.end();++pe) {
switch (pe->second.type) {
case PORT_TYPE_UDP_SOCKET_V4:
case PORT_TYPE_UDP_SOCKET_V6:
delete ((UdpSocket *)pe->second.obj);
break;
case PORT_TYPE_LOCAL_ETHERNET:
case PORT_TYPE_RELAY_TUNNEL:
break;
}
}
}
std::string Demarc::describe(Demarc::Port p)
{
char buf[64];
switch ((DemarcPortType)(((uint64_t)p) >> 60)) {
case PORT_TYPE_UDP_SOCKET_V4:
Utils::snprintf(buf,sizeof(buf),"udp/4/%d",(int)((uint64_t)p & 0xffff));
return std::string(buf);
case PORT_TYPE_UDP_SOCKET_V6:
Utils::snprintf(buf,sizeof(buf),"udp/6/%d",(int)((uint64_t)p & 0xffff));
return std::string(buf);
case PORT_TYPE_LOCAL_ETHERNET:
return std::string("ethernet");
case PORT_TYPE_RELAY_TUNNEL:
return std::string("relay");
}
return std::string("(null)");
}
bool Demarc::has(Port p) const
throw()
{
Mutex::Lock _l(_ports_m);
return (_ports.count(p) != 0);
}
bool Demarc::bindLocalUdp(unsigned int localPort)
{
Mutex::Lock _l(_ports_m);
uint64_t v4p = ((uint64_t)PORT_TYPE_UDP_SOCKET_V4 << 60) | (uint64_t)localPort;
uint64_t v6p = ((uint64_t)PORT_TYPE_UDP_SOCKET_V6 << 60) | (uint64_t)localPort;
if ((_ports.count((Port)v4p))||(_ports.count((Port)v6p)))
return true; // port already bound
UdpSocket *v4 = (UdpSocket *)0;
try {
DemarcPortObj *v4r = &(_ports[(Port)v4p]);
v4r->port = (Port)v4p;
v4r->parent = this;
v4r->obj = v4 = new UdpSocket(false,localPort,false,&Demarc::_CBudpSocketPacketHandler,v4r);
v4r->type = PORT_TYPE_UDP_SOCKET_V4;
} catch ( ... ) {
_ports.erase((Port)v4p);
v4 = (UdpSocket *)0;
}
UdpSocket *v6 = (UdpSocket *)0;
try {
DemarcPortObj *v6r = &(_ports[(Port)v6p]);
v6r->port = (Port)v6p;
v6r->parent = this;
v6r->obj = v6 = new UdpSocket(false,localPort,true,&Demarc::_CBudpSocketPacketHandler,v6r);
v6r->type = PORT_TYPE_UDP_SOCKET_V6;
} catch ( ... ) {
_ports.erase((Port)v6p);
v6 = (UdpSocket *)0;
}
return ((v4)||(v6));
}
Demarc::Port Demarc::pick(const InetAddress &to) const
throw()
{
Mutex::Lock _l(_ports_m);
try {
std::vector< std::map< Port,DemarcPortObj >::const_iterator > possibilities;
for(std::map< Port,DemarcPortObj >::const_iterator pe(_ports.begin());pe!=_ports.end();++pe) {
switch (pe->second.type) {
case PORT_TYPE_UDP_SOCKET_V4:
if (to.isV4())
possibilities.push_back(pe);
break;
case PORT_TYPE_UDP_SOCKET_V6:
if (to.isV6())
possibilities.push_back(pe);
break;
default:
break;
}
}
if (possibilities.size())
return possibilities[_r->prng->next32() % possibilities.size()]->first;
else return NULL_PORT;
} catch ( ... ) {
return NULL_PORT;
}
}
Demarc::Port Demarc::send(Demarc::Port fromPort,const InetAddress &to,const void *data,unsigned int len,int hopLimit) const
throw()
{
_ports_m.lock();
std::map< Port,DemarcPortObj >::const_iterator pe(_ports.find(fromPort));
if (pe == _ports.end()) {
try {
std::vector< std::map< Port,DemarcPortObj >::const_iterator > possibilities;
for(pe=_ports.begin();pe!=_ports.end();++pe) {
switch (pe->second.type) {
case PORT_TYPE_UDP_SOCKET_V4:
if (to.isV4())
possibilities.push_back(pe);
break;
case PORT_TYPE_UDP_SOCKET_V6:
if (to.isV6())
possibilities.push_back(pe);
break;
default:
break;
}
}
if (possibilities.size())
pe = possibilities[_r->prng->next32() % possibilities.size()];
else {
_ports_m.unlock();
return NULL_PORT;
}
} catch ( ... ) {
_ports_m.unlock();
return NULL_PORT;
}
}
switch (pe->second.type) {
case PORT_TYPE_UDP_SOCKET_V4:
case PORT_TYPE_UDP_SOCKET_V6:
_ports_m.unlock();
if (((UdpSocket *)pe->second.obj)->send(to,data,len,hopLimit))
return pe->first;
return NULL_PORT;
default:
break;
}
_ports_m.unlock();
return NULL_PORT;
}
void Demarc::_CBudpSocketPacketHandler(UdpSocket *sock,void *arg,const InetAddress &from,const void *data,unsigned int len)
{
if (!((DemarcPortObj *)arg)->parent->_r->shutdownInProgress)
((DemarcPortObj *)arg)->parent->_r->sw->onRemotePacket(((DemarcPortObj *)arg)->port,from,Buffer<4096>(data,len));
}
} // namespace ZeroTier
-174
View File
@@ -1,174 +0,0 @@
/*
* ZeroTier One - Global Peer to Peer Ethernet
* Copyright (C) 2011-2014 ZeroTier Networks LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* ZeroTier may be used and distributed under the terms of the GPLv3, which
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form, please contact ZeroTier Networks
* LLC. Start here: http://www.zerotier.com/
*/
#ifndef ZT_DEMARC_HPP
#define ZT_DEMARC_HPP
#include <stdlib.h>
#include <stdint.h>
#include <map>
#include <string>
#include "Mutex.hpp"
#include "InetAddress.hpp"
namespace ZeroTier {
class RuntimeEnvironment;
class UdpSocket;
/**
* Local demarcation point
*
* This holds and provides unique identifiers for all local communication
* endpoints, such as UDP sockets, raw Ethernet sockets, tunnels to a relay
* server, etc. It permits other code to refer to these via Port and forget
* about what they actually are.
*
* All ports are closed when this class is destroyed.
*
* Its name "demarcation point" comes from the telco/cable terminology for
* the box where wires terminate at a customer's property.
*/
class Demarc
{
public:
/**
* Local demarcation port
*
* NULL_PORT is zero so this can be used in if(port) to check for
* a valid/known port.
*/
typedef uint64_t Port;
/**
* Port identifier used to refer to any port
*/
static const Port ANY_PORT;
/**
* Port identifier used to refer to null port / port not found
*/
static const Port NULL_PORT;
Demarc(const RuntimeEnvironment *renv);
~Demarc();
/**
* Describe a port
*
* This can describe even ports that are not bound, e.g. from serialized
* data.
*
* @param p Port
* @return Human-readable description of port
*/
static std::string describe(Port p);
/**
* @param p Port to check
* @return True if this port is bound/connected/etc.
*/
bool has(Port p) const
throw();
/**
* Bind local UDP port for both IPv4 and IPv6 traffic
*
* @param localPort Local IP port
* @return True if successfully bound, or if already bound
*/
bool bindLocalUdp(unsigned int localPort);
/**
* Pick a port to send to an address of a given type
*
* @param to Destination address
* @return Port or NULL_PORT if none
*/
Port pick(const InetAddress &to) const
throw();
/**
* Send a packet
*
* If fromPort is ANY_PORT or if the port is not found, a random port is
* chosen from those available matching the characteristics of the address
* in 'to'.
*
* @param fromPort Port to send from
* @param to Destination IP/port
* @param data Data to send
* @param len Length of data in bytes
* @param hopLimit IP hop limit for UDP packets or -1 for max/unlimited
* @return Port actually sent from or NULL_PORT on failure
*/
Port send(Port fromPort,const InetAddress &to,const void *data,unsigned int len,int hopLimit) const
throw();
/**
* @param p Port
* @return 64-bit integer suitable for serialization
*/
static inline uint64_t portToInt(const Port p) throw() { return (uint64_t)p; }
/**
* @param p 64-bit integer from serialized representation
* @return Port suitable for use in code
*/
static inline Port intToPort(const uint64_t p) throw() { return (Port)p; }
private:
const RuntimeEnvironment *_r;
static void _CBudpSocketPacketHandler(UdpSocket *sock,void *arg,const InetAddress &from,const void *data,unsigned int len);
enum DemarcPortType
{
PORT_TYPE_UDP_SOCKET_V4 = 1,
PORT_TYPE_UDP_SOCKET_V6 = 2,
PORT_TYPE_LOCAL_ETHERNET = 3,
PORT_TYPE_RELAY_TUNNEL = 4
};
// Variant holding instances of UdpSocket, etc.
struct DemarcPortObj
{
Demarc::Port port;
Demarc *parent;
void *obj;
DemarcPortType type;
};
std::map< Port,DemarcPortObj > _ports;
Mutex _ports_m;
};
} // namespace ZeroTier
#endif
-1782
View File
File diff suppressed because it is too large. Load diff
+39 -119
View File
@@ -31,68 +31,44 @@
#include <stdio.h>
#include <stdlib.h>
#include <map>
#include <list>
#include <vector>
#include <set>
#include <string>
#include <queue>
#include <stdexcept>
#include <set>
#include "Constants.hpp"
#include "InetAddress.hpp"
#include "MAC.hpp"
#include "Mutex.hpp"
#include "Condition.hpp"
#include "MulticastGroup.hpp"
#include "Thread.hpp"
#include "InetAddress.hpp"
#include "Buffer.hpp"
#include "Array.hpp"
#ifdef __WINDOWS__
#include <WinSock2.h>
#include <Windows.h>
#endif
#include "MulticastGroup.hpp"
#include "NonCopyable.hpp"
namespace ZeroTier {
class RuntimeEnvironment;
/**
* System ethernet tap device
* Base class for Ethernet tap device implementations
*/
class EthernetTap
class EthernetTap : NonCopyable
{
public:
/**
* Construct a new TAP device
*
* Handler arguments: arg,from,to,etherType,data
*
* @param renv Runtime environment
* @param tag A tag used to identify persistent taps at the OS layer (e.g. nwid in hex)
* @param mac MAC address of device
* @param mtu MTU of device
* @param desc If non-NULL, a description (not used on all OSes)
* @param handler Handler function to be called when data is received from the tap
* @param arg First argument to handler function
* @throws std::runtime_error Unable to allocate device
*/
EthernetTap(
const RuntimeEnvironment *renv,
const char *tag,
const MAC &mac,
unsigned int mtu,
void (*handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &),
void *arg)
throw(std::runtime_error);
virtual ~EthernetTap() {}
/**
* Close tap and shut down thread
*
* This may block for a few seconds while thread exits.
* @return Implementation class name (e.g. UnixEthernetTap)
*/
~EthernetTap();
inline const char *implementationName() const { return _implName; }
/**
* Sets whether device is 'up'
*
* This may do nothing on some platforms.
*
* @param en Is device enabled?
*/
virtual void setEnabled(bool en) = 0;
/**
* @return Is device 'up'?
*/
virtual bool enabled() const = 0;
/**
* Set the user display name for this connection
@@ -101,7 +77,7 @@ public:
*
* @param dn User display name
*/
void setDisplayName(const char *dn);
virtual void setDisplayName(const char *dn) = 0;
/**
* @return MAC address of this interface
@@ -119,7 +95,7 @@ public:
* @param ip IP and netmask (netmask stored in port field)
* @return True if IP added successfully
*/
bool addIP(const InetAddress &ip);
virtual bool addIP(const InetAddress &ip) = 0;
/**
* Remove an IP from this interface
@@ -129,12 +105,12 @@ public:
* @param ip IP and netmask (netmask stored in port field)
* @return True if IP removed successfully
*/
bool removeIP(const InetAddress &ip);
virtual bool removeIP(const InetAddress &ip) = 0;
/**
* @return All IP addresses (V4 and V6) assigned to this interface (including link-local)
*/
std::set<InetAddress> ips() const;
virtual std::set<InetAddress> ips() const = 0;
/**
* Set this tap's IP addresses to exactly this set of IPs
@@ -176,17 +152,17 @@ public:
* @param data Frame payload
* @param len Length of frame
*/
void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len);
virtual void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) = 0;
/**
* @return OS-specific device or connection name
*/
std::string deviceName() const;
virtual std::string deviceName() const = 0;
/**
* @return OS-internal persistent device ID or empty string if not applicable to this platform or not persistent
*/
std::string persistentId() const;
virtual std::string persistentId() const = 0;
/**
* Fill or modify a set to contain multicast groups for this device
@@ -200,73 +176,17 @@ public:
* @param groups Set to modify in place
* @return True if set was changed since last call
*/
bool updateMulticastGroups(std::set<MulticastGroup> &groups);
virtual bool updateMulticastGroups(std::set<MulticastGroup> &groups) = 0;
/**
* Thread main method; do not call elsewhere
*/
void threadMain()
throw();
protected:
EthernetTap(const char *cn,const MAC &m,unsigned int mt) :
_implName(cn),
_mac(m),
_mtu(mt) {}
/**
* Remove persistent tap device by device name
*
* This has no effect on platforms that do not have persistent taps.
* On platforms like Windows with persistent devices the device is
* uninstalled.
*
* @param _r Runtime environment
* @param pdev Device name as returned by persistentId() while tap is running
* @return True if a device was deleted
*/
static bool deletePersistentTapDevice(const RuntimeEnvironment *_r,const char *pid);
/**
* Clean persistent tap devices that are not in the supplied set
*
* This has no effect on platforms that do not have persistent taps.
* On platforms like Windows with persistent devices the device is
* uninstalled.
*
* @param _r Runtime environment
* @param exceptThese Devices to leave in place
* @param alsoRemoveUnassociatedDevices If true, remove devices not associated with any network as well
* @return Number of devices deleted or -1 if an error prevented the operation from being performed
*/
static int cleanPersistentTapDevices(const RuntimeEnvironment *_r,const std::set<std::string> &exceptThese,bool alsoRemoveUnassociatedDevices);
private:
const MAC _mac;
const unsigned int _mtu;
const RuntimeEnvironment *_r;
void (*_handler)(void *,const MAC &,const MAC &,unsigned int,const Buffer<4096> &);
void *_arg;
Thread _thread;
#ifdef __UNIX_LIKE__
char _dev[16];
int _fd;
int _shutdownSignalPipe[2];
#endif
#ifdef __WINDOWS__
void _syncIpsWithRegistry(const std::set<InetAddress> &haveIps);
HANDLE _tap;
OVERLAPPED _tapOvlRead,_tapOvlWrite;
char _tapReadBuf[ZT_IF_MTU + 32];
HANDLE _injectSemaphore;
GUID _deviceGuid;
std::string _myDeviceInstanceId; // NetCfgInstanceId, a GUID
std::string _myDeviceInstanceIdPath; // DeviceInstanceID, another kind of "instance ID"
std::queue< std::pair< Array<char,ZT_IF_MTU + 32>,unsigned int > > _injectPending;
Mutex _injectPending_m;
volatile bool _run;
volatile bool _initialized;
#endif
const char *_implName;
MAC _mac;
unsigned int _mtu;
};
} // namespace ZeroTier
+17 -15
View File
@@ -141,27 +141,29 @@ bool InetAddress::operator==(const InetAddress &a) const
return (!memcmp(_sa.sin6.sin6_addr.s6_addr,a._sa.sin6.sin6_addr.s6_addr,sizeof(_sa.sin6.sin6_addr.s6_addr)));
}
return false;
} else if (!_sa.saddr.sa_family)
return (!a._sa.saddr.sa_family);
return (!memcmp(&_sa,&a._sa,sizeof(_sa)));
} else return (memcmp(&_sa,&a._sa,sizeof(_sa)) == 0);
}
bool InetAddress::operator<(const InetAddress &a) const
throw()
{
if (_sa.saddr.sa_family == AF_INET) {
if (a._sa.saddr.sa_family == AF_INET)
return ((ntohl(_sa.sin.sin_addr.s_addr < ntohl(a._sa.sin.sin_addr.s_addr)))||((_sa.sin.sin_addr.s_addr == a._sa.sin.sin_addr.s_addr)&&(ntohs(_sa.sin.sin_port) < ntohs(a._sa.sin.sin_port))));
else if (a._sa.saddr.sa_family == AF_INET6)
return true;
} else if (_sa.saddr.sa_family == AF_INET6) {
if (a._sa.saddr.sa_family == AF_INET6) {
int cmp = memcmp(_sa.sin6.sin6_addr.s6_addr,a._sa.sin6.sin6_addr.s6_addr,16);
return ((cmp < 0)||((!cmp)&&(ntohs(_sa.sin6.sin6_port) < ntohs(a._sa.sin6.sin6_port))));
} else if (a._sa.saddr.sa_family == AF_INET)
return false;
if (_sa.saddr.sa_family < a._sa.saddr.sa_family)
return true;
else if (_sa.saddr.sa_family == a._sa.saddr.sa_family) {
if (_sa.saddr.sa_family == AF_INET) {
unsigned long x = ntohl(_sa.sin.sin_addr.s_addr);
unsigned long y = ntohl(a._sa.sin.sin_addr.s_addr);
if (x == y)
return (ntohs(_sa.sin.sin_port) < ntohs(a._sa.sin.sin_port));
else return (x < y);
} else if (_sa.saddr.sa_family == AF_INET6) {
int cmp = (int)memcmp(_sa.sin6.sin6_addr.s6_addr,a._sa.sin6.sin6_addr.s6_addr,16);
if (cmp == 0)
return (ntohs(_sa.sin6.sin6_port) < ntohs(a._sa.sin6.sin6_port));
else return (cmp < 0);
} else return (memcmp(&_sa,&a._sa,sizeof(_sa)) < 0);
}
return (_sa.saddr.sa_family < a._sa.saddr.sa_family);
return false;
}
} // namespace ZeroTier
+2
View File
@@ -51,6 +51,8 @@ namespace ZeroTier {
/**
* Wrapper for sockaddr structures for IPV4 and IPV6
*
* Note: this class is raw memcpy'able, which is used in a couple places.
*/
class InetAddress
{
Loaded 20 of 60 files, more files were not shown because too many files have changed in this diff. Show more