summaryrefslogtreecommitdiff
path: root/node/Multicaster.hpp
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2013-07-11 16:19:06 -0400
committerAdam Ierymenko <adam.ierymenko@gmail.com>2013-07-11 16:19:06 -0400
commitffad0b27809f8ec0cca11a5dabd9624340857f57 (patch)
treeab0d78f3ad1fce257214065c4dd87fe3502473e7 /node/Multicaster.hpp
parentbcd079b70eb984a44dc62b2f8aa591c4f9c57f8a (diff)
downloadinfinitytier-ffad0b27809f8ec0cca11a5dabd9624340857f57.tar.gz
infinitytier-ffad0b27809f8ec0cca11a5dabd9624340857f57.zip
Factoring out packet decoder from Switch to put that object on a little bit of a diet. Work in progress, wont build yet.
Diffstat (limited to 'node/Multicaster.hpp')
-rw-r--r--node/Multicaster.hpp45
1 files changed, 27 insertions, 18 deletions
diff --git a/node/Multicaster.hpp b/node/Multicaster.hpp
index 03a94ca2..daa53358 100644
--- a/node/Multicaster.hpp
+++ b/node/Multicaster.hpp
@@ -81,6 +81,7 @@ public:
* Generate a signature of a multicast packet using an identity
*
* @param id Identity to sign with (must have secret key portion)
+ * @param nwid Network ID
* @param from MAC address of sender
* @param to Multicast group
* @param etherType 16-bit ethernet type
@@ -88,10 +89,10 @@ public:
* @param len Length of frame
* @return ECDSA signature
*/
- static inline std::string signMulticastPacket(const Identity &id,const MAC &from,const MulticastGroup &to,unsigned int etherType,const void *data,unsigned int len)
+ static inline std::string signMulticastPacket(const Identity &id,uint64_t nwid,const MAC &from,const MulticastGroup &to,unsigned int etherType,const void *data,unsigned int len)
{
unsigned char digest[32];
- _hashMulticastPacketForSig(from,to,etherType,data,len,digest);
+ _hashMulticastPacketForSig(nwid,from,to,etherType,data,len,digest);
return id.sign(digest);
}
@@ -99,6 +100,7 @@ public:
* Verify a signature from a multicast packet
*
* @param id Identity of original signer
+ * @param nwid Network ID
* @param from MAC address of sender
* @param to Multicast group
* @param etherType 16-bit ethernet type
@@ -108,11 +110,11 @@ public:
* @param siglen Length of signature in bytes
* @return ECDSA signature
*/
- static bool verifyMulticastPacket(const Identity &id,const MAC &from,const MulticastGroup &to,unsigned int etherType,const void *data,unsigned int len,const void *signature,unsigned int siglen)
+ static bool verifyMulticastPacket(const Identity &id,uint64_t nwid,const MAC &from,const MulticastGroup &to,unsigned int etherType,const void *data,unsigned int len,const void *signature,unsigned int siglen)
{
unsigned char digest[32];
- _hashMulticastPacketForSig(from,to,etherType,data,len,digest);
- return id.verify(digest,signature,siglen);
+ _hashMulticastPacketForSig(nwid,from,to,etherType,data,len,digest);
+ return id.verifySignature(digest,signature,siglen);
}
/**
@@ -183,6 +185,7 @@ public:
* @param topology Topology object or mock thereof
* @param nwid Network ID
* @param mg Multicast group
+ * @param originalSubmitter Original submitter of multicast message to network
* @param upstream Address from which message originated, or null (0) address if none
* @param bf Bloom filter, updated in place with sums of addresses in chosen peers and/or decay
* @param max Maximum number of peers to pick
@@ -197,6 +200,7 @@ public:
T &topology,
uint64_t nwid,
const MulticastGroup &mg,
+ const Address &originalSubmitter,
const Address &upstream,
MulticastBloomFilter &bf,
unsigned int max,
@@ -240,12 +244,15 @@ public:
}
// If it's not expired and it's from our random sample, add it to the set of peers
- // to consider.
- P peer = topology.getPeer(channelMemberEntry->first);
- if (peer) {
- toConsider[sampleSize++] = peer;
- if (sampleSize >= ZT_MULTICAST_PICK_MAX_SAMPLE_SIZE)
- break; // abort if we have enough candidates
+ // to consider. Exclude immediate upstream and original submitter, since we know for
+ // a fact they've already seen this.
+ if ((channelMemberEntry->first != originalSubmitter)&&(channelMemberEntry->first != upstream)) {
+ P peer = topology.getPeer(channelMemberEntry->first);
+ if (peer) {
+ toConsider[sampleSize++] = peer;
+ if (sampleSize >= ZT_MULTICAST_PICK_MAX_SAMPLE_SIZE)
+ break; // abort if we have enough candidates
+ }
}
++channelMemberEntry;
}
@@ -264,7 +271,10 @@ public:
// Decay a few random bits in bloom filter to probabilistically eliminate
// false positives as we go. The odds of decaying an already-set bit
// increases as the bloom filter saturates, so in the early hops of
- // propagation this likely won't have any effect.
+ // propagation this likely won't have any effect. This allows peers with
+ // bloom filter collisions to be reconsidered, but at positions on the
+ // network graph likely to be hops away from the original origin of the
+ // message.
for(unsigned int i=0;i<ZT_MULTICAST_BLOOM_FILTER_DECAY_RATE;++i)
bf.decay();
@@ -278,8 +288,7 @@ public:
// Add a supernode if there's nowhere else to go. Supernodes know of all multicast
// LIKEs and so can act to bridge sparse multicast groups. We do not remember them
- // in the bloom filter, since such bridging may very well need to happen more than
- // once.
+ // in the bloom filter.
if (!picked) {
P peer = topology.getBestSupernode();
if (peer)
@@ -300,20 +309,20 @@ private:
}
};
- static inline void _hashMulticastPacketForSig(const MAC &from,const MulticastGroup &to,unsigned int etherType,const void *data,unsigned int len,unsigned char *digest)
+ static inline void _hashMulticastPacketForSig(uint64_t nwid,const MAC &from,const MulticastGroup &to,unsigned int etherType,const void *data,unsigned int len,unsigned char *digest)
throw()
{
unsigned char zero = 0;
SHA256_CTX sha;
SHA256_Init(&sha);
- uint64_t _nwid = Utils::hton(network->id());
+ uint64_t _nwid = Utils::hton(nwid);
SHA256_Update(&sha,(unsigned char *)&_nwid,sizeof(_nwid));
SHA256_Update(&sha,&zero,1);
SHA256_Update(&sha,(unsigned char *)from.data,6);
SHA256_Update(&sha,&zero,1);
- SHA256_Update(&sha,(unsigned char *)mg.mac().data,6);
+ SHA256_Update(&sha,(unsigned char *)to.mac().data,6);
SHA256_Update(&sha,&zero,1);
- uint32_t _adi = Utils::hton(mg.adi());
+ uint32_t _adi = Utils::hton(to.adi());
SHA256_Update(&sha,(unsigned char *)&_adi,sizeof(_adi));
SHA256_Update(&sha,&zero,1);
uint16_t _etype = Utils::hton((uint16_t)etherType);