diff options
-rw-r--r-- | include/ZeroTierOne.h | 28 | ||||
-rw-r--r-- | node/Node.cpp | 24 | ||||
-rw-r--r-- | node/Node.hpp | 38 | ||||
-rw-r--r-- | node/Path.hpp | 26 | ||||
-rw-r--r-- | node/Peer.cpp | 26 | ||||
-rw-r--r-- | node/Peer.hpp | 30 | ||||
-rw-r--r-- | node/Switch.cpp | 32 | ||||
-rw-r--r-- | node/Switch.hpp | 13 | ||||
-rw-r--r-- | node/Topology.cpp | 2 | ||||
-rw-r--r-- | node/Topology.hpp | 2 |
10 files changed, 99 insertions, 122 deletions
diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index 90f92b4a..583a75ca 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -408,9 +408,9 @@ typedef struct * What trust hierarchy role does this peer have? */ enum ZT1_PeerRole { - ZT1_PEER_ROLE_NODE = 0 // ordinary node - ZT1_PEER_ROLE_HUB = 1, // locally federated hub - ZT1_PEER_ROLE_SUPERNODE = 2, // planetary supernode + ZT1_PEER_ROLE_NODE = 0, // ordinary node + ZT1_PEER_ROLE_HUB = 1, // locally federated hub + ZT1_PEER_ROLE_SUPERNODE = 2 // planetary supernode }; /** @@ -541,18 +541,14 @@ typedef int (*ZT1_DataStorePutFunction)(ZT1_Node *,const char *,const void *,uns /** * Function to send a ZeroTier packet out over the wire * - * Parameters: (1) node, (2) address, (3) desperation, (4) spam? (bool), - * (5) packet data, (6) packet data length. - * - * If spam is nonzero, the implementation should attempt to send the packet - * over all link types or protocols up to and including the stated level of - * desperation. Non-applicable link types can of course be skipped. + * Parameters: (1) node, (2) address, (3) link desperation, + * (4) packet data, (5) packet data length. * * The function must return zero on success and may return any error code * on failure. Note that success does not (of course) guarantee packet * delivery. It only means that the packet appears to have been sent. */ -typedef int (*ZT1_WirePacketSendFunction)(ZT1_Node *,const struct sockaddr_storage *,int,int,const void *,unsigned int); +typedef int (*ZT1_WirePacketSendFunction)(ZT1_Node *,const struct sockaddr_storage *,int,const void *,unsigned int); /** * Function to send a frame out to a virtual network port @@ -583,12 +579,12 @@ typedef void (*ZT1_VirtualNetworkFrameFunction)(ZT1_Node *,uint64_t,uint64_t,uin enum ZT1_ResultCode ZT1_Node_new( ZT1_Node **node, uint64_t now, - ZT1_DataStoreGetFunction *dataStoreGetFunction, - ZT1_DataStorePutFunction *dataStorePutFunction, - ZT1_WirePacketSendFunction *wirePacketSendFunction, - ZT1_VirtualNetworkFrameFunction *virtualNetworkFrameFunction, - ZT1_VirtualNetworkConfigCallback *virtualNetworkConfigCallback, - ZT1_StatusCallback *statusCallback); + ZT1_DataStoreGetFunction dataStoreGetFunction, + ZT1_DataStorePutFunction dataStorePutFunction, + ZT1_WirePacketSendFunction wirePacketSendFunction, + ZT1_VirtualNetworkFrameFunction virtualNetworkFrameFunction, + ZT1_VirtualNetworkConfigCallback virtualNetworkConfigCallback, + ZT1_StatusCallback statusCallback); /** * Process a packet received from the physical wire diff --git a/node/Node.cpp b/node/Node.cpp index 936a5b60..370e35d6 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -46,12 +46,12 @@ namespace ZeroTier { Node::Node( uint64_t now, - ZT1_DataStoreGetFunction *dataStoreGetFunction, - ZT1_DataStorePutFunction *dataStorePutFunction, - ZT1_WirePacketSendFunction *wirePacketSendFunction, - ZT1_VirtualNetworkFrameFunction *virtualNetworkFrameFunction, - ZT1_VirtualNetworkConfigCallback *virtualNetworkConfigCallback, - ZT1_StatusCallback *statusCallback) : + ZT1_DataStoreGetFunction dataStoreGetFunction, + ZT1_DataStorePutFunction dataStorePutFunction, + ZT1_WirePacketSendFunction wirePacketSendFunction, + ZT1_VirtualNetworkFrameFunction virtualNetworkFrameFunction, + ZT1_VirtualNetworkConfigCallback virtualNetworkConfigCallback, + ZT1_StatusCallback statusCallback) : RR(new RuntimeEnvironment(this)), _dataStoreGetFunction(dataStoreGetFunction), _dataStorePutFunction(dataStorePutFunction), @@ -183,12 +183,12 @@ extern "C" { enum ZT1_ResultCode ZT1_Node_new( ZT1_Node **node, uint64_t now, - ZT1_DataStoreGetFunction *dataStoreGetFunction, - ZT1_DataStorePutFunction *dataStorePutFunction, - ZT1_WirePacketSendFunction *wirePacketSendFunction, - ZT1_VirtualNetworkFrameFunction *virtualNetworkFrameFunction, - ZT1_VirtualNetworkConfigCallback *virtualNetworkConfigCallback, - ZT1_StatusCallback *statusCallback) + ZT1_DataStoreGetFunction dataStoreGetFunction, + ZT1_DataStorePutFunction dataStorePutFunction, + ZT1_WirePacketSendFunction wirePacketSendFunction, + ZT1_VirtualNetworkFrameFunction virtualNetworkFrameFunction, + ZT1_VirtualNetworkConfigCallback virtualNetworkConfigCallback, + ZT1_StatusCallback statusCallback) { *node = (ZT1_Node *)0; try { diff --git a/node/Node.hpp b/node/Node.hpp index f7cab5f7..385d60a4 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -57,12 +57,12 @@ class Node public: Node( uint64_t now, - ZT1_DataStoreGetFunction *dataStoreGetFunction, - ZT1_DataStorePutFunction *dataStorePutFunction, - ZT1_WirePacketSendFunction *wirePacketSendFunction, - ZT1_VirtualNetworkFrameFunction *virtualNetworkFrameFunction, - ZT1_VirtualNetworkConfigCallback *virtualNetworkConfigCallback, - ZT1_StatusCallback *statusCallback); + ZT1_DataStoreGetFunction dataStoreGetFunction, + ZT1_DataStorePutFunction dataStorePutFunction, + ZT1_WirePacketSendFunction wirePacketSendFunction, + ZT1_VirtualNetworkFrameFunction virtualNetworkFrameFunction, + ZT1_VirtualNetworkConfigCallback virtualNetworkConfigCallback, + ZT1_StatusCallback statusCallback); ~Node(); @@ -85,7 +85,7 @@ public: const void *frameData, unsigned int frameLength, uint64_t *nextCallDeadline); - ZT1_Resultcode processNothing(uint64_t now,uint64_t *nextCallDeadline); + ZT1_ResultCode processNothing(uint64_t now,uint64_t *nextCallDeadline); ZT1_ResultCode join(uint64_t nwid); ZT1_ResultCode leave(uint64_t nwid); ZT1_ResultCode multicastSubscribe(ZT1_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi = 0); @@ -111,16 +111,14 @@ public: * @param data Packet data * @param len Packet length * @param desperation Link desperation for reaching this address - * @param spam If true, flag this packet to be spammed to lower-desperation links * @return True if packet appears to have been sent */ - inline bool putPacket(const InetAddress &addr,const void *data,unsigned int len,int desperation,bool spam) + inline bool putPacket(const InetAddress &addr,const void *data,unsigned int len,int desperation) { return (_wirePacketSendFunction( reinterpret_cast<ZT1_Node *>(this), reinterpret_cast<const struct sockaddr_storage *>(&addr), desperation, - (int)spam, data, len) == 0); } @@ -160,28 +158,24 @@ public: return ((nw == _networks.end()) ? SharedPtr<Network>() : nw->second); } - inline bool dataStorePut(const char *name,const void *data,unsigned int len,bool secure) - { - } + inline bool dataStorePut(const char *name,const void *data,unsigned int len,bool secure) { return (_dataStorePutFunction(reinterpret_cast<ZT1_Node *>(this),name,data,len,(int)secure) == 0); } inline bool dataStorePut(const char *name,const std::string &data,bool secure) { return dataStorePut(name,(const void *)data.data(),(unsigned int)data.length(),secure); } inline std::string dataStoreGet(const char *name) { } - inline void dataStoreDelete(const char *name) - { - } + inline void dataStoreDelete(const char *name) { _dataStorePutFunction(reinterpret_cast<ZT1_Node *>(this),name,(const void *)0,0,0); } private: RuntimeEnvironment *RR; - ZT1_DataStoreGetFunction *_dataStoreGetFunction; - ZT1_DataStorePutFunction *_dataStorePutFunction; - ZT1_WirePacketSendFunction *_wirePacketSendFunction; - ZT1_VirtualNetworkFrameFunction *_virtualNetworkFrameFunction; - ZT1_VirtualNetworkConfigCallback *_virtualNetworkConfigCallback; - ZT1_StatusCallback *_statusCallback; + ZT1_DataStoreGetFunction _dataStoreGetFunction; + ZT1_DataStorePutFunction _dataStorePutFunction; + ZT1_WirePacketSendFunction _wirePacketSendFunction; + ZT1_VirtualNetworkFrameFunction _virtualNetworkFrameFunction; + ZT1_VirtualNetworkConfigCallback _virtualNetworkConfigCallback; + ZT1_StatusCallback _statusCallback; //Dictionary _localConfig; // persisted as local.conf //Mutex _localConfig_m; diff --git a/node/Path.hpp b/node/Path.hpp index df68339e..1adb8f99 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -36,8 +36,11 @@ #include <algorithm> #include "Constants.hpp" +#include "Node.hpp" #include "InetAddress.hpp" #include "Utils.hpp" +#include "AntiRecursion.hpp" +#include "RuntimeEnvironment.hpp" namespace ZeroTier { @@ -91,6 +94,8 @@ public: /** * Called when a packet is sent to this path * + * This is called automatically by Path::send(). + * * @param t Time of send */ inline void sent(uint64_t t) throw() { _lastSend = t; } @@ -128,7 +133,7 @@ public: */ inline int desperation(uint64_t now) const { - if ((_lastSend > _lastReceived)&&(_fixed)) + if ((_fixed)&&(_lastSend > _lastReceived)) return std::max(_lastReceiveDesperation,(int)((_lastSend - _lastReceived) / ZT_DESPERATION_INCREMENT)); return _lastReceiveDesperation; } @@ -144,6 +149,25 @@ public: } /** + * Send a packet via this path + * + * @param RR Runtime environment + * @param data Packet data + * @param len Packet length + * @param now Current time + * @return True if transport reported success + */ + inline bool send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) + { + if (RR->node->putPacket(_addr,data,len,desperation(now))) { + sent(now); + RR->antiRec->logOutgoingZT(data,len); + return true; + } + return false; + } + + /** * @param now Current time * @return Human-readable address and other information about this path */ diff --git a/node/Peer.cpp b/node/Peer.cpp index 294c02bf..0bff2aae 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -43,7 +43,6 @@ Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity) _lastUnicastFrame(0), _lastMulticastFrame(0), _lastAnnouncedTo(0), - _lastSpammed(0), _vMajor(0), _vMinor(0), _vRevision(0), @@ -147,31 +146,6 @@ void Peer::received( _lastMulticastFrame = now; } -bool Peer::send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now) -{ - Path *bestPath = (Path *)0; - uint64_t lrMax = 0; - for(unsigned int p=0,np=_numPaths;p<np;++p) { - if ((_paths[p].active(now)&&(_paths[p].lastReceived() >= lrMax)) { - lrMax = _paths[p].lastReceived(); - bestPath = &(_paths[p]); - } - } - - if (bestPath) { - bool spam = ((now - _lastSpammed) >= ZT_DESPERATION_SPAM_INTERVAL); - if (RR->node->putPacket(bestPath->address(),data,len,bestPath->desperation(),spam)) { - bestPath->sent(now); - RR->antiRec->logOutgoingZT(data,len); - if (spam) - _lastSpammed = now; - return true; - } - } - - return false; -} - void Peer::addPath(const Path &newp) { unsigned int np = _numPaths; diff --git a/node/Peer.hpp b/node/Peer.hpp index 67efde1f..9774ecad 100644 --- a/node/Peer.hpp +++ b/node/Peer.hpp @@ -132,18 +132,23 @@ public: Packet::Verb inReVerb = Packet::VERB_NOP); /** - * Send a packet directly to this peer + * Get the best direct path to this peer * - * This sends only via direct paths if available and does not handle - * finding of relays. That is done in the send logic in Switch. - * - * @param RR Runtime environment - * @param data Data to send - * @param len Length of packet * @param now Current time - * @return True if packet appears to have been sent via some available path + * @return Best path or NULL if there are no active (or fixed) direct paths */ - bool send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now); + Path *getBestPath(uint64_t now) + { + Path *bestPath = (Path *)0; + uint64_t lrMax = 0; + for(unsigned int p=0,np=_numPaths;p<np;++p) { + if ((_paths[p].active(now))&&(_paths[p].lastReceived() >= lrMax)) { + lrMax = _paths[p].lastReceived(); + bestPath = &(_paths[p]); + } + } + return bestPath; + } /** * @return All known direct paths to this peer @@ -359,25 +364,20 @@ private: void _announceMulticastGroups(const RuntimeEnvironment *RR,uint64_t now); unsigned char _key[ZT_PEER_SECRET_KEY_LENGTH]; - uint64_t _lastUsed; uint64_t _lastReceive; // direct or indirect uint64_t _lastUnicastFrame; uint64_t _lastMulticastFrame; uint64_t _lastAnnouncedTo; - uint64_t _lastSpammed; uint16_t _vProto; uint16_t _vMajor; uint16_t _vMinor; uint16_t _vRevision; - Identity _id; - Path _paths[ZT_PEER_MAX_PATHS]; unsigned int _numPaths; - unsigned int _latency; - unsigned int _spamCounter; + AtomicCounter __refCount; }; diff --git a/node/Switch.cpp b/node/Switch.cpp index ec66586d..fe8282ed 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -32,13 +32,10 @@ #include <utility> #include <stdexcept> -#include "Constants.hpp" - -#ifdef __WINDOWS__ -#include <WinSock2.h> -#include <Windows.h> -#endif +#include "../version.h" +#include "../include/ZeroTierOne.h" +#include "Constants.hpp" #include "Switch.hpp" #include "Node.hpp" #include "EthernetTap.hpp" @@ -50,8 +47,6 @@ #include "CMWC4096.hpp" #include "AntiRecursion.hpp" -#include "../version.h" - namespace ZeroTier { Switch::Switch(const RuntimeEnvironment *renv) : @@ -64,16 +59,17 @@ Switch::~Switch() { } -void Switch::onRemotePacket(const SharedPtr<Socket> &fromSock,const InetAddress &fromAddr,Buffer<ZT_SOCKET_MAX_MESSAGE_LEN> &data) +void Switch::onRemotePacket(const InetAddress &fromAddr,int linkDesperation,const Buffer<4096> &data) { try { if (data.size() == ZT_PROTO_BEACON_LENGTH) { - _handleBeacon(fromSock,fromAddr,data); + _handleBeacon(fromAddr,linkDesperation,data); } else if (data.size() > ZT_PROTO_MIN_FRAGMENT_LENGTH) { - if (data[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR] == ZT_PACKET_FRAGMENT_INDICATOR) - _handleRemotePacketFragment(fromSock,fromAddr,data); - else if (data.size() >= ZT_PROTO_MIN_PACKET_LENGTH) - _handleRemotePacketHead(fromSock,fromAddr,data); + if (data[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR] == ZT_PACKET_FRAGMENT_INDICATOR) { + _handleRemotePacketFragment(fromAddr,linkDesperation,data); + } else if (data.size() >= ZT_PROTO_MIN_PACKET_LENGTH) { + _handleRemotePacketHead(fromAddr,linkDesperation,data); + } } } catch (std::exception &ex) { TRACE("dropped packet from %s: unexpected exception: %s",fromAddr.toString().c_str(),ex.what()); @@ -376,7 +372,7 @@ void Switch::contact(const SharedPtr<Peer> &peer,const InetAddress &atAddr) { // Send simple packet directly to indicated address -- works for most NATs sendHELLO(peer,atAddr); - TRACE("sending NAT-t HELLO to %s(%s)",peer->address().toString().c_str(),atAddr.toString().c_str()); + TRACE("sending NAT-t message to %s(%s)",peer->address().toString().c_str(),atAddr.toString().c_str()); // If we have not punched through after this timeout, open refreshing can of whupass { @@ -543,7 +539,7 @@ const char *Switch::etherTypeName(const unsigned int etherType) return "UNKNOWN"; } -void Switch::_handleRemotePacketFragment(const SharedPtr<Socket> &fromSock,const InetAddress &fromAddr,const Buffer<4096> &data) +void Switch::_handleRemotePacketFragment(const InetAddress &fromAddr,int linkDesperation,const Buffer<4096> &data) { Packet::Fragment fragment(data); Address destination(fragment.destination()); @@ -615,7 +611,7 @@ void Switch::_handleRemotePacketFragment(const SharedPtr<Socket> &fromSock,const } } -void Switch::_handleRemotePacketHead(const SharedPtr<Socket> &fromSock,const InetAddress &fromAddr,const Buffer<4096> &data) +void Switch::_handleRemotePacketHead(const InetAddress &fromAddr,int linkDesperation,const Buffer<4096> &data) { SharedPtr<IncomingPacket> packet(new IncomingPacket(data,fromSock,fromAddr)); @@ -690,7 +686,7 @@ void Switch::_handleRemotePacketHead(const SharedPtr<Socket> &fromSock,const Ine } } -void Switch::_handleBeacon(const SharedPtr<Socket> &fromSock,const InetAddress &fromAddr,const Buffer<4096> &data) +void Switch::_handleBeacon(const InetAddress &fromAddr,int linkDesperation,const Buffer<4096> &data) { Address beaconAddr(data.field(ZT_PROTO_BEACON_IDX_ADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); if (beaconAddr == RR->identity.address()) diff --git a/node/Switch.hpp b/node/Switch.hpp index b5da54a0..d5d1335f 100644 --- a/node/Switch.hpp +++ b/node/Switch.hpp @@ -45,7 +45,6 @@ #include "Network.hpp" #include "SharedPtr.hpp" #include "IncomingPacket.hpp" -#include "Socket.hpp" /* Ethernet frame types that might be relevant to us */ #define ZT_ETHERTYPE_IPV4 0x0800 @@ -60,9 +59,7 @@ namespace ZeroTier { class RuntimeEnvironment; -class EthernetTap; class Logger; -class Node; class Peer; /** @@ -82,11 +79,11 @@ public: /** * Called when a packet is received from the real network * - * @param fromSock Originating socket * @param fromAddr Internet IP address of origin + * @param linkDesperation Link desperation of path over which packet was received * @param data Packet data */ - void onRemotePacket(const SharedPtr<Socket> &fromSock,const InetAddress &fromAddr,Buffer<ZT_SOCKET_MAX_MESSAGE_LEN> &data); + void onRemotePacket(const InetAddress &fromAddr,int linkDesperation,const Buffer<4096> &data); /** * Called when a packet comes from a local Ethernet tap @@ -178,9 +175,9 @@ public: throw(); private: - void _handleRemotePacketFragment(const SharedPtr<Socket> &fromSock,const InetAddress &fromAddr,const Buffer<4096> &data); - void _handleRemotePacketHead(const SharedPtr<Socket> &fromSock,const InetAddress &fromAddr,const Buffer<4096> &data); - void _handleBeacon(const SharedPtr<Socket> &fromSock,const InetAddress &fromAddr,const Buffer<4096> &data); + void _handleRemotePacketFragment(const InetAddress &fromAddr,int linkDesperation,const Buffer<4096> &data); + void _handleRemotePacketHead(const InetAddress &fromAddr,int linkDesperation,const Buffer<4096> &data); + void _handleBeacon(const InetAddress &fromAddr,int linkDesperation,const Buffer<4096> &data); Address _sendWhoisRequest( const Address &addr, diff --git a/node/Topology.cpp b/node/Topology.cpp index 99361cff..77583d55 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -32,8 +32,6 @@ #include "CMWC4096.hpp" #include "Dictionary.hpp" -#define ZT_PEER_WRITE_BUF_SIZE 131072 - namespace ZeroTier { Topology::Topology(const RuntimeEnvironment *renv) : diff --git a/node/Topology.hpp b/node/Topology.hpp index ec8de5d0..ca86b2e3 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -44,8 +44,6 @@ #include "Mutex.hpp" #include "InetAddress.hpp" #include "Utils.hpp" -#include "Packet.hpp" -#include "Logger.hpp" #include "Dictionary.hpp" #include "ExternalSurface.hpp" |