summaryrefslogtreecommitdiff
path: root/node/Switch.cpp
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2015-06-02 12:49:36 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2015-06-02 12:49:36 -0700
commit3d6c1860ca8169f618ad70ae92e4a8cd2f4746c8 (patch)
treeca93fd3ca8dc6fb9afffcc78b0167a3c6d204eec /node/Switch.cpp
parentf0be5e814eb0c9496d6c163e2d5bc213e7b483c4 (diff)
parent79efceb57bd71e91f5733dc4c54b3213a3f95636 (diff)
downloadinfinitytier-3d6c1860ca8169f618ad70ae92e4a8cd2f4746c8.tar.gz
infinitytier-3d6c1860ca8169f618ad70ae92e4a8cd2f4746c8.zip
Merge branch 'adamierymenko-dev' into android-jni
Diffstat (limited to 'node/Switch.cpp')
-rw-r--r--node/Switch.cpp51
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;
}