diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2014-03-31 22:23:55 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2014-03-31 22:23:55 -0700 |
commit | f13493edb2aae228ddbe70cc2f0609c541faf2d7 (patch) | |
tree | cb1a6845ec82e2ea361ce15e88440a249992091c | |
parent | 595b386afcd4e4eca0cf379cd14689c1db8ee647 (diff) | |
download | infinitytier-f13493edb2aae228ddbe70cc2f0609c541faf2d7.tar.gz infinitytier-f13493edb2aae228ddbe70cc2f0609c541faf2d7.zip |
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.
-rw-r--r-- | node/PacketDecoder.cpp | 18 | ||||
-rw-r--r-- | node/Path.hpp | 81 | ||||
-rw-r--r-- | node/Peer.cpp | 80 | ||||
-rw-r--r-- | node/Socket.hpp | 12 | ||||
-rw-r--r-- | node/SocketManager.cpp | 11 | ||||
-rw-r--r-- | node/SocketManager.hpp | 17 | ||||
-rw-r--r-- | node/Switch.cpp | 10 | ||||
-rw-r--r-- | node/Switch.hpp | 12 | ||||
-rw-r--r-- | node/TcpSocket.cpp | 8 | ||||
-rw-r--r-- | node/TcpSocket.hpp | 6 | ||||
-rw-r--r-- | node/Topology.cpp | 2 |
11 files changed, 147 insertions, 110 deletions
diff --git a/node/PacketDecoder.cpp b/node/PacketDecoder.cpp index 329aab78..2b8cba51 100644 --- a/node/PacketDecoder.cpp +++ b/node/PacketDecoder.cpp @@ -579,7 +579,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared source().toString().c_str(), frameLen, startingFifoItems); - _r->sm->send(ZT_DEFAULTS.multicastTraceWatcher,false,mct,strlen(mct)); + _r->sm->sendUdp(ZT_DEFAULTS.multicastTraceWatcher,mct,strlen(mct)); #endif // At this point the frame is basically valid, so we can call it a receive @@ -602,7 +602,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared mctdepth, (_r->topology->amSupernode() ? 'S' : '-'), _r->identity.address().toString().c_str()); - _r->sm->send(ZT_DEFAULTS.multicastTraceWatcher,false,mct,strlen(mct)); + _r->sm->sendUdp(ZT_DEFAULTS.multicastTraceWatcher,mct,strlen(mct)); #endif TRACE("dropped MULTICAST_FRAME from %s(%s): duplicate",source().toString().c_str(),_remoteAddress.toString().c_str()); return true; @@ -648,7 +648,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared mctdepth, (_r->topology->amSupernode() ? 'S' : '-'), _r->identity.address().toString().c_str()); - _r->sm->send(ZT_DEFAULTS.multicastTraceWatcher,false,mct,strlen(mct)); + _r->sm->sendUdp(ZT_DEFAULTS.multicastTraceWatcher,mct,strlen(mct)); #endif TRACE("dropped MULTICAST_FRAME from %s(%s) into %.16llx: source mac %s doesn't belong to %s, and bridging is not supported on network",source().toString().c_str(),_remoteAddress.toString().c_str(),nwid,sourceMac.toString().c_str(),origin.toString().c_str()); return true; @@ -664,7 +664,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared mctdepth, (_r->topology->amSupernode() ? 'S' : '-'), _r->identity.address().toString().c_str()); - _r->sm->send(ZT_DEFAULTS.multicastTraceWatcher,false,mct,strlen(mct)); + _r->sm->sendUdp(ZT_DEFAULTS.multicastTraceWatcher,mct,strlen(mct)); #endif TRACE("dropped MULTICAST_FRAME from %s(%s) into %.16llx: ethertype %u is not allowed",source().toString().c_str(),nwid,_remoteAddress.toString().c_str(),etherType); return true; @@ -681,7 +681,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared mctdepth, (_r->topology->amSupernode() ? 'S' : '-'), _r->identity.address().toString().c_str()); - _r->sm->send(ZT_DEFAULTS.multicastTraceWatcher,false,mct,strlen(mct)); + _r->sm->sendUdp(ZT_DEFAULTS.multicastTraceWatcher,mct,strlen(mct)); #endif TRACE("dropped MULTICAST_FRAME from %s(%s): rate limits exceeded for sender %s",source().toString().c_str(),_remoteAddress.toString().c_str(),origin.toString().c_str()); return true; @@ -702,7 +702,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared mctdepth, (_r->topology->amSupernode() ? 'S' : '-'), _r->identity.address().toString().c_str()); - _r->sm->send(ZT_DEFAULTS.multicastTraceWatcher,false,mct,strlen(mct)); + _r->sm->sendUdp(ZT_DEFAULTS.multicastTraceWatcher,mct,strlen(mct)); #endif TRACE("not forwarding MULTICAST_FRAME from %s(%s): depth == 0xffff (do not forward)",source().toString().c_str(),_remoteAddress.toString().c_str()); return true; @@ -717,7 +717,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared mctdepth, (_r->topology->amSupernode() ? 'S' : '-'), _r->identity.address().toString().c_str()); - _r->sm->send(ZT_DEFAULTS.multicastTraceWatcher,false,mct,strlen(mct)); + _r->sm->sendUdp(ZT_DEFAULTS.multicastTraceWatcher,mct,strlen(mct)); #endif TRACE("not forwarding MULTICAST_FRAME from %s(%s): max propagation depth reached",source().toString().c_str(),_remoteAddress.toString().c_str()); return true; @@ -776,7 +776,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared mctdepth, (_r->topology->amSupernode() ? 'S' : '-'), _r->identity.address().toString().c_str()); - _r->sm->send(ZT_DEFAULTS.multicastTraceWatcher,false,mct,strlen(mct)); + _r->sm->sendUdp(ZT_DEFAULTS.multicastTraceWatcher,mct,strlen(mct)); #endif //TRACE("not forwarding MULTICAST_FRAME from %s(%s): no next hop",source().toString().c_str(),_remoteAddress.toString().c_str()); return true; @@ -797,7 +797,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared origin.toString().c_str(), nextHop.toString().c_str(), numAdded); - _r->sm->send(ZT_DEFAULTS.multicastTraceWatcher,false,mct,strlen(mct)); + _r->sm->sendUdp(ZT_DEFAULTS.multicastTraceWatcher,mct,strlen(mct)); #endif // Send to next hop, reusing this packet as scratch space diff --git a/node/Path.hpp b/node/Path.hpp index b227811a..8cd0776c 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -39,7 +39,7 @@ #include "Utils.hpp" #include "Buffer.hpp" -#define ZT_PATH_SERIALIZATION_VERSION 1 +#define ZT_PATH_SERIALIZATION_VERSION 2 namespace ZeroTier { @@ -49,13 +49,21 @@ namespace ZeroTier { class Path { public: + enum Type + { + PATH_TYPE_NULL = 0, + PATH_TYPE_UDP = 1, + PATH_TYPE_TCP_OUT = 2, + PATH_TYPE_TCP_IN = 3 + }; + Path() : _lastSend(0), _lastReceived(0), _lastFirewallOpener(0), _lastPing(0), _addr(), - _tcp(false), + _type(PATH_TYPE_NULL), _fixed(false) {} Path(const Path &p) @@ -64,13 +72,13 @@ public: memcpy(this,&p,sizeof(Path)); } - Path(const InetAddress &addr,bool tcp,bool fixed = false) : + Path(const InetAddress &addr,Type t,bool fixed = false) : _lastSend(0), _lastReceived(0), _lastFirewallOpener(0), _lastPing(0), _addr(addr), - _tcp(tcp), + _type(t), _fixed(fixed) {} inline Path &operator=(const Path &p) @@ -81,13 +89,16 @@ public: } inline const InetAddress &address() const throw() { return _addr; } - inline bool tcp() const throw() { return _tcp; } + + inline Type type() const throw() { return _type; } + inline bool tcp() const throw() { return ((_type == PATH_TYPE_TCP_IN)||(_type == PATH_TYPE_TCP_OUT)); } + inline uint64_t lastSend() const throw() { return _lastSend; } inline uint64_t lastReceived() const throw() { return _lastReceived; } inline uint64_t lastFirewallOpener() const throw() { return _lastFirewallOpener; } inline uint64_t lastPing() const throw() { return _lastPing; } - inline bool fixed() const throw() { return _fixed; } + inline bool fixed() const throw() { return _fixed; } inline void setFixed(bool f) throw() { _fixed = f; } inline void sent(uint64_t t) throw() { _lastSend = t; } @@ -111,40 +122,34 @@ public: inline std::string toString() const { uint64_t now = Utils::now(); - char lsago[32],lrago[32],lfoago[32],lpago[32]; - Utils::snprintf(lsago,sizeof(lsago),"%lld",(long long)((_lastSend != 0) ? (now - _lastSend) : -1)); - Utils::snprintf(lrago,sizeof(lrago),"%lld",(long long)((_lastReceived != 0) ? (now - _lastReceived) : -1)); - Utils::snprintf(lfoago,sizeof(lfoago),"%lld",(long long)((_lastFirewallOpener != 0) ? (now - _lastFirewallOpener) : -1)); - Utils::snprintf(lpago,sizeof(lfoago),"%lld",(long long)((_lastPing != 0) ? (now - _lastPing) : -1)); - return ( _addr.toString() + - "[" + - (_tcp ? "tcp" : "udp") + - ";" + - lsago + - ";" + - lrago + - ";" + - lpago + - ";" + - lfoago + - ";" + - (active(now) ? "active" : "inactive") + - ";" + - (_fixed ? "fixed" : "learned") + - "]" - ); + char tmp[1024]; + const char *t = ""; + switch(_type) { + case PATH_TYPE_NULL: t = "null"; break; + case PATH_TYPE_UDP: t = "udp"; break; + case PATH_TYPE_TCP_OUT: t = "tcp_out"; break; + case PATH_TYPE_TCP_IN: t = "tcp_in"; break; + } + Utils::snprintf(tmp,sizeof(tmp),"%s:%s:%lld;%lld;%lld;%lld;%s", + t, + _addr.toString().c_str(), + (long long)((_lastSend != 0) ? (now - _lastSend) : -1), + (long long)((_lastReceived != 0) ? (now - _lastReceived) : -1), + (long long)((_lastFirewallOpener != 0) ? (now - _lastFirewallOpener) : -1), + (long long)((_lastPing != 0) ? (now - _lastPing) : -1), + ((_fixed) ? "fixed" : (active(now) ? "active" : "inactive")) + ); + return std::string(tmp); } - inline bool operator==(const Path &p) const throw() { return ((_addr == p._addr)&&(_tcp == p._tcp)); } - inline bool operator!=(const Path &p) const throw() { return ((_addr != p._addr)||(_tcp != p._tcp)); } + inline bool operator==(const Path &p) const throw() { return ((_addr == p._addr)&&(_type == p._type)); } + inline bool operator!=(const Path &p) const throw() { return ((_addr != p._addr)||(_type != p._type)); } inline bool operator<(const Path &p) const throw() { - if (_addr == p._addr) { - if (!_tcp) // UDP < TCP - return p._tcp; - return false; - } else return (_addr < p._addr); + if (_addr == p._addr) + return ((int)_type < (int)p._type); + else return (_addr < p._addr); } inline bool operator>(const Path &p) const throw() { return (p < *this); } inline bool operator<=(const Path &p) const throw() { return !(p < *this); } @@ -171,7 +176,7 @@ public: b.append((uint16_t)_addr.port()); break; } - b.append(_tcp ? (unsigned char)1 : (unsigned char)0); + b.append((unsigned char)_type); b.append(_fixed ? (unsigned char)1 : (unsigned char)0); } template<unsigned int C> @@ -199,7 +204,7 @@ public: _addr.zero(); break; } - _tcp = (b[p++] != 0); + _type = (Type)b[p++]; _fixed = (b[p++] != 0); return (p - startAt); @@ -211,7 +216,7 @@ private: volatile uint64_t _lastFirewallOpener; volatile uint64_t _lastPing; InetAddress _addr; - bool _tcp; + Type _type; bool _fixed; }; diff --git a/node/Peer.cpp b/node/Peer.cpp index f7d24fee..6e8ecc01 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -69,25 +69,36 @@ void Peer::receive( Packet::Verb inReVerb, uint64_t now) { + // Update system-wide last packet receive time *((const_cast<uint64_t *>(&(_r->timeOfLastPacketReceived)))) = now; - if (!hops) { // direct packet + // Learn paths from direct packets (hops == 0) + if (!hops) { { Mutex::Lock _l(_lock); - // Update receive time on known paths bool havePath = false; for(std::vector<Path>::iterator p(_paths.begin());p!=_paths.end();++p) { - if ((p->address() == remoteAddr)&&(p->tcp() == (fromSock->type() == Socket::ZT_SOCKET_TYPE_TCP))) { + if ((p->address() == remoteAddr)&&(p->tcp() == fromSock->tcp())) { p->received(now); havePath = true; break; } } - // Learn new UDP paths (learning TCP would require an explicit mechanism) - if ((!havePath)&&(fromSock->type() != Socket::ZT_SOCKET_TYPE_TCP)) { - _paths.push_back(Path(remoteAddr,false,false)); + if (!havePath) { + Path::Type pt = Path::PATH_TYPE_UDP; + switch(fromSock->type()) { + case Socket::ZT_SOCKET_TYPE_TCP_IN: + pt = Path::PATH_TYPE_TCP_IN; + break; + case Socket::ZT_SOCKET_TYPE_TCP_OUT: + pt = Path::PATH_TYPE_TCP_OUT; + break; + default: + break; + } + _paths.push_back(Path(remoteAddr,pt,false)); _paths.back().received(now); } } @@ -110,26 +121,30 @@ bool Peer::send(const RuntimeEnvironment *_r,const void *data,unsigned int len,u { Mutex::Lock _l(_lock); - std::vector<Path>::iterator p(_paths.begin()); - if (p == _paths.end()) { - //TRACE("send to %s failed: no paths available",_id.address().toString().c_str()); - return false; - } - uint64_t bestPathLastReceived = p->lastReceived(); - std::vector<Path>::iterator bestPath = p; - while (++p != _paths.end()) { - uint64_t lr = p->lastReceived(); - if (lr > bestPathLastReceived) { - bestPathLastReceived = lr; - bestPath = p; + for(;;) { + std::vector<Path>::iterator p(_paths.begin()); + if (p == _paths.end()) + return false; + + uint64_t bestPathLastReceived = p->lastReceived(); + std::vector<Path>::iterator bestPath = p; + while (++p != _paths.end()) { + uint64_t lr = p->lastReceived(); + if (lr > bestPathLastReceived) { + bestPathLastReceived = lr; + bestPath = p; + } } - } - //TRACE("send to %s: using path: %s",_id.address().toString().c_str(),bestPath->toString().c_str()); - - if (_r->sm->send(bestPath->address(),bestPath->tcp(),data,len)) { - bestPath->sent(now); - return true; + if (_r->sm->send(bestPath->address(),bestPath->tcp(),bestPath->type() == Path::PATH_TYPE_TCP_OUT,data,len)) { + bestPath->sent(now); + return true; + } else { + if (bestPath->fixed()) + return false; + _paths.erase(bestPath); + // ... try again and pick a different path + } } return false; @@ -160,23 +175,24 @@ bool Peer::sendPing(const RuntimeEnvironment *_r,uint64_t now,bool firstSinceRes bool pingTcp; if (!firstSinceReset) { - // Do not use TCP if one of our UDP endpoints has answered recently. + uint64_t lastUdp = 0; + uint64_t lastTcp = 0; uint64_t lastPing = 0; - uint64_t lastDirectReceive = 0; - for(std::vector<Path>::iterator p(_paths.begin());p!=_paths.end();++p) { - lastPing = std::max(lastPing,p->lastPing()); - lastDirectReceive = std::max(lastDirectReceive,p->lastReceived()); + if (p->tcp()) + lastTcp = std::max(p->lastReceived(),lastTcp); + else lastUdp = std::max(p->lastReceived(),lastUdp); + lastPing = std::max(p->lastPing(),lastPing); } - - pingTcp = ( (lastDirectReceive < lastPing) && ((lastPing - lastDirectReceive) >= ZT_PING_UNANSWERED_AFTER) ); + uint64_t lastAny = std::max(lastUdp,lastTcp); + pingTcp = ( ( (lastAny < lastPing) && ((lastPing - lastAny) >= ZT_PING_UNANSWERED_AFTER) ) || (lastTcp > lastUdp) ); } else pingTcp = false; TRACE("PING %s (pingTcp==%d)",_id.address().toString().c_str(),(int)pingTcp); for(std::vector<Path>::iterator p(_paths.begin());p!=_paths.end();++p) { if ((pingTcp)||(!p->tcp())) { - if (_r->sw->sendHELLO(self,p->address(),p->tcp())) { + if (_r->sw->sendHELLO(self,*p)) { p->sent(now); p->pinged(now); sent = true; diff --git a/node/Socket.hpp b/node/Socket.hpp index ff185e6f..3cfedb1a 100644 --- a/node/Socket.hpp +++ b/node/Socket.hpp @@ -65,7 +65,8 @@ public: { ZT_SOCKET_TYPE_UDP_V4, ZT_SOCKET_TYPE_UDP_V6, - ZT_SOCKET_TYPE_TCP + ZT_SOCKET_TYPE_TCP_IN, // incoming connection, not listen + ZT_SOCKET_TYPE_TCP_OUT }; virtual ~Socket() {} @@ -80,6 +81,15 @@ public: } /** + * @return True if this is a TCP socket + */ + inline bool tcp() const + throw() + { + return ((_type == ZT_SOCKET_TYPE_TCP_IN)||(_type == ZT_SOCKET_TYPE_TCP_OUT)); + } + + /** * Send a ZeroTier message packet * * @param to Destination address (ignored in connected TCP sockets) diff --git a/node/SocketManager.cpp b/node/SocketManager.cpp index 722db5b1..85bf9dc3 100644 --- a/node/SocketManager.cpp +++ b/node/SocketManager.cpp @@ -347,7 +347,7 @@ SocketManager::~SocketManager() _closeSockets(); } -bool SocketManager::send(const InetAddress &to,bool tcp,const void *msg,unsigned int msglen) +bool SocketManager::send(const InetAddress &to,bool tcp,bool autoConnectTcp,const void *msg,unsigned int msglen) { if (tcp) { SharedPtr<Socket> ts; @@ -360,6 +360,9 @@ bool SocketManager::send(const InetAddress &to,bool tcp,const void *msg,unsigned if (ts) return ts->send(to,msg,msglen); + if (!autoConnectTcp) + return false; + #ifdef __WINDOWS__ SOCKET s = ::socket(to.isV4() ? AF_INET : AF_INET6,SOCK_STREAM,0); if (s == INVALID_SOCKET) @@ -394,7 +397,7 @@ bool SocketManager::send(const InetAddress &to,bool tcp,const void *msg,unsigned } else connecting = true; } - ts = SharedPtr<Socket>(new TcpSocket(this,s,connecting,to)); + ts = SharedPtr<Socket>(new TcpSocket(this,s,Socket::ZT_SOCKET_TYPE_TCP_OUT,connecting,to)); if (!ts->send(to,msg,msglen)) { _fdSetLock.lock(); FD_CLR(s,&_readfds); @@ -496,7 +499,7 @@ void SocketManager::poll(unsigned long timeout) InetAddress fromia((const struct sockaddr *)&from); Mutex::Lock _l2(_tcpSockets_m); try { - _tcpSockets[fromia] = SharedPtr<Socket>(new TcpSocket(this,sockfd,false,fromia)); + _tcpSockets[fromia] = SharedPtr<Socket>(new TcpSocket(this,sockfd,Socket::ZT_SOCKET_TYPE_TCP_IN,false,fromia)); #ifdef __WINDOWS__ { u_long iMode=1; ioctlsocket(sockfd,FIONBIO,&iMode); } #ifdef ZT_TCP_NODELAY @@ -536,7 +539,7 @@ void SocketManager::poll(unsigned long timeout) InetAddress fromia((const struct sockaddr *)&from); Mutex::Lock _l2(_tcpSockets_m); try { - _tcpSockets[fromia] = SharedPtr<Socket>(new TcpSocket(this,sockfd,false,fromia)); + _tcpSockets[fromia] = SharedPtr<Socket>(new TcpSocket(this,sockfd,Socket::ZT_SOCKET_TYPE_TCP_IN,false,fromia)); #ifdef __WINDOWS__ { u_long iMode=1; ioctlsocket(sockfd,FIONBIO,&iMode); } #ifdef ZT_TCP_NODELAY diff --git a/node/SocketManager.hpp b/node/SocketManager.hpp index 003c35eb..40a0c1df 100644 --- a/node/SocketManager.hpp +++ b/node/SocketManager.hpp @@ -85,17 +85,22 @@ public: /** * Send a message to a remote peer * - * If 'tcp' is true an existing TCP socket will be used or an attempt will - * be made to connect if one is not available. The message will be placed - * in the connecting TCP socket's outgoing queue, so if the connection - * succeeds the message will be sent. Otherwise it will be dropped. - * * @param to Destination address * @param tcp Use TCP? + * @param autoConnectTcp If true, automatically initiate TCP connection if there is none + * @param msg Message to send + * @param msglen Length of message + */ + bool send(const InetAddress &to,bool tcp,bool autoConnectTcp,const void *msg,unsigned int msglen); + + /** + * Send a message to a remote peer via UDP (shortcut for setting both TCP params to false in send) + * + * @param to Destination address * @param msg Message to send * @param msglen Length of message */ - bool send(const InetAddress &to,bool tcp,const void *msg,unsigned int msglen); + inline bool sendUdp(const InetAddress &to,const void *msg,unsigned int msglen) { return send(to,false,false,msg,msglen); } /** * Send a UDP packet with a limited IP TTL diff --git a/node/Switch.cpp b/node/Switch.cpp index 0e58c744..2ee3a4a0 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -214,7 +214,7 @@ void Switch::sendHELLO(const Address &dest) send(outp,false); } -bool Switch::sendHELLO(const SharedPtr<Socket> &fromSock,const SharedPtr<Peer> &dest,const InetAddress &remoteAddr) +bool Switch::sendHELLO(const SharedPtr<Peer> &dest,const Path &path) { uint64_t now = Utils::now(); Packet outp(dest->address(),_r->identity.address(),Packet::VERB_HELLO); @@ -225,10 +225,10 @@ bool Switch::sendHELLO(const SharedPtr<Socket> &fromSock,const SharedPtr<Peer> & outp.append(now); _r->identity.serialize(outp,false); outp.armor(dest->key(),false); - return fromSock->send(remoteAddr,outp.data(),outp.size()); + return _r->sm->send(path.address(),path.tcp(),path.type() == Path::PATH_TYPE_TCP_OUT,outp.data(),outp.size()); } -bool Switch::sendHELLO(const SharedPtr<Peer> &dest,const InetAddress &remoteAddr,bool tcp) +bool Switch::sendHELLO(const SharedPtr<Peer> &dest,const InetAddress &destUdp) { uint64_t now = Utils::now(); Packet outp(dest->address(),_r->identity.address(),Packet::VERB_HELLO); @@ -239,7 +239,7 @@ bool Switch::sendHELLO(const SharedPtr<Peer> &dest,const InetAddress &remoteAddr outp.append(now); _r->identity.serialize(outp,false); outp.armor(dest->key(),false); - return _r->sm->send(remoteAddr,tcp,outp.data(),outp.size()); + return _r->sm->send(deskUdp,false,false,outp.data(),outp.size()); } bool Switch::unite(const Address &p1,const Address &p2,bool force) @@ -354,7 +354,7 @@ unsigned long Switch::doTimerTasks() for(std::list<ContactQueueEntry>::iterator qi(_contactQueue.begin());qi!=_contactQueue.end();) { if (now >= qi->fireAtTime) { TRACE("sending NAT-T HELLO to %s(%s)",qi->peer->address().toString().c_str(),qi->inaddr.toString().c_str()); - sendHELLO(qi->peer,qi->inaddr,false); + sendHELLO(qi->peer,qi->inaddr); _contactQueue.erase(qi++); } else { nextDelay = std::min(nextDelay,(unsigned long)(qi->fireAtTime - now)); diff --git a/node/Switch.hpp b/node/Switch.hpp index fd5837b7..ee78d9fd 100644 --- a/node/Switch.hpp +++ b/node/Switch.hpp @@ -122,22 +122,20 @@ public: /** * Send a HELLO announcement immediately to the indicated address * - * @param fromSock Send from this local socket * @param dest Destination peer - * @param remoteAddr Remote address + * @param path Network path to peer * @return True if send appears successful */ - bool sendHELLO(const SharedPtr<Socket> &fromSock,const SharedPtr<Peer> &dest,const InetAddress &remoteAddr); + bool sendHELLO(const SharedPtr<Peer> &dest,const Path &path); /** - * Send a HELLO announcement immediately to the indicated address + * Send a HELLO announcement immediately to the indicated address via UDP * * @param dest Destination peer - * @param remoteAddr Remote address - * @param tcp Attempt to use TCP? + * @param destUdp UDP inet address * @return True if send appears successful */ - bool sendHELLO(const SharedPtr<Peer> &dest,const InetAddress &remoteAddr,bool tcp); + bool sendHELLO(const SharedPtr<Peer> &dest,const InetAddress &destUdp); /** * Send RENDEZVOUS to two peers to permit them to directly connect diff --git a/node/TcpSocket.cpp b/node/TcpSocket.cpp index 7dbcc4e1..b21cbd5e 100644 --- a/node/TcpSocket.cpp +++ b/node/TcpSocket.cpp @@ -72,7 +72,6 @@ bool TcpSocket::send(const InetAddress &to,const void *msg,unsigned int msglen) return true; // sanity check Mutex::Lock _l(_writeLock); - bool writeInProgress = ((_outptr != 0)||(_connecting)); // Ensure that _outbuf is large enough @@ -144,9 +143,10 @@ bool TcpSocket::notifyAvailableForRead(const SharedPtr<Socket> &self,SocketManag if ((pl)&&(p >= pl)) { Buffer<ZT_SOCKET_MAX_MESSAGE_LEN> data(_inbuf + 5,pl - 5); - sm->handleReceivedPacket(self,_remote,data); - memmove(_inbuf,_inbuf + pl,p - pl); - p -= pl; + memmove(_inbuf,_inbuf + pl,p -= pl); + try { + sm->handleReceivedPacket(self,_remote,data); + } catch ( ... ) {} // handlers should not throw pl = 0; } } diff --git a/node/TcpSocket.hpp b/node/TcpSocket.hpp index ea2b0ddf..8a9a7095 100644 --- a/node/TcpSocket.hpp +++ b/node/TcpSocket.hpp @@ -71,11 +71,11 @@ public: protected: #ifdef __WINDOWS__ - TcpSocket(SocketManager *sm,SOCKET s,bool c,const InetAddress &r) : + TcpSocket(SocketManager *sm,SOCKET s,Socket::Type t,bool c,const InetAddress &r) : #else - TcpSocket(SocketManager *sm,int s,bool c,const InetAddress &r) : + TcpSocket(SocketManager *sm,int s,Socket::Type t,bool c,const InetAddress &r) : #endif - Socket(Socket::ZT_SOCKET_TYPE_TCP,s), + Socket(t,s), _lastActivity(Utils::now()), _sm(sm), _outbuf((unsigned char *)0), diff --git a/node/Topology.cpp b/node/Topology.cpp index 6390a338..d4df3ce6 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -65,7 +65,7 @@ void Topology::setSupernodes(const std::map< Identity,std::vector< std::pair<Ine if (!p) p = addPeer(SharedPtr<Peer>(new Peer(_r->identity,i->first))); for(std::vector< std::pair<InetAddress,bool> >::const_iterator j(i->second.begin());j!=i->second.end();++j) - p->addPath(Path(j->first,j->second,true)); + p->addPath(Path(j->first,(j->second) ? Path::PATH_TYPE_TCP_OUT : Path::PATH_TYPE_UDP,true)); p->use(now); _supernodePeers.push_back(p); } |