mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-01-21 03:55:19 +00:00
Merge branch 'dev' into edge
This commit is contained in:
commit
ba9fcb31d0
@ -1097,13 +1097,42 @@ typedef int (*ZT_DataStorePutFunction)(
|
|||||||
* delivery. It only means that the packet appears to have been sent.
|
* delivery. It only means that the packet appears to have been sent.
|
||||||
*/
|
*/
|
||||||
typedef int (*ZT_WirePacketSendFunction)(
|
typedef int (*ZT_WirePacketSendFunction)(
|
||||||
ZT_Node *, /* Node */
|
ZT_Node *, /* Node */
|
||||||
void *, /* User ptr */
|
void *, /* User ptr */
|
||||||
const struct sockaddr_storage *, /* Local address */
|
const struct sockaddr_storage *, /* Local address */
|
||||||
const struct sockaddr_storage *, /* Remote address */
|
const struct sockaddr_storage *, /* Remote address */
|
||||||
const void *, /* Packet data */
|
const void *, /* Packet data */
|
||||||
unsigned int, /* Packet length */
|
unsigned int, /* Packet length */
|
||||||
unsigned int); /* TTL or 0 to use default */
|
unsigned int); /* TTL or 0 to use default */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to check whether a path should be used for ZeroTier traffic
|
||||||
|
*
|
||||||
|
* Paramters:
|
||||||
|
* (1) Node
|
||||||
|
* (2) User pointer
|
||||||
|
* (3) Local interface address
|
||||||
|
* (4) Remote address
|
||||||
|
*
|
||||||
|
* This function must return nonzero (true) if the path should be used.
|
||||||
|
*
|
||||||
|
* If no path check function is specified, ZeroTier will still exclude paths
|
||||||
|
* that overlap with ZeroTier-assigned and managed IP address blocks. But the
|
||||||
|
* use of a path check function is recommended to ensure that recursion does
|
||||||
|
* not occur in cases where addresses are assigned by the OS or managed by
|
||||||
|
* an out of band mechanism like DHCP. The path check function should examine
|
||||||
|
* all configured ZeroTier interfaces and check to ensure that the supplied
|
||||||
|
* addresses will not result in ZeroTier traffic being sent over a ZeroTier
|
||||||
|
* interface (recursion).
|
||||||
|
*
|
||||||
|
* Obviously this is not required in configurations where this can't happen,
|
||||||
|
* such as network containers or embedded.
|
||||||
|
*/
|
||||||
|
typedef int (*ZT_PathCheckFunction)(
|
||||||
|
ZT_Node *, /* Node */
|
||||||
|
void *, /* User ptr */
|
||||||
|
const struct sockaddr_storage *, /* Local address */
|
||||||
|
const struct sockaddr_storage *); /* Remote address */
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/* C Node API */
|
/* C Node API */
|
||||||
@ -1121,6 +1150,7 @@ typedef int (*ZT_WirePacketSendFunction)(
|
|||||||
* @param dataStoreGetFunction Function called to get objects from persistent storage
|
* @param dataStoreGetFunction Function called to get objects from persistent storage
|
||||||
* @param dataStorePutFunction Function called to put objects in persistent storage
|
* @param dataStorePutFunction Function called to put objects in persistent storage
|
||||||
* @param virtualNetworkConfigFunction Function to be called when virtual LANs are created, deleted, or their config parameters change
|
* @param virtualNetworkConfigFunction Function to be called when virtual LANs are created, deleted, or their config parameters change
|
||||||
|
* @param pathCheckFunction A function to check whether a path should be used for ZeroTier traffic, or NULL to allow any path
|
||||||
* @param eventCallback Function to receive status updates and non-fatal error notices
|
* @param eventCallback Function to receive status updates and non-fatal error notices
|
||||||
* @return OK (0) or error code if a fatal error condition has occurred
|
* @return OK (0) or error code if a fatal error condition has occurred
|
||||||
*/
|
*/
|
||||||
@ -1133,6 +1163,7 @@ enum ZT_ResultCode ZT_Node_new(
|
|||||||
ZT_WirePacketSendFunction wirePacketSendFunction,
|
ZT_WirePacketSendFunction wirePacketSendFunction,
|
||||||
ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction,
|
ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction,
|
||||||
ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction,
|
ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction,
|
||||||
|
ZT_PathCheckFunction pathCheckFunction,
|
||||||
ZT_EventCallback eventCallback);
|
ZT_EventCallback eventCallback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1334,18 +1365,21 @@ void ZT_Node_freeQueryResult(ZT_Node *node,void *qr);
|
|||||||
/**
|
/**
|
||||||
* Add a local interface address
|
* Add a local interface address
|
||||||
*
|
*
|
||||||
* Take care that these are never ZeroTier interface addresses, otherwise
|
* This is used to make ZeroTier aware of those local interface addresses
|
||||||
* strange things might happen or they simply won't work.
|
* that you wish to use for ZeroTier communication. This is optional, and if
|
||||||
|
* it is not used ZeroTier will rely upon upstream peers (and roots) to
|
||||||
|
* perform empirical address discovery and NAT traversal. But the use of this
|
||||||
|
* method is recommended as it improves peer discovery when both peers are
|
||||||
|
* on the same LAN.
|
||||||
*
|
*
|
||||||
* Addresses can also be added here if they are the result of a UPnP or
|
* It is the responsibility of the caller to take care that these are never
|
||||||
* NAT-PMP port mapping or other discovery or mapping means.
|
* ZeroTier interface addresses, whether these are assigned by ZeroTier or
|
||||||
|
* are otherwise assigned to an interface managed by this ZeroTier instance.
|
||||||
|
* This can cause recursion or other undesirable behavior.
|
||||||
*
|
*
|
||||||
* This returns a boolean indicating whether or not the address was
|
* This returns a boolean indicating whether or not the address was
|
||||||
* accepted. ZeroTier will only communicate over certain address types
|
* accepted. ZeroTier will only communicate over certain address types
|
||||||
* and (for IP) address classes. Thus it's safe to just dump your OS's
|
* and (for IP) address classes.
|
||||||
* entire remote IP list (excluding ZeroTier interface IPs) into here
|
|
||||||
* and let ZeroTier determine which addresses it will use. It will
|
|
||||||
* reject bad, empty, and unusable addresses.
|
|
||||||
*
|
*
|
||||||
* @param addr Local interface address
|
* @param addr Local interface address
|
||||||
* @return Boolean: non-zero if address was accepted and added
|
* @return Boolean: non-zero if address was accepted and added
|
||||||
|
@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Network Virtualization Everywhere
|
|
||||||
* Copyright (C) 2011-2015 ZeroTier, Inc.
|
|
||||||
*
|
|
||||||
* 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_ANTIRECURSION_HPP
|
|
||||||
#define ZT_ANTIRECURSION_HPP
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "Constants.hpp"
|
|
||||||
|
|
||||||
namespace ZeroTier {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Size of anti-recursion history
|
|
||||||
*/
|
|
||||||
#define ZT_ANTIRECURSION_HISTORY_SIZE 16
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter to prevent recursion (ZeroTier-over-ZeroTier)
|
|
||||||
*
|
|
||||||
* This works by logging ZeroTier packets that we send. It's then invoked
|
|
||||||
* again against packets read from local Ethernet taps. If the last 32
|
|
||||||
* bytes representing the ZeroTier packet match in the tap frame, then
|
|
||||||
* the frame is a re-injection of a frame that we sent and is rejected.
|
|
||||||
*
|
|
||||||
* This means that ZeroTier packets simply will not traverse ZeroTier
|
|
||||||
* networks, which would cause all sorts of weird problems.
|
|
||||||
*
|
|
||||||
* This is highly optimized code since it's checked for every packet.
|
|
||||||
*/
|
|
||||||
class AntiRecursion
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AntiRecursion()
|
|
||||||
{
|
|
||||||
for(int i=0;i<ZT_ANTIRECURSION_HISTORY_SIZE;++i) {
|
|
||||||
_history[i].tail[0] = 0;
|
|
||||||
_history[i].tail[1] = 0;
|
|
||||||
_history[i].tail[2] = 0;
|
|
||||||
_history[i].tail[3] = 0;
|
|
||||||
}
|
|
||||||
_ptr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an outgoing ZeroTier packet to the circular log
|
|
||||||
*
|
|
||||||
* @param data ZT packet data
|
|
||||||
* @param len Length of packet
|
|
||||||
*/
|
|
||||||
inline void logOutgoingZT(const void *const data,const unsigned int len)
|
|
||||||
{
|
|
||||||
if (len < 32)
|
|
||||||
return;
|
|
||||||
#ifdef ZT_NO_TYPE_PUNNING
|
|
||||||
memcpy(_history[++_ptr % ZT_ANTIRECURSION_HISTORY_SIZE].tail,reinterpret_cast<const uint8_t *>(data) + (len - 32),32);
|
|
||||||
#else
|
|
||||||
uint64_t *t = _history[++_ptr % ZT_ANTIRECURSION_HISTORY_SIZE].tail;
|
|
||||||
const uint64_t *p = reinterpret_cast<const uint64_t *>(reinterpret_cast<const uint8_t *>(data) + (len - 32));
|
|
||||||
*(t++) = *(p++);
|
|
||||||
*(t++) = *(p++);
|
|
||||||
*(t++) = *(p++);
|
|
||||||
*t = *p;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check an ethernet frame from a local tap against anti-recursion history
|
|
||||||
*
|
|
||||||
* @param data Raw frame data
|
|
||||||
* @param len Length of frame
|
|
||||||
* @return True if frame is OK to be passed, false if it's a ZT frame that we sent
|
|
||||||
*/
|
|
||||||
inline bool checkEthernetFrame(const void *const data,const unsigned int len) const
|
|
||||||
{
|
|
||||||
if (len < 32)
|
|
||||||
return true;
|
|
||||||
const uint8_t *const pp = reinterpret_cast<const uint8_t *>(data) + (len - 32);
|
|
||||||
const _ArItem *i = _history;
|
|
||||||
const _ArItem *const end = i + ZT_ANTIRECURSION_HISTORY_SIZE;
|
|
||||||
while (i != end) {
|
|
||||||
#ifdef ZT_NO_TYPE_PUNNING
|
|
||||||
if (!memcmp(pp,i->tail,32)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
const uint64_t *t = i->tail;
|
|
||||||
const uint64_t *p = reinterpret_cast<const uint64_t *>(pp);
|
|
||||||
uint64_t bits = *(t++) ^ *(p++);
|
|
||||||
bits |= *(t++) ^ *(p++);
|
|
||||||
bits |= *(t++) ^ *(p++);
|
|
||||||
bits |= *t ^ *p;
|
|
||||||
if (!bits) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct _ArItem { uint64_t tail[4]; };
|
|
||||||
_ArItem _history[ZT_ANTIRECURSION_HISTORY_SIZE];
|
|
||||||
volatile unsigned long _ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ZeroTier
|
|
||||||
|
|
||||||
#endif
|
|
@ -45,7 +45,6 @@
|
|||||||
#include "World.hpp"
|
#include "World.hpp"
|
||||||
#include "Cluster.hpp"
|
#include "Cluster.hpp"
|
||||||
#include "Node.hpp"
|
#include "Node.hpp"
|
||||||
#include "AntiRecursion.hpp"
|
|
||||||
#include "DeferredPackets.hpp"
|
#include "DeferredPackets.hpp"
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
@ -163,7 +162,6 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer>
|
|||||||
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE);
|
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE);
|
||||||
nconf->com().serialize(outp);
|
nconf->com().serialize(outp);
|
||||||
outp.armor(peer->key(),true);
|
outp.armor(peer->key(),true);
|
||||||
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
||||||
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -345,7 +343,6 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,SharedPtr<Peer> &peer
|
|||||||
}
|
}
|
||||||
|
|
||||||
outp.armor(peer->key(),true);
|
outp.armor(peer->key(),true);
|
||||||
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
||||||
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
||||||
|
|
||||||
peer->setRemoteVersion(protoVersion,vMajor,vMinor,vRevision); // important for this to go first so received() knows the version
|
peer->setRemoteVersion(protoVersion,vMajor,vMinor,vRevision); // important for this to go first so received() knows the version
|
||||||
@ -483,7 +480,6 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr<Peer>
|
|||||||
outp.append(packetId());
|
outp.append(packetId());
|
||||||
queried.serialize(outp,false);
|
queried.serialize(outp,false);
|
||||||
outp.armor(peer->key(),true);
|
outp.armor(peer->key(),true);
|
||||||
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
||||||
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
||||||
} else {
|
} else {
|
||||||
#ifdef ZT_ENABLE_CLUSTER
|
#ifdef ZT_ENABLE_CLUSTER
|
||||||
@ -511,10 +507,12 @@ bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment *RR,const SharedPtr<
|
|||||||
const unsigned int port = at<uint16_t>(ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT);
|
const unsigned int port = at<uint16_t>(ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT);
|
||||||
const unsigned int addrlen = (*this)[ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN];
|
const unsigned int addrlen = (*this)[ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN];
|
||||||
if ((port > 0)&&((addrlen == 4)||(addrlen == 16))) {
|
if ((port > 0)&&((addrlen == 4)||(addrlen == 16))) {
|
||||||
|
peer->received(_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP);
|
||||||
|
|
||||||
InetAddress atAddr(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS,addrlen),addrlen,port);
|
InetAddress atAddr(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS,addrlen),addrlen,port);
|
||||||
TRACE("RENDEZVOUS from %s says %s might be at %s, starting NAT-t",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str());
|
TRACE("RENDEZVOUS from %s says %s might be at %s, starting NAT-t",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str());
|
||||||
peer->received(_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP);
|
if (RR->node->shouldUsePathForZeroTierTraffic(_localAddress,atAddr))
|
||||||
RR->sw->rendezvous(withPeer,_localAddress,atAddr);
|
RR->sw->rendezvous(withPeer,_localAddress,atAddr);
|
||||||
} else {
|
} else {
|
||||||
TRACE("dropped corrupt RENDEZVOUS from %s(%s) (bad address or port)",peer->address().toString().c_str(),_remoteAddress.toString().c_str());
|
TRACE("dropped corrupt RENDEZVOUS from %s(%s) (bad address or port)",peer->address().toString().c_str(),_remoteAddress.toString().c_str());
|
||||||
}
|
}
|
||||||
@ -644,7 +642,6 @@ bool IncomingPacket::_doECHO(const RuntimeEnvironment *RR,const SharedPtr<Peer>
|
|||||||
if (size() > ZT_PACKET_IDX_PAYLOAD)
|
if (size() > ZT_PACKET_IDX_PAYLOAD)
|
||||||
outp.append(reinterpret_cast<const unsigned char *>(data()) + ZT_PACKET_IDX_PAYLOAD,size() - ZT_PACKET_IDX_PAYLOAD);
|
outp.append(reinterpret_cast<const unsigned char *>(data()) + ZT_PACKET_IDX_PAYLOAD,size() - ZT_PACKET_IDX_PAYLOAD);
|
||||||
outp.armor(peer->key(),true);
|
outp.armor(peer->key(),true);
|
||||||
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
||||||
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
||||||
peer->received(_localAddress,_remoteAddress,hops(),pid,Packet::VERB_ECHO,0,Packet::VERB_NOP);
|
peer->received(_localAddress,_remoteAddress,hops(),pid,Packet::VERB_ECHO,0,Packet::VERB_NOP);
|
||||||
} catch ( ... ) {
|
} catch ( ... ) {
|
||||||
@ -722,7 +719,6 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
|
|||||||
if (outp.size() > ZT_PROTO_MAX_PACKET_LENGTH) { // sanity check
|
if (outp.size() > ZT_PROTO_MAX_PACKET_LENGTH) { // sanity check
|
||||||
TRACE("NETWORK_CONFIG_REQUEST failed: internal error: netconf size %u is too large",(unsigned int)netconfStr.length());
|
TRACE("NETWORK_CONFIG_REQUEST failed: internal error: netconf size %u is too large",(unsigned int)netconfStr.length());
|
||||||
} else {
|
} else {
|
||||||
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
||||||
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -735,7 +731,6 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
|
|||||||
outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND);
|
outp.append((unsigned char)Packet::ERROR_OBJ_NOT_FOUND);
|
||||||
outp.append(nwid);
|
outp.append(nwid);
|
||||||
outp.armor(peer->key(),true);
|
outp.armor(peer->key(),true);
|
||||||
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
||||||
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -746,7 +741,6 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
|
|||||||
outp.append((unsigned char)Packet::ERROR_NETWORK_ACCESS_DENIED_);
|
outp.append((unsigned char)Packet::ERROR_NETWORK_ACCESS_DENIED_);
|
||||||
outp.append(nwid);
|
outp.append(nwid);
|
||||||
outp.armor(peer->key(),true);
|
outp.armor(peer->key(),true);
|
||||||
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
||||||
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -769,7 +763,6 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
|
|||||||
outp.append((unsigned char)Packet::ERROR_UNSUPPORTED_OPERATION);
|
outp.append((unsigned char)Packet::ERROR_UNSUPPORTED_OPERATION);
|
||||||
outp.append(nwid);
|
outp.append(nwid);
|
||||||
outp.armor(peer->key(),true);
|
outp.armor(peer->key(),true);
|
||||||
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
||||||
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
||||||
}
|
}
|
||||||
} catch ( ... ) {
|
} catch ( ... ) {
|
||||||
@ -815,7 +808,6 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,const Shar
|
|||||||
const unsigned int gatheredLocally = RR->mc->gather(peer->address(),nwid,mg,outp,gatherLimit);
|
const unsigned int gatheredLocally = RR->mc->gather(peer->address(),nwid,mg,outp,gatherLimit);
|
||||||
if (gatheredLocally) {
|
if (gatheredLocally) {
|
||||||
outp.armor(peer->key(),true);
|
outp.armor(peer->key(),true);
|
||||||
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
||||||
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -909,7 +901,6 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share
|
|||||||
outp.append((unsigned char)0x02); // flag 0x02 = contains gather results
|
outp.append((unsigned char)0x02); // flag 0x02 = contains gather results
|
||||||
if (RR->mc->gather(peer->address(),nwid,to,outp,gatherLimit)) {
|
if (RR->mc->gather(peer->address(),nwid,to,outp,gatherLimit)) {
|
||||||
outp.armor(peer->key(),true);
|
outp.armor(peer->key(),true);
|
||||||
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
||||||
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -952,7 +943,7 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha
|
|||||||
switch(addrType) {
|
switch(addrType) {
|
||||||
case 4: {
|
case 4: {
|
||||||
InetAddress a(field(ptr,4),4,at<uint16_t>(ptr + 4));
|
InetAddress a(field(ptr,4),4,at<uint16_t>(ptr + 4));
|
||||||
if ( ((flags & 0x01) == 0) && (Path::isAddressValidForPath(a)) && (!peer->hasActivePathTo(now,a)) ) {
|
if ( ((flags & 0x01) == 0) && (Path::isAddressValidForPath(a)) && (!peer->hasActivePathTo(now,a)) && (RR->node->shouldUsePathForZeroTierTraffic(_localAddress,a)) ) {
|
||||||
if (++countPerScope[(int)a.ipScope()][0] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) {
|
if (++countPerScope[(int)a.ipScope()][0] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) {
|
||||||
TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str());
|
TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str());
|
||||||
peer->sendHELLO(_localAddress,a,now);
|
peer->sendHELLO(_localAddress,a,now);
|
||||||
@ -963,7 +954,7 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha
|
|||||||
} break;
|
} break;
|
||||||
case 6: {
|
case 6: {
|
||||||
InetAddress a(field(ptr,16),16,at<uint16_t>(ptr + 16));
|
InetAddress a(field(ptr,16),16,at<uint16_t>(ptr + 16));
|
||||||
if ( ((flags & 0x01) == 0) && (Path::isAddressValidForPath(a)) && (!peer->hasActivePathTo(now,a)) ) {
|
if ( ((flags & 0x01) == 0) && (Path::isAddressValidForPath(a)) && (!peer->hasActivePathTo(now,a)) && (RR->node->shouldUsePathForZeroTierTraffic(_localAddress,a)) ) {
|
||||||
if (++countPerScope[(int)a.ipScope()][1] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) {
|
if (++countPerScope[(int)a.ipScope()][1] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) {
|
||||||
TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str());
|
TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str());
|
||||||
peer->sendHELLO(_localAddress,a,now);
|
peer->sendHELLO(_localAddress,a,now);
|
||||||
@ -1220,7 +1211,6 @@ bool IncomingPacket::_doREQUEST_PROOF_OF_WORK(const RuntimeEnvironment *RR,const
|
|||||||
outp.append((uint16_t)sizeof(result));
|
outp.append((uint16_t)sizeof(result));
|
||||||
outp.append(result,sizeof(result));
|
outp.append(result,sizeof(result));
|
||||||
outp.armor(peer->key(),true);
|
outp.armor(peer->key(),true);
|
||||||
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
||||||
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
||||||
} else {
|
} else {
|
||||||
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR);
|
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ERROR);
|
||||||
@ -1228,7 +1218,6 @@ bool IncomingPacket::_doREQUEST_PROOF_OF_WORK(const RuntimeEnvironment *RR,const
|
|||||||
outp.append(pid);
|
outp.append(pid);
|
||||||
outp.append((unsigned char)Packet::ERROR_INVALID_REQUEST);
|
outp.append((unsigned char)Packet::ERROR_INVALID_REQUEST);
|
||||||
outp.armor(peer->key(),true);
|
outp.armor(peer->key(),true);
|
||||||
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
||||||
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -1334,7 +1323,6 @@ void IncomingPacket::_sendErrorNeedCertificate(const RuntimeEnvironment *RR,cons
|
|||||||
outp.append((unsigned char)Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE);
|
outp.append((unsigned char)Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE);
|
||||||
outp.append(nwid);
|
outp.append(nwid);
|
||||||
outp.armor(peer->key(),true);
|
outp.armor(peer->key(),true);
|
||||||
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
||||||
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,6 +280,30 @@ InetAddress InetAddress::network() const
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InetAddress::containsAddress(const InetAddress &addr) const
|
||||||
|
{
|
||||||
|
if (addr.ss_family == ss_family) {
|
||||||
|
switch(ss_family) {
|
||||||
|
case AF_INET: {
|
||||||
|
const unsigned int bits = netmaskBits();
|
||||||
|
return ( (Utils::ntoh((uint32_t)reinterpret_cast<const struct sockaddr_in *>(&addr)->sin_addr.s_addr) >> (32 - bits)) == (Utils::ntoh((uint32_t)reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr) >> (32 - bits)) );
|
||||||
|
}
|
||||||
|
case AF_INET6: {
|
||||||
|
const InetAddress mask(netmask());
|
||||||
|
const uint8_t *m = reinterpret_cast<const uint8_t *>(reinterpret_cast<const struct sockaddr_in6 *>(&mask)->sin6_addr.s6_addr);
|
||||||
|
const uint8_t *a = reinterpret_cast<const uint8_t *>(reinterpret_cast<const struct sockaddr_in6 *>(&addr)->sin6_addr.s6_addr);
|
||||||
|
const uint8_t *b = reinterpret_cast<const uint8_t *>(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr);
|
||||||
|
for(unsigned int i=0;i<16;++i) {
|
||||||
|
if ((a[i] & m[i]) != b[i])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool InetAddress::isNetwork() const
|
bool InetAddress::isNetwork() const
|
||||||
throw()
|
throw()
|
||||||
{
|
{
|
||||||
|
@ -325,6 +325,14 @@ struct InetAddress : public sockaddr_storage
|
|||||||
*/
|
*/
|
||||||
InetAddress network() const;
|
InetAddress network() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether this IP/netmask contains this address
|
||||||
|
*
|
||||||
|
* @param addr Address to check
|
||||||
|
* @return True if this IP/netmask (route) contains this address
|
||||||
|
*/
|
||||||
|
bool containsAddress(const InetAddress &addr) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return True if this is an IPv4 address
|
* @return True if this is an IPv4 address
|
||||||
*/
|
*/
|
||||||
|
@ -39,7 +39,6 @@
|
|||||||
#include "NetworkController.hpp"
|
#include "NetworkController.hpp"
|
||||||
#include "Switch.hpp"
|
#include "Switch.hpp"
|
||||||
#include "Multicaster.hpp"
|
#include "Multicaster.hpp"
|
||||||
#include "AntiRecursion.hpp"
|
|
||||||
#include "Topology.hpp"
|
#include "Topology.hpp"
|
||||||
#include "Buffer.hpp"
|
#include "Buffer.hpp"
|
||||||
#include "Packet.hpp"
|
#include "Packet.hpp"
|
||||||
@ -65,6 +64,7 @@ Node::Node(
|
|||||||
ZT_WirePacketSendFunction wirePacketSendFunction,
|
ZT_WirePacketSendFunction wirePacketSendFunction,
|
||||||
ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction,
|
ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction,
|
||||||
ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction,
|
ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction,
|
||||||
|
ZT_PathCheckFunction pathCheckFunction,
|
||||||
ZT_EventCallback eventCallback) :
|
ZT_EventCallback eventCallback) :
|
||||||
_RR(this),
|
_RR(this),
|
||||||
RR(&_RR),
|
RR(&_RR),
|
||||||
@ -74,6 +74,7 @@ Node::Node(
|
|||||||
_wirePacketSendFunction(wirePacketSendFunction),
|
_wirePacketSendFunction(wirePacketSendFunction),
|
||||||
_virtualNetworkFrameFunction(virtualNetworkFrameFunction),
|
_virtualNetworkFrameFunction(virtualNetworkFrameFunction),
|
||||||
_virtualNetworkConfigFunction(virtualNetworkConfigFunction),
|
_virtualNetworkConfigFunction(virtualNetworkConfigFunction),
|
||||||
|
_pathCheckFunction(pathCheckFunction),
|
||||||
_eventCallback(eventCallback),
|
_eventCallback(eventCallback),
|
||||||
_networks(),
|
_networks(),
|
||||||
_networks_m(),
|
_networks_m(),
|
||||||
@ -114,7 +115,6 @@ Node::Node(
|
|||||||
try {
|
try {
|
||||||
RR->sw = new Switch(RR);
|
RR->sw = new Switch(RR);
|
||||||
RR->mc = new Multicaster(RR);
|
RR->mc = new Multicaster(RR);
|
||||||
RR->antiRec = new AntiRecursion();
|
|
||||||
RR->topology = new Topology(RR);
|
RR->topology = new Topology(RR);
|
||||||
RR->sa = new SelfAwareness(RR);
|
RR->sa = new SelfAwareness(RR);
|
||||||
RR->dp = new DeferredPackets(RR);
|
RR->dp = new DeferredPackets(RR);
|
||||||
@ -122,7 +122,6 @@ Node::Node(
|
|||||||
delete RR->dp;
|
delete RR->dp;
|
||||||
delete RR->sa;
|
delete RR->sa;
|
||||||
delete RR->topology;
|
delete RR->topology;
|
||||||
delete RR->antiRec;
|
|
||||||
delete RR->mc;
|
delete RR->mc;
|
||||||
delete RR->sw;
|
delete RR->sw;
|
||||||
throw;
|
throw;
|
||||||
@ -141,7 +140,6 @@ Node::~Node()
|
|||||||
delete RR->dp;
|
delete RR->dp;
|
||||||
delete RR->sa;
|
delete RR->sa;
|
||||||
delete RR->topology;
|
delete RR->topology;
|
||||||
delete RR->antiRec;
|
|
||||||
delete RR->mc;
|
delete RR->mc;
|
||||||
delete RR->sw;
|
delete RR->sw;
|
||||||
#ifdef ZT_ENABLE_CLUSTER
|
#ifdef ZT_ENABLE_CLUSTER
|
||||||
@ -675,6 +673,27 @@ std::string Node::dataStoreGet(const char *name)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Node::shouldUsePathForZeroTierTraffic(const InetAddress &localAddress,const InetAddress &remoteAddress)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Mutex::Lock _l(_networks_m);
|
||||||
|
for(std::vector< std::pair< uint64_t, SharedPtr<Network> > >::const_iterator i=_networks.begin();i!=_networks.end();++i) {
|
||||||
|
SharedPtr<NetworkConfig> nc(i->second->config2());
|
||||||
|
if (nc) {
|
||||||
|
for(std::vector<InetAddress>::const_iterator a(nc->staticIps().begin());a!=nc->staticIps().end();++a) {
|
||||||
|
if (a->containsAddress(remoteAddress)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_pathCheckFunction)
|
||||||
|
return (_pathCheckFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,reinterpret_cast<const struct sockaddr_storage *>(&localAddress),reinterpret_cast<const struct sockaddr_storage *>(&remoteAddress)) != 0);
|
||||||
|
else return true;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ZT_TRACE
|
#ifdef ZT_TRACE
|
||||||
void Node::postTrace(const char *module,unsigned int line,const char *fmt,...)
|
void Node::postTrace(const char *module,unsigned int line,const char *fmt,...)
|
||||||
{
|
{
|
||||||
@ -747,11 +766,12 @@ enum ZT_ResultCode ZT_Node_new(
|
|||||||
ZT_WirePacketSendFunction wirePacketSendFunction,
|
ZT_WirePacketSendFunction wirePacketSendFunction,
|
||||||
ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction,
|
ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction,
|
||||||
ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction,
|
ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction,
|
||||||
|
ZT_PathCheckFunction pathCheckFunction,
|
||||||
ZT_EventCallback eventCallback)
|
ZT_EventCallback eventCallback)
|
||||||
{
|
{
|
||||||
*node = (ZT_Node *)0;
|
*node = (ZT_Node *)0;
|
||||||
try {
|
try {
|
||||||
*node = reinterpret_cast<ZT_Node *>(new ZeroTier::Node(now,uptr,dataStoreGetFunction,dataStorePutFunction,wirePacketSendFunction,virtualNetworkFrameFunction,virtualNetworkConfigFunction,eventCallback));
|
*node = reinterpret_cast<ZT_Node *>(new ZeroTier::Node(now,uptr,dataStoreGetFunction,dataStorePutFunction,wirePacketSendFunction,virtualNetworkFrameFunction,virtualNetworkConfigFunction,pathCheckFunction,eventCallback));
|
||||||
return ZT_RESULT_OK;
|
return ZT_RESULT_OK;
|
||||||
} catch (std::bad_alloc &exc) {
|
} catch (std::bad_alloc &exc) {
|
||||||
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||||
|
@ -71,6 +71,7 @@ public:
|
|||||||
ZT_WirePacketSendFunction wirePacketSendFunction,
|
ZT_WirePacketSendFunction wirePacketSendFunction,
|
||||||
ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction,
|
ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction,
|
||||||
ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction,
|
ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction,
|
||||||
|
ZT_PathCheckFunction pathCheckFunction,
|
||||||
ZT_EventCallback eventCallback);
|
ZT_EventCallback eventCallback);
|
||||||
|
|
||||||
~Node();
|
~Node();
|
||||||
@ -189,6 +190,13 @@ public:
|
|||||||
len);
|
len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param localAddress Local address
|
||||||
|
* @param remoteAddress Remote address
|
||||||
|
* @return True if path should be used
|
||||||
|
*/
|
||||||
|
bool shouldUsePathForZeroTierTraffic(const InetAddress &localAddress,const InetAddress &remoteAddress);
|
||||||
|
|
||||||
inline SharedPtr<Network> network(uint64_t nwid) const
|
inline SharedPtr<Network> network(uint64_t nwid) const
|
||||||
{
|
{
|
||||||
Mutex::Lock _l(_networks_m);
|
Mutex::Lock _l(_networks_m);
|
||||||
@ -288,6 +296,7 @@ private:
|
|||||||
ZT_WirePacketSendFunction _wirePacketSendFunction;
|
ZT_WirePacketSendFunction _wirePacketSendFunction;
|
||||||
ZT_VirtualNetworkFrameFunction _virtualNetworkFrameFunction;
|
ZT_VirtualNetworkFrameFunction _virtualNetworkFrameFunction;
|
||||||
ZT_VirtualNetworkConfigFunction _virtualNetworkConfigFunction;
|
ZT_VirtualNetworkConfigFunction _virtualNetworkConfigFunction;
|
||||||
|
ZT_PathCheckFunction _pathCheckFunction;
|
||||||
ZT_EventCallback _eventCallback;
|
ZT_EventCallback _eventCallback;
|
||||||
|
|
||||||
std::vector< std::pair< uint64_t, SharedPtr<Network> > > _networks;
|
std::vector< std::pair< uint64_t, SharedPtr<Network> > > _networks;
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Path.hpp"
|
#include "Path.hpp"
|
||||||
#include "AntiRecursion.hpp"
|
|
||||||
#include "RuntimeEnvironment.hpp"
|
#include "RuntimeEnvironment.hpp"
|
||||||
#include "Node.hpp"
|
#include "Node.hpp"
|
||||||
|
|
||||||
@ -34,7 +33,6 @@ namespace ZeroTier {
|
|||||||
|
|
||||||
bool Path::send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now)
|
bool Path::send(const RuntimeEnvironment *RR,const void *data,unsigned int len,uint64_t now)
|
||||||
{
|
{
|
||||||
RR->antiRec->logOutgoingZT(data,len);
|
|
||||||
if (RR->node->putPacket(_localAddress,address(),data,len)) {
|
if (RR->node->putPacket(_localAddress,address(),data,len)) {
|
||||||
sent(now);
|
sent(now);
|
||||||
return true;
|
return true;
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
#include "Node.hpp"
|
#include "Node.hpp"
|
||||||
#include "Switch.hpp"
|
#include "Switch.hpp"
|
||||||
#include "Network.hpp"
|
#include "Network.hpp"
|
||||||
#include "AntiRecursion.hpp"
|
|
||||||
#include "SelfAwareness.hpp"
|
#include "SelfAwareness.hpp"
|
||||||
#include "Cluster.hpp"
|
#include "Cluster.hpp"
|
||||||
#include "Packet.hpp"
|
#include "Packet.hpp"
|
||||||
@ -104,7 +103,6 @@ void Peer::received(
|
|||||||
}
|
}
|
||||||
outp.append((uint16_t)redirectTo.port());
|
outp.append((uint16_t)redirectTo.port());
|
||||||
outp.armor(_key,true);
|
outp.armor(_key,true);
|
||||||
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
||||||
RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size());
|
RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size());
|
||||||
} else {
|
} else {
|
||||||
// For older peers we use RENDEZVOUS to coax them into contacting us elsewhere.
|
// For older peers we use RENDEZVOUS to coax them into contacting us elsewhere.
|
||||||
@ -120,7 +118,6 @@ void Peer::received(
|
|||||||
outp.append(redirectTo.rawIpData(),16);
|
outp.append(redirectTo.rawIpData(),16);
|
||||||
}
|
}
|
||||||
outp.armor(_key,true);
|
outp.armor(_key,true);
|
||||||
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
||||||
RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size());
|
RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size());
|
||||||
}
|
}
|
||||||
suboptimalPath = true;
|
suboptimalPath = true;
|
||||||
@ -159,7 +156,7 @@ void Peer::received(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pathIsConfirmed) {
|
if ((!pathIsConfirmed)&&(RR->node->shouldUsePathForZeroTierTraffic(localAddr,remoteAddr))) {
|
||||||
if (verb == Packet::VERB_OK) {
|
if (verb == Packet::VERB_OK) {
|
||||||
|
|
||||||
Path *slot = (Path *)0;
|
Path *slot = (Path *)0;
|
||||||
@ -232,7 +229,6 @@ void Peer::sendHELLO(const InetAddress &localAddr,const InetAddress &atAddress,u
|
|||||||
outp.append((uint64_t)RR->topology->worldTimestamp());
|
outp.append((uint64_t)RR->topology->worldTimestamp());
|
||||||
|
|
||||||
outp.armor(_key,false); // HELLO is sent in the clear
|
outp.armor(_key,false); // HELLO is sent in the clear
|
||||||
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
|
|
||||||
RR->node->putPacket(localAddr,atAddress,outp.data(),outp.size(),ttl);
|
RR->node->putPacket(localAddr,atAddress,outp.data(),outp.size(),ttl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -512,7 +508,12 @@ bool Peer::_checkPath(Path &p,const uint64_t now)
|
|||||||
* counter is reset on any packet receive over this path. If it reaches the
|
* counter is reset on any packet receive over this path. If it reaches the
|
||||||
* MAX_PROBATION threshold the path is considred dead. */
|
* MAX_PROBATION threshold the path is considred dead. */
|
||||||
|
|
||||||
if ( (p.lastSend() > p.lastReceived()) && ((p.lastSend() - p.lastReceived()) >= ZT_PEER_DEAD_PATH_DETECTION_NO_ANSWER_TIMEOUT) && ((now - p.lastPing()) >= ZT_PEER_DEAD_PATH_DETECTION_NO_ANSWER_TIMEOUT) ) {
|
if (
|
||||||
|
(p.lastSend() > p.lastReceived()) &&
|
||||||
|
((p.lastSend() - p.lastReceived()) >= ZT_PEER_DEAD_PATH_DETECTION_NO_ANSWER_TIMEOUT) &&
|
||||||
|
((now - p.lastPing()) >= ZT_PEER_DEAD_PATH_DETECTION_NO_ANSWER_TIMEOUT) &&
|
||||||
|
(!RR->topology->amRoot())
|
||||||
|
) {
|
||||||
TRACE("%s(%s) does not seem to be answering in a timely manner, checking if dead (probation == %u)",_id.address().toString().c_str(),p.address().toString().c_str(),p.probation());
|
TRACE("%s(%s) does not seem to be answering in a timely manner, checking if dead (probation == %u)",_id.address().toString().c_str(),p.address().toString().c_str(),p.probation());
|
||||||
|
|
||||||
if ( (_vProto >= 5) && ( !((_vMajor == 1)&&(_vMinor == 1)&&(_vRevision == 0)) ) ) {
|
if ( (_vProto >= 5) && ( !((_vMajor == 1)&&(_vMinor == 1)&&(_vRevision == 0)) ) ) {
|
||||||
|
@ -41,7 +41,6 @@ class Switch;
|
|||||||
class Topology;
|
class Topology;
|
||||||
class Node;
|
class Node;
|
||||||
class Multicaster;
|
class Multicaster;
|
||||||
class AntiRecursion;
|
|
||||||
class NetworkController;
|
class NetworkController;
|
||||||
class SelfAwareness;
|
class SelfAwareness;
|
||||||
class Cluster;
|
class Cluster;
|
||||||
@ -59,7 +58,6 @@ public:
|
|||||||
,localNetworkController((NetworkController *)0)
|
,localNetworkController((NetworkController *)0)
|
||||||
,sw((Switch *)0)
|
,sw((Switch *)0)
|
||||||
,mc((Multicaster *)0)
|
,mc((Multicaster *)0)
|
||||||
,antiRec((AntiRecursion *)0)
|
|
||||||
,topology((Topology *)0)
|
,topology((Topology *)0)
|
||||||
,sa((SelfAwareness *)0)
|
,sa((SelfAwareness *)0)
|
||||||
,dp((DeferredPackets *)0)
|
,dp((DeferredPackets *)0)
|
||||||
@ -91,7 +89,6 @@ public:
|
|||||||
|
|
||||||
Switch *sw;
|
Switch *sw;
|
||||||
Multicaster *mc;
|
Multicaster *mc;
|
||||||
AntiRecursion *antiRec;
|
|
||||||
Topology *topology;
|
Topology *topology;
|
||||||
SelfAwareness *sa;
|
SelfAwareness *sa;
|
||||||
DeferredPackets *dp;
|
DeferredPackets *dp;
|
||||||
|
@ -42,7 +42,6 @@
|
|||||||
#include "InetAddress.hpp"
|
#include "InetAddress.hpp"
|
||||||
#include "Topology.hpp"
|
#include "Topology.hpp"
|
||||||
#include "Peer.hpp"
|
#include "Peer.hpp"
|
||||||
#include "AntiRecursion.hpp"
|
|
||||||
#include "SelfAwareness.hpp"
|
#include "SelfAwareness.hpp"
|
||||||
#include "Packet.hpp"
|
#include "Packet.hpp"
|
||||||
#include "Cluster.hpp"
|
#include "Cluster.hpp"
|
||||||
@ -124,15 +123,6 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
|
|||||||
if (to == network->mac())
|
if (to == network->mac())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Check anti-recursion module to ensure that this is not ZeroTier talking over its own links.
|
|
||||||
* Note: even when we introduce a more purposeful binding of the main UDP port, this can
|
|
||||||
* still happen because Windows likes to send broadcasts over interfaces that have little
|
|
||||||
* to do with their intended target audience. :P */
|
|
||||||
if (!RR->antiRec->checkEthernetFrame(data,len)) {
|
|
||||||
TRACE("%.16llx: rejected recursively addressed ZeroTier packet by tail match (type %s, length: %u)",network->id(),etherTypeName(etherType),len);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check to make sure this protocol is allowed on this network
|
// Check to make sure this protocol is allowed on this network
|
||||||
if (!nconf->permitsEtherType(etherType)) {
|
if (!nconf->permitsEtherType(etherType)) {
|
||||||
TRACE("%.16llx: ignored tap: %s -> %s: ethertype %s not allowed on network %.16llx",network->id(),from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType),(unsigned long long)network->id());
|
TRACE("%.16llx: ignored tap: %s -> %s: ethertype %s not allowed on network %.16llx",network->id(),from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType),(unsigned long long)network->id());
|
||||||
|
@ -397,6 +397,7 @@ static long SnodeDataStoreGetFunction(ZT_Node *node,void *uptr,const char *name,
|
|||||||
static int SnodeDataStorePutFunction(ZT_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure);
|
static int SnodeDataStorePutFunction(ZT_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure);
|
||||||
static int SnodeWirePacketSendFunction(ZT_Node *node,void *uptr,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *addr,const void *data,unsigned int len,unsigned int ttl);
|
static int SnodeWirePacketSendFunction(ZT_Node *node,void *uptr,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *addr,const void *data,unsigned int len,unsigned int ttl);
|
||||||
static void SnodeVirtualNetworkFrameFunction(ZT_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len);
|
static void SnodeVirtualNetworkFrameFunction(ZT_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len);
|
||||||
|
static int SnodePathCheckFunction(ZT_Node *node,void *uptr,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *remoteAddr);
|
||||||
|
|
||||||
#ifdef ZT_ENABLE_CLUSTER
|
#ifdef ZT_ENABLE_CLUSTER
|
||||||
static void SclusterSendFunction(void *uptr,unsigned int toMemberId,const void *data,unsigned int len);
|
static void SclusterSendFunction(void *uptr,unsigned int toMemberId,const void *data,unsigned int len);
|
||||||
@ -592,6 +593,7 @@ public:
|
|||||||
SnodeWirePacketSendFunction,
|
SnodeWirePacketSendFunction,
|
||||||
SnodeVirtualNetworkFrameFunction,
|
SnodeVirtualNetworkFrameFunction,
|
||||||
SnodeVirtualNetworkConfigFunction,
|
SnodeVirtualNetworkConfigFunction,
|
||||||
|
SnodePathCheckFunction,
|
||||||
SnodeEventCallback);
|
SnodeEventCallback);
|
||||||
|
|
||||||
#ifdef ZT_USE_MINIUPNPC
|
#ifdef ZT_USE_MINIUPNPC
|
||||||
@ -763,6 +765,13 @@ public:
|
|||||||
if ((now - lastLocalInterfaceAddressCheck) >= ZT_LOCAL_INTERFACE_CHECK_INTERVAL) {
|
if ((now - lastLocalInterfaceAddressCheck) >= ZT_LOCAL_INTERFACE_CHECK_INTERVAL) {
|
||||||
lastLocalInterfaceAddressCheck = now;
|
lastLocalInterfaceAddressCheck = now;
|
||||||
|
|
||||||
|
_node->clearLocalInterfaceAddresses();
|
||||||
|
#ifdef ZT_USE_MINIUPNPC
|
||||||
|
std::vector<InetAddress> mappedAddresses(_portMapper->get());
|
||||||
|
for(std::vector<InetAddress>::const_iterator ext(mappedAddresses.begin());ext!=mappedAddresses.end();++ext)
|
||||||
|
_node->addLocalInterfaceAddress(reinterpret_cast<const struct sockaddr_storage *>(&(*ext)));
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __UNIX_LIKE__
|
#ifdef __UNIX_LIKE__
|
||||||
std::vector<std::string> ztDevices;
|
std::vector<std::string> ztDevices;
|
||||||
{
|
{
|
||||||
@ -770,15 +779,6 @@ public:
|
|||||||
for(std::map< uint64_t,EthernetTap *>::const_iterator t(_taps.begin());t!=_taps.end();++t)
|
for(std::map< uint64_t,EthernetTap *>::const_iterator t(_taps.begin());t!=_taps.end();++t)
|
||||||
ztDevices.push_back(t->second->deviceName());
|
ztDevices.push_back(t->second->deviceName());
|
||||||
}
|
}
|
||||||
|
|
||||||
_node->clearLocalInterfaceAddresses();
|
|
||||||
|
|
||||||
#ifdef ZT_USE_MINIUPNPC
|
|
||||||
std::vector<InetAddress> mappedAddresses(_portMapper->get());
|
|
||||||
for(std::vector<InetAddress>::const_iterator ext(mappedAddresses.begin());ext!=mappedAddresses.end();++ext)
|
|
||||||
_node->addLocalInterfaceAddress(reinterpret_cast<const struct sockaddr_storage *>(&(*ext)));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct ifaddrs *ifatbl = (struct ifaddrs *)0;
|
struct ifaddrs *ifatbl = (struct ifaddrs *)0;
|
||||||
if ((getifaddrs(&ifatbl) == 0)&&(ifatbl)) {
|
if ((getifaddrs(&ifatbl) == 0)&&(ifatbl)) {
|
||||||
struct ifaddrs *ifa = ifatbl;
|
struct ifaddrs *ifa = ifatbl;
|
||||||
@ -810,7 +810,6 @@ public:
|
|||||||
for(std::map< uint64_t,EthernetTap *>::const_iterator t(_taps.begin());t!=_taps.end();++t)
|
for(std::map< uint64_t,EthernetTap *>::const_iterator t(_taps.begin());t!=_taps.end();++t)
|
||||||
ztDevices.push_back(t->second->luid());
|
ztDevices.push_back(t->second->luid());
|
||||||
}
|
}
|
||||||
|
|
||||||
char aabuf[16384];
|
char aabuf[16384];
|
||||||
ULONG aalen = sizeof(aabuf);
|
ULONG aalen = sizeof(aabuf);
|
||||||
if (GetAdaptersAddresses(AF_UNSPEC,GAA_FLAG_SKIP_ANYCAST|GAA_FLAG_SKIP_MULTICAST|GAA_FLAG_SKIP_DNS_SERVER,(void *)0,reinterpret_cast<PIP_ADAPTER_ADDRESSES>(aabuf),&aalen) == NO_ERROR) {
|
if (GetAdaptersAddresses(AF_UNSPEC,GAA_FLAG_SKIP_ANYCAST|GAA_FLAG_SKIP_MULTICAST|GAA_FLAG_SKIP_DNS_SERVER,(void *)0,reinterpret_cast<PIP_ADAPTER_ADDRESSES>(aabuf),&aalen) == NO_ERROR) {
|
||||||
@ -1396,6 +1395,22 @@ public:
|
|||||||
t->second->put(MAC(sourceMac),MAC(destMac),etherType,data,len);
|
t->second->put(MAC(sourceMac),MAC(destMac),etherType,data,len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int nodePathCheckFunction(const struct sockaddr_storage *localAddr,const struct sockaddr_storage *remoteAddr)
|
||||||
|
{
|
||||||
|
Mutex::Lock _l(_taps_m);
|
||||||
|
for(std::map< uint64_t,EthernetTap * >::const_iterator t(_taps.begin());t!=_taps.end();++t) {
|
||||||
|
if (t->second) {
|
||||||
|
std::vector<InetAddress> ips(t->second->ips());
|
||||||
|
for(std::vector<InetAddress>::const_iterator i(ips.begin());i!=ips.end();++i) {
|
||||||
|
if (i->containsAddress(*(reinterpret_cast<const InetAddress *>(remoteAddr)))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
inline void tapFrameHandler(uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
|
inline void tapFrameHandler(uint64_t nwid,const MAC &from,const MAC &to,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
|
||||||
{
|
{
|
||||||
_node->processVirtualNetworkFrame(OSUtils::now(),nwid,from.toInt(),to.toInt(),etherType,vlanId,data,len,&_nextBackgroundTaskDeadline);
|
_node->processVirtualNetworkFrame(OSUtils::now(),nwid,from.toInt(),to.toInt(),etherType,vlanId,data,len,&_nextBackgroundTaskDeadline);
|
||||||
@ -1530,6 +1545,8 @@ static int SnodeWirePacketSendFunction(ZT_Node *node,void *uptr,const struct soc
|
|||||||
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodeWirePacketSendFunction(localAddr,addr,data,len,ttl); }
|
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodeWirePacketSendFunction(localAddr,addr,data,len,ttl); }
|
||||||
static void SnodeVirtualNetworkFrameFunction(ZT_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
|
static void SnodeVirtualNetworkFrameFunction(ZT_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len)
|
||||||
{ reinterpret_cast<OneServiceImpl *>(uptr)->nodeVirtualNetworkFrameFunction(nwid,sourceMac,destMac,etherType,vlanId,data,len); }
|
{ reinterpret_cast<OneServiceImpl *>(uptr)->nodeVirtualNetworkFrameFunction(nwid,sourceMac,destMac,etherType,vlanId,data,len); }
|
||||||
|
static int SnodePathCheckFunction(ZT_Node *node,void *uptr,const struct sockaddr_storage *localAddr,const struct sockaddr_storage *remoteAddr)
|
||||||
|
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodePathCheckFunction(localAddr,remoteAddr); }
|
||||||
|
|
||||||
#ifdef ZT_ENABLE_CLUSTER
|
#ifdef ZT_ENABLE_CLUSTER
|
||||||
static void SclusterSendFunction(void *uptr,unsigned int toMemberId,const void *data,unsigned int len)
|
static void SclusterSendFunction(void *uptr,unsigned int toMemberId,const void *data,unsigned int len)
|
||||||
|
Loading…
Reference in New Issue
Block a user