diff options
| author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-06-02 12:49:36 -0700 |
|---|---|---|
| committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-06-02 12:49:36 -0700 |
| commit | 3d6c1860ca8169f618ad70ae92e4a8cd2f4746c8 (patch) | |
| tree | ca93fd3ca8dc6fb9afffcc78b0167a3c6d204eec /node/Switch.cpp | |
| parent | f0be5e814eb0c9496d6c163e2d5bc213e7b483c4 (diff) | |
| parent | 79efceb57bd71e91f5733dc4c54b3213a3f95636 (diff) | |
| download | infinitytier-3d6c1860ca8169f618ad70ae92e4a8cd2f4746c8.tar.gz infinitytier-3d6c1860ca8169f618ad70ae92e4a8cd2f4746c8.zip | |
Merge branch 'adamierymenko-dev' into android-jni
Diffstat (limited to 'node/Switch.cpp')
| -rw-r--r-- | node/Switch.cpp | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/node/Switch.cpp b/node/Switch.cpp index 4bdf2d84..0aa0b664 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -114,8 +114,6 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c if (to.isMulticast()) { // Destination is a multicast address (including broadcast) - - const uint64_t now = RR->node->now(); MulticastGroup mg(to,0); if (to.isBroadcast()) { @@ -145,7 +143,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c * multicast addresses on bridge interfaces and subscribing each slave. * But in that case this does no harm, as the sets are just merged. */ if (fromBridged) - network->learnBridgedMulticastGroup(mg,now); + network->learnBridgedMulticastGroup(mg,RR->node->now()); // Check multicast/broadcast bandwidth quotas and reject if quota exceeded if (!network->updateAndCheckMulticastBalance(mg,len)) { @@ -158,7 +156,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c RR->mc->send( ((!nconf->isPublic())&&(nconf->com())) ? &(nconf->com()) : (const CertificateOfMembership *)0, nconf->multicastLimit(), - now, + RR->node->now(), network->id(), nconf->activeBridges(), mg, @@ -180,7 +178,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c // bundle this with EXT_FRAME instead of sending two packets. Packet outp(toZT,RR->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE); nconf->com().serialize(outp); - send(outp,true); + send(outp,true,network->id()); } if (fromBridged) { @@ -193,7 +191,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c outp.append((uint16_t)etherType); outp.append(data,len); outp.compress(); - send(outp,true); + send(outp,true,network->id()); } else { // FRAME is a shorter version that can be used when there's no bridging and no COM Packet outp(toZT,RR->identity.address(),Packet::VERB_FRAME); @@ -201,7 +199,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c outp.append((uint16_t)etherType); outp.append(data,len); outp.compress(); - send(outp,true); + send(outp,true,network->id()); } //TRACE("%.16llx: UNICAST: %s -> %s etherType==%s(%.4x) vlanId==%u len==%u fromBridged==%d",network->id(),from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType),etherType,vlanId,len,(int)fromBridged); @@ -259,21 +257,21 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c outp.append((uint16_t)etherType); outp.append(data,len); outp.compress(); - send(outp,true); + send(outp,true,network->id()); } } } -void Switch::send(const Packet &packet,bool encrypt) +void Switch::send(const Packet &packet,bool encrypt,uint64_t nwid) { if (packet.destination() == RR->identity.address()) { TRACE("BUG: caught attempt to send() to self, ignored"); return; } - if (!_trySend(packet,encrypt)) { + if (!_trySend(packet,encrypt,nwid)) { Mutex::Lock _l(_txQueue_m); - _txQueue.insert(std::pair< Address,TXQueueEntry >(packet.destination(),TXQueueEntry(RR->node->now(),packet,encrypt))); + _txQueue.insert(std::pair< Address,TXQueueEntry >(packet.destination(),TXQueueEntry(RR->node->now(),packet,encrypt,nwid))); } } @@ -423,7 +421,7 @@ void Switch::doAnythingWaitingForPeer(const SharedPtr<Peer> &peer) Mutex::Lock _l(_txQueue_m); std::pair< std::multimap< Address,TXQueueEntry >::iterator,std::multimap< Address,TXQueueEntry >::iterator > waitingTxQueueItems(_txQueue.equal_range(peer->address())); for(std::multimap< Address,TXQueueEntry >::iterator txi(waitingTxQueueItems.first);txi!=waitingTxQueueItems.second;) { - if (_trySend(txi->second.packet,txi->second.encrypt)) + if (_trySend(txi->second.packet,txi->second.encrypt,txi->second.nwid)) _txQueue.erase(txi++); else ++txi; } @@ -505,7 +503,7 @@ unsigned long Switch::doTimerTasks(uint64_t now) { // Time out TX queue packets that never got WHOIS lookups or other info. Mutex::Lock _l(_txQueue_m); for(std::multimap< Address,TXQueueEntry >::iterator i(_txQueue.begin());i!=_txQueue.end();) { - if (_trySend(i->second.packet,i->second.encrypt)) + if (_trySend(i->second.packet,i->second.encrypt,i->second.nwid)) _txQueue.erase(i++); else if ((now - i->second.creationTime) > ZT_TRANSMIT_QUEUE_TIMEOUT) { TRACE("TX %s -> %s timed out",i->second.packet.source().toString().c_str(),i->second.packet.destination().toString().c_str()); @@ -725,7 +723,7 @@ Address Switch::_sendWhoisRequest(const Address &addr,const Address *peersAlread return Address(); } -bool Switch::_trySend(const Packet &packet,bool encrypt) +bool Switch::_trySend(const Packet &packet,bool encrypt,uint64_t nwid) { SharedPtr<Peer> peer(RR->topology->getPeer(packet.destination())); @@ -734,8 +732,29 @@ bool Switch::_trySend(const Packet &packet,bool encrypt) Path *viaPath = peer->getBestPath(now); if (!viaPath) { - SharedPtr<Peer> sn(RR->topology->getBestSupernode()); - if (!(sn)||(!(viaPath = sn->getBestPath(now)))) + SharedPtr<Peer> relay; + + if (nwid) { + SharedPtr<Network> network(RR->node->network(nwid)); + if (network) { + SharedPtr<NetworkConfig> nconf(network->config2()); + if (nconf) { + unsigned int latency = ~((unsigned int)0); + for(std::vector< std::pair<Address,InetAddress> >::const_iterator r(nconf->relays().begin());r!=nconf->relays().end();++r) { + if (r->first != peer->address()) { + SharedPtr<Peer> rp(RR->topology->getPeer(r->first)); + if ((rp)&&(rp->hasActiveDirectPath(now))&&(rp->latency() <= latency)) + rp.swap(relay); + } + } + } + } + } + + if (!relay) + relay = RR->topology->getBestSupernode(); + + if (!(relay)||(!(viaPath = relay->getBestPath(now)))) return false; } |
