diff --git a/AUTHORS.md b/AUTHORS.md
new file mode 100644
index 000000000..149362c31
--- /dev/null
+++ b/AUTHORS.md
@@ -0,0 +1,38 @@
+## Authors
+
+ * ZeroTier protocol design and core network virtualization engine, ZeroTier One service, React web UI, packaging for most platforms, kitchen sink...
+ Adam Ierymenko / adam.ierymenko@zerotier.com
+
+ * Java JNI Interface to enable Android application development, and Android app itself (code for that is elsewhere)
+ Grant Limberg / glimberg@gmail.com
+
+## Contributors
+
+ * Debugging and testing, OpenWRT support fixes.
+ Moritz Warning / moritzwarning@web.de
+
+ * Several others made smaller contributions, which GitHub tracks here:
+ https://github.com/zerotier/ZeroTierOne/graphs/contributors
+
+## Third Party Code
+
+ * LZ4 compression algorithm by Yann Collet (BSD license)
+ http://code.google.com/p/lz4/
+
+ * http-parser by many authors (MIT license)
+ https://github.com/joyent/http-parser
+
+ * json-parser by James McLaughlin (BSD license)
+ https://github.com/udp/json-parser
+
+ * TunTapOSX by Mattias Nissler (BSD license)
+ http://tuntaposx.sourceforge.net
+
+ * tap-windows and tap-windows6 by the OpenVPN project (GPL)
+ https://github.com/OpenVPN/tap-windows
+ https://github.com/OpenVPN/tap-windows6
+
+ * Salsa20 stream cipher, Curve25519 elliptic curve cipher, Ed25519
+ digital signature algorithm, and Poly1305 MAC algorithm, all by
+ Daniel J. Bernstein (public domain)
+ http://cr.yp.to/
diff --git a/AUTHORS.txt b/AUTHORS.txt
deleted file mode 100644
index 4ac870f1e..000000000
--- a/AUTHORS.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-ZeroTier One is designed and written by Adam Ierymenko, with a few bug
-fixes and other contributions from other users. Information about all
-contributors can be found on the GitHub home page at:
-
-https://github.com/zerotier/ZeroTierOne
-
-ZeroTier One includes the following third party code:
-
- * LZ4 compression algorithm by Yann Collet (BSD license)
- http://code.google.com/p/lz4/
-
- * http-parser by many authors (MIT license)
- https://github.com/joyent/http-parser
-
- * json-parser by James McLaughlin (BSD license)
- https://github.com/udp/json-parser
-
- * TunTapOSX by Mattias Nissler (forked for ZT1) (BSD license)
- http://tuntaposx.sourceforge.net
-
- * tap-windows by the OpenVPN project (forked for ZT1) (GPL)
- https://github.com/OpenVPN/tap-windows
-
- * Salsa20 stream cipher, Curve25519 elliptic curve cipher, Ed25519
- digital signature algorithm, and Poly1305 MAC algorithm, all by
- Daniel J. Bernstein (public domain)
- http://cr.yp.to/
diff --git a/ext/installfiles/windows/ZeroTier One.aip b/ext/installfiles/windows/ZeroTier One.aip
index 234873f87..ff7ee2190 100644
--- a/ext/installfiles/windows/ZeroTier One.aip
+++ b/ext/installfiles/windows/ZeroTier One.aip
@@ -23,7 +23,7 @@
-
+
diff --git a/osdep/Phy.hpp b/osdep/Phy.hpp
index 23fd2ee24..ec01625ba 100644
--- a/osdep/Phy.hpp
+++ b/osdep/Phy.hpp
@@ -123,12 +123,13 @@ private:
enum PhySocketType
{
- ZT_PHY_SOCKET_TCP_OUT_PENDING = 0x00,
- ZT_PHY_SOCKET_TCP_OUT_CONNECTED = 0x01,
- ZT_PHY_SOCKET_TCP_IN = 0x02,
- ZT_PHY_SOCKET_TCP_LISTEN = 0x03,
- ZT_PHY_SOCKET_RAW = 0x04,
- ZT_PHY_SOCKET_UDP = 0x05
+ ZT_PHY_SOCKET_CLOSED = 0x00, // socket is closed, will be removed on next poll()
+ ZT_PHY_SOCKET_TCP_OUT_PENDING = 0x01,
+ ZT_PHY_SOCKET_TCP_OUT_CONNECTED = 0x02,
+ ZT_PHY_SOCKET_TCP_IN = 0x03,
+ ZT_PHY_SOCKET_TCP_LISTEN = 0x04,
+ ZT_PHY_SOCKET_RAW = 0x05,
+ ZT_PHY_SOCKET_UDP = 0x06
};
struct PhySocketImpl
@@ -205,8 +206,10 @@ public:
~Phy()
{
- while (!_socks.empty())
- this->close((PhySocket *)&(_socks.front()),true);
+ for(typename std::list::const_iterator s(_socks.begin());s!=_socks.end();++s) {
+ if (s->type != ZT_PHY_SOCKET_CLOSED)
+ this->close((PhySocket *)&(*s),true);
+ }
ZT_PHY_CLOSE_SOCKET(_whackReceiveSocket);
ZT_PHY_CLOSE_SOCKET(_whackSendSocket);
}
@@ -620,11 +623,7 @@ public:
#endif
}
- bool atEnd = false;
- for(typename std::list::iterator s(_socks.begin()),nexts;(!atEnd);s=nexts) {
- nexts = s; ++nexts; // we can delete the linked list item, so traverse now
- atEnd = (nexts == _socks.end()); // if we delete the last element, s!=_socks.end() will no longer terminate our loop
-
+ for(typename std::list::iterator s(_socks.begin());s!=_socks.end();) {
switch (s->type) {
case ZT_PHY_SOCKET_TCP_OUT_PENDING:
@@ -724,6 +723,10 @@ public:
break;
}
+
+ if (s->type == ZT_PHY_SOCKET_CLOSED)
+ _socks.erase(s++);
+ else ++s;
}
}
@@ -736,6 +739,8 @@ public:
if (!sock)
return;
PhySocketImpl &sws = *(reinterpret_cast(sock));
+ if (sws.type == ZT_PHY_SOCKET_CLOSED)
+ return;
FD_CLR(sws.sock,&_readfds);
FD_CLR(sws.sock,&_writefds);
@@ -765,21 +770,15 @@ public:
break;
}
- long oldSock = (long)sws.sock;
+ // Causes entry to be deleted from list in poll(), ignored elsewhere
+ sws.type = ZT_PHY_SOCKET_CLOSED;
- for(typename std::list::iterator s(_socks.begin());s!=_socks.end();++s) {
- if (reinterpret_cast(&(*s)) == sock) {
- _socks.erase(s);
- break;
- }
- }
-
- if (oldSock >= _nfds) {
+ if (sws.sock >= _nfds) {
long nfds = (long)_whackSendSocket;
if ((long)_whackReceiveSocket > nfds)
nfds = (long)_whackReceiveSocket;
for(typename std::list::iterator s(_socks.begin());s!=_socks.end();++s) {
- if ((long)s->sock > nfds)
+ if ((s->type != ZT_PHY_SOCKET_CLOSED)&&((long)s->sock > nfds))
nfds = (long)s->sock;
}
_nfds = nfds;