summaryrefslogtreecommitdiff
path: root/node/Multicaster.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'node/Multicaster.hpp')
-rw-r--r--node/Multicaster.hpp145
1 files changed, 96 insertions, 49 deletions
diff --git a/node/Multicaster.hpp b/node/Multicaster.hpp
index c43c8d93..e57f81fe 100644
--- a/node/Multicaster.hpp
+++ b/node/Multicaster.hpp
@@ -1,6 +1,6 @@
/*
* ZeroTier One - Network Virtualization Everywhere
- * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
+ * Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/
*
* 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
@@ -14,6 +14,14 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * --
+ *
+ * You can be released from the requirements of the license by purchasing
+ * a commercial license. Buying such a license is mandatory as soon as you
+ * develop commercial closed-source software that incorporates or links
+ * directly against ZeroTier software without disclosing the source code
+ * of your own application.
*/
#ifndef ZT_MULTICASTER_HPP
@@ -34,50 +42,20 @@
#include "OutboundMulticast.hpp"
#include "Utils.hpp"
#include "Mutex.hpp"
-#include "NonCopyable.hpp"
+#include "SharedPtr.hpp"
namespace ZeroTier {
class RuntimeEnvironment;
class CertificateOfMembership;
class Packet;
+class Network;
/**
* Database of known multicast peers within a network
*/
-class Multicaster : NonCopyable
+class Multicaster
{
-private:
- struct Key
- {
- Key() : nwid(0),mg() {}
- Key(uint64_t n,const MulticastGroup &g) : nwid(n),mg(g) {}
-
- uint64_t nwid;
- MulticastGroup mg;
-
- inline bool operator==(const Key &k) const throw() { return ((nwid == k.nwid)&&(mg == k.mg)); }
- inline unsigned long hashCode() const throw() { return (mg.hashCode() ^ (unsigned long)(nwid ^ (nwid >> 32))); }
- };
-
- struct MulticastGroupMember
- {
- MulticastGroupMember() {}
- MulticastGroupMember(const Address &a,uint64_t ts) : address(a),timestamp(ts) {}
-
- Address address;
- uint64_t timestamp; // time of last notification
- };
-
- struct MulticastGroupStatus
- {
- MulticastGroupStatus() : lastExplicitGather(0) {}
-
- uint64_t lastExplicitGather;
- std::list<OutboundMulticast> txQueue; // pending outbound multicasts
- std::vector<MulticastGroupMember> members; // members of this group
- };
-
public:
Multicaster(const RuntimeEnvironment *renv);
~Multicaster();
@@ -90,10 +68,10 @@ public:
* @param mg Multicast group
* @param member New member address
*/
- inline void add(uint64_t now,uint64_t nwid,const MulticastGroup &mg,const Address &member)
+ inline void add(void *tPtr,int64_t now,uint64_t nwid,const MulticastGroup &mg,const Address &member)
{
Mutex::Lock _l(_groups_m);
- _add(now,nwid,mg,_groups[Multicaster::Key(nwid,mg)],member);
+ _add(tPtr,now,nwid,mg,_groups[Multicaster::Key(nwid,mg)],member);
}
/**
@@ -101,6 +79,7 @@ public:
*
* It's up to the caller to check bounds on the array before calling this.
*
+ * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param now Current time
* @param nwid Network ID
* @param mg Multicast group
@@ -108,7 +87,7 @@ public:
* @param count Number of addresses
* @param totalKnown Total number of known addresses as reported by peer
*/
- void addMultiple(uint64_t now,uint64_t nwid,const MulticastGroup &mg,const void *addresses,unsigned int count,unsigned int totalKnown);
+ void addMultiple(void *tPtr,int64_t now,uint64_t nwid,const MulticastGroup &mg,const void *addresses,unsigned int count,unsigned int totalKnown);
/**
* Remove a multicast group member (if present)
@@ -150,11 +129,10 @@ public:
/**
* Send a multicast
*
- * @param com Certificate of membership to include or NULL for none
- * @param limit Multicast limit
+ * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
* @param now Current time
- * @param nwid Network ID
- * @param alwaysSendTo Send to these peers first and even if not included in subscriber list
+ * @param network Network
+ * @param origin Origin of multicast (to not return to sender) or NULL if none
* @param mg Multicast group
* @param src Source Ethernet MAC address or NULL to skip in packet and compute from ZT address (non-bridged mode)
* @param etherType Ethernet frame type
@@ -162,11 +140,10 @@ public:
* @param len Length of packet data
*/
void send(
- const CertificateOfMembership *com,
- unsigned int limit,
- uint64_t now,
- uint64_t nwid,
- const std::vector<Address> &alwaysSendTo,
+ void *tPtr,
+ int64_t now,
+ const SharedPtr<Network> &network,
+ const Address &origin,
const MulticastGroup &mg,
const MAC &src,
unsigned int etherType,
@@ -179,14 +156,84 @@ public:
* @param RR Runtime environment
* @param now Current time
*/
- void clean(uint64_t now);
+ void clean(int64_t now);
+
+ /**
+ * Add an authorization credential
+ *
+ * The Multicaster keeps its own track of when valid credentials of network
+ * membership are presented. This allows it to control MULTICAST_LIKE
+ * GATHER authorization for networks this node does not belong to.
+ *
+ * @param com Certificate of membership
+ * @param alreadyValidated If true, COM has already been checked and found to be valid and signed
+ */
+ void addCredential(void *tPtr,const CertificateOfMembership &com,bool alreadyValidated);
+
+ /**
+ * Check authorization for GATHER and LIKE for non-network-members
+ *
+ * @param a Address of peer
+ * @param nwid Network ID
+ * @param now Current time
+ * @return True if GATHER and LIKE should be allowed
+ */
+ bool cacheAuthorized(const Address &a,const uint64_t nwid,const int64_t now) const
+ {
+ Mutex::Lock _l(_gatherAuth_m);
+ const uint64_t *p = _gatherAuth.get(_GatherAuthKey(nwid,a));
+ return ((p)&&((now - *p) < ZT_MULTICAST_CREDENTIAL_EXPIRATON));
+ }
private:
- void _add(uint64_t now,uint64_t nwid,const MulticastGroup &mg,MulticastGroupStatus &gs,const Address &member);
+ struct Key
+ {
+ Key() : nwid(0),mg() {}
+ Key(uint64_t n,const MulticastGroup &g) : nwid(n),mg(g) {}
+
+ uint64_t nwid;
+ MulticastGroup mg;
+
+ inline bool operator==(const Key &k) const { return ((nwid == k.nwid)&&(mg == k.mg)); }
+ inline unsigned long hashCode() const { return (mg.hashCode() ^ (unsigned long)(nwid ^ (nwid >> 32))); }
+ };
+
+ struct MulticastGroupMember
+ {
+ MulticastGroupMember() {}
+ MulticastGroupMember(const Address &a,uint64_t ts) : address(a),timestamp(ts) {}
+
+ Address address;
+ uint64_t timestamp; // time of last notification
+ };
+
+ struct MulticastGroupStatus
+ {
+ MulticastGroupStatus() : lastExplicitGather(0) {}
+
+ uint64_t lastExplicitGather;
+ std::list<OutboundMulticast> txQueue; // pending outbound multicasts
+ std::vector<MulticastGroupMember> members; // members of this group
+ };
+
+ void _add(void *tPtr,int64_t now,uint64_t nwid,const MulticastGroup &mg,MulticastGroupStatus &gs,const Address &member);
+
+ const RuntimeEnvironment *const RR;
- const RuntimeEnvironment *RR;
Hashtable<Multicaster::Key,MulticastGroupStatus> _groups;
Mutex _groups_m;
+
+ struct _GatherAuthKey
+ {
+ _GatherAuthKey() : member(0),networkId(0) {}
+ _GatherAuthKey(const uint64_t nwid,const Address &a) : member(a.toInt()),networkId(nwid) {}
+ inline unsigned long hashCode() const { return (unsigned long)(member ^ networkId); }
+ inline bool operator==(const _GatherAuthKey &k) const { return ((member == k.member)&&(networkId == k.networkId)); }
+ uint64_t member;
+ uint64_t networkId;
+ };
+ Hashtable< _GatherAuthKey,uint64_t > _gatherAuth;
+ Mutex _gatherAuth_m;
};
} // namespace ZeroTier