summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
Diffstat (limited to 'node')
-rw-r--r--node/IncomingPacket.cpp41
-rw-r--r--node/Network.cpp13
-rw-r--r--node/NetworkConfig.cpp8
-rw-r--r--node/Node.cpp100
-rw-r--r--node/OutboundMulticast.cpp4
-rw-r--r--node/Salsa20.hpp6
-rw-r--r--node/Switch.cpp51
-rw-r--r--node/Switch.hpp20
-rw-r--r--node/Topology.hpp5
9 files changed, 139 insertions, 109 deletions
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp
index 2ddd83a8..8b228de5 100644
--- a/node/IncomingPacket.cpp
+++ b/node/IncomingPacket.cpp
@@ -486,38 +486,21 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr<Peer>
bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
{
try {
- /*
- * At the moment, we only obey RENDEZVOUS if it comes from a designated
- * supernode. If relay offloading is implemented to scale the net, this
- * will need reconsideration.
- *
- * The reason is that RENDEZVOUS could technically be used to cause a
- * peer to send a weird encrypted UDP packet to an arbitrary IP:port.
- * The sender of RENDEZVOUS has no control over the content of this
- * packet, but it's still maybe something we want to not allow just
- * anyone to order due to possible DDOS or network forensic implications.
- * So if we diversify relays, we'll need some way of deciding whether the
- * sender is someone we should trust with a RENDEZVOUS hint.
- */
- if (RR->topology->isSupernode(peer->address())) {
- const Address with(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
- const SharedPtr<Peer> withPeer(RR->topology->getPeer(with));
- if (withPeer) {
- const unsigned int port = at<uint16_t>(ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT);
- const unsigned int addrlen = (*this)[ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN];
- if ((port > 0)&&((addrlen == 4)||(addrlen == 16))) {
- 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());
- peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP);
- RR->sw->contact(withPeer,atAddr);
- } else {
- TRACE("dropped corrupt RENDEZVOUS from %s(%s) (bad address or port)",peer->address().toString().c_str(),_remoteAddress.toString().c_str());
- }
+ const Address with(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
+ const SharedPtr<Peer> withPeer(RR->topology->getPeer(with));
+ if (withPeer) {
+ const unsigned int port = at<uint16_t>(ZT_PROTO_VERB_RENDEZVOUS_IDX_PORT);
+ const unsigned int addrlen = (*this)[ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRLEN];
+ if ((port > 0)&&((addrlen == 4)||(addrlen == 16))) {
+ 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());
+ peer->received(RR,_remoteAddress,hops(),packetId(),Packet::VERB_RENDEZVOUS,0,Packet::VERB_NOP);
+ RR->sw->contact(withPeer,atAddr);
} else {
- TRACE("ignored RENDEZVOUS from %s(%s) to meet unknown peer %s",peer->address().toString().c_str(),_remoteAddress.toString().c_str(),with.toString().c_str());
+ TRACE("dropped corrupt RENDEZVOUS from %s(%s) (bad address or port)",peer->address().toString().c_str(),_remoteAddress.toString().c_str());
}
} else {
- TRACE("ignored RENDEZVOUS from %s(%s): source not supernode",peer->address().toString().c_str(),_remoteAddress.toString().c_str());
+ TRACE("ignored RENDEZVOUS from %s(%s) to meet unknown peer %s",peer->address().toString().c_str(),_remoteAddress.toString().c_str(),with.toString().c_str());
}
} catch (std::exception &ex) {
TRACE("dropped RENDEZVOUS from %s(%s): %s",peer->address().toString().c_str(),_remoteAddress.toString().c_str(),ex.what());
diff --git a/node/Network.cpp b/node/Network.cpp
index deb05d1c..e513f43f 100644
--- a/node/Network.cpp
+++ b/node/Network.cpp
@@ -264,7 +264,7 @@ void Network::requestConfiguration()
outp.append((uint64_t)_config->revision());
else outp.append((uint64_t)0);
}
- RR->sw->send(outp,true);
+ RR->sw->send(outp,true,_id);
}
void Network::addMembershipCertificate(const CertificateOfMembership &cert,bool forceAccept)
@@ -498,12 +498,11 @@ bool Network::_isAllowed(const Address &peer) const
std::vector<MulticastGroup> Network::_allMulticastGroups() const
{
// Assumes _lock is locked
- std::vector<MulticastGroup> mgs(_myMulticastGroups);
- std::vector<MulticastGroup>::iterator oldend(mgs.end());
- for(std::map< MulticastGroup,uint64_t >::const_iterator i(_multicastGroupsBehindMe.begin());i!=_multicastGroupsBehindMe.end();++i) {
- if (!std::binary_search(mgs.begin(),oldend,i->first))
- mgs.push_back(i->first);
- }
+ std::vector<MulticastGroup> mgs;
+ mgs.reserve(_myMulticastGroups.size() + _multicastGroupsBehindMe.size() + 1);
+ mgs.insert(mgs.end(),_myMulticastGroups.begin(),_myMulticastGroups.end());
+ for(std::map< MulticastGroup,uint64_t >::const_iterator i(_multicastGroupsBehindMe.begin());i!=_multicastGroupsBehindMe.end();++i)
+ mgs.push_back(i->first);
if ((_config)&&(_config->enableBroadcast()))
mgs.push_back(Network::BROADCAST);
std::sort(mgs.begin(),mgs.end());
diff --git a/node/NetworkConfig.cpp b/node/NetworkConfig.cpp
index 82e986e2..4b9620a6 100644
--- a/node/NetworkConfig.cpp
+++ b/node/NetworkConfig.cpp
@@ -184,9 +184,11 @@ void NetworkConfig::_fromDictionary(const Dictionary &d)
std::vector<std::string> relaysSplit(Utils::split(d.get(ZT_NETWORKCONFIG_DICT_KEY_RELAYS,"").c_str(),",","",""));
for(std::vector<std::string>::const_iterator r(relaysSplit.begin());r!=relaysSplit.end();++r) {
std::size_t semi(r->find(';')); // address;ip/port,...
- if ((semi == ZT_ADDRESS_LENGTH)&&(r->length() > (ZT_ADDRESS_LENGTH + 1))) {
- std::pair<Address,InetAddress> relay(Address(r->substr(0,semi)),InetAddress(r->substr(semi+1)));
- if ((relay.first)&&(relay.second))
+ if (semi == ZT_ADDRESS_LENGTH_HEX) {
+ std::pair<Address,InetAddress> relay(
+ Address(r->substr(0,semi)),
+ ((r->length() > (semi + 1)) ? InetAddress(r->substr(semi + 1)) : InetAddress()) );
+ if ((relay.first)&&(!relay.first.isReserved()))
_relays.push_back(relay);
}
}
diff --git a/node/Node.cpp b/node/Node.cpp
index c5c9873c..9f195a10 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -184,27 +184,41 @@ ZT1_ResultCode Node::processVirtualNetworkFrame(
class _PingPeersThatNeedPing
{
public:
- _PingPeersThatNeedPing(const RuntimeEnvironment *renv,uint64_t now) :
+ _PingPeersThatNeedPing(const RuntimeEnvironment *renv,uint64_t now,const std::vector< std::pair<Address,InetAddress> > &relays) :
lastReceiveFromUpstream(0),
RR(renv),
_now(now),
- _supernodes(RR->topology->supernodeAddresses()) {}
+ _relays(relays),
+ _supernodes(RR->topology->supernodeAddresses())
+ {
+ }
uint64_t lastReceiveFromUpstream;
inline void operator()(Topology &t,const SharedPtr<Peer> &p)
{
- if (std::find(_supernodes.begin(),_supernodes.end(),p->address()) != _supernodes.end()) {
+ bool isRelay = false;
+ for(std::vector< std::pair<Address,InetAddress> >::const_iterator r(_relays.begin());r!=_relays.end();++r) {
+ if (r->first == p->address()) {
+ isRelay = true;
+ break;
+ }
+ }
+
+ if ((isRelay)||(std::find(_supernodes.begin(),_supernodes.end(),p->address()) != _supernodes.end())) {
p->doPingAndKeepalive(RR,_now);
if (p->lastReceive() > lastReceiveFromUpstream)
lastReceiveFromUpstream = p->lastReceive();
- } else if (p->alive(_now)) {
- p->doPingAndKeepalive(RR,_now);
+ } else {
+ if (p->alive(_now))
+ p->doPingAndKeepalive(RR,_now);
}
}
+
private:
const RuntimeEnvironment *RR;
uint64_t _now;
+ const std::vector< std::pair<Address,InetAddress> > &_relays;
std::vector<Address> _supernodes;
};
@@ -214,54 +228,70 @@ ZT1_ResultCode Node::processBackgroundTasks(uint64_t now,volatile uint64_t *next
Mutex::Lock bl(_backgroundTasksLock);
if ((now - _lastPingCheck) >= ZT_PING_CHECK_INVERVAL) {
- _lastPingCheck = now;
-
try {
- _PingPeersThatNeedPing pfunc(RR,now);
+ _lastPingCheck = now;
+
+ // Get relays and networks that need config without leaving the mutex locked
+ std::vector< std::pair<Address,InetAddress> > networkRelays;
+ std::vector< SharedPtr<Network> > needConfig;
+ {
+ Mutex::Lock _l(_networks_m);
+ for(std::map< uint64_t,SharedPtr<Network> >::const_iterator n(_networks.begin());n!=_networks.end();++n) {
+ SharedPtr<NetworkConfig> nc(n->second->config2());
+ if (((now - n->second->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY)||(!nc))
+ needConfig.push_back(n->second);
+ if (nc)
+ networkRelays.insert(networkRelays.end(),nc->relays().begin(),nc->relays().end());
+ }
+ }
+
+ // Request updated configuration for networks that need it
+ for(std::vector< SharedPtr<Network> >::const_iterator n(needConfig.begin());n!=needConfig.end();++n)
+ (*n)->requestConfiguration();
+
+ // Attempt to contact network preferred relays that we don't have direct links to
+ std::sort(networkRelays.begin(),networkRelays.end());
+ std::unique(networkRelays.begin(),networkRelays.end());
+ for(std::vector< std::pair<Address,InetAddress> >::const_iterator nr(networkRelays.begin());nr!=networkRelays.end();++nr) {
+ if (nr->second) {
+ SharedPtr<Peer> rp(RR->topology->getPeer(nr->first));
+ if ((rp)&&(!rp->hasActiveDirectPath(now)))
+ rp->attemptToContactAt(RR,nr->second,now);
+ }
+ }
+
+ // Ping living or supernode/relay peers
+ _PingPeersThatNeedPing pfunc(RR,now,networkRelays);
RR->topology->eachPeer<_PingPeersThatNeedPing &>(pfunc);
+ // Update online status, post status change as event
bool oldOnline = _online;
_online = ((now - pfunc.lastReceiveFromUpstream) < ZT_PEER_ACTIVITY_TIMEOUT);
if (oldOnline != _online)
postEvent(_online ? ZT1_EVENT_ONLINE : ZT1_EVENT_OFFLINE);
- } catch ( ... ) {
- return ZT1_RESULT_FATAL_ERROR_INTERNAL;
- }
- try {
- Mutex::Lock _l(_networks_m);
- for(std::map< uint64_t,SharedPtr<Network> >::const_iterator n(_networks.begin());n!=_networks.end();++n) {
- if ((now - n->second->lastConfigUpdate()) >= ZT_NETWORK_AUTOCONF_DELAY)
- n->second->requestConfiguration();
+ // Send LAN beacons
+ if ((now - _lastBeacon) >= ZT_BEACON_INTERVAL) {
+ _lastBeacon = now;
+ char beacon[13];
+ void *p = beacon;
+ *(reinterpret_cast<uint32_t *>(p)) = RR->prng->next32();
+ p = beacon + 4;
+ *(reinterpret_cast<uint32_t *>(p)) = RR->prng->next32();
+ RR->identity.address().copyTo(beacon + 8,5);
+ RR->antiRec->logOutgoingZT(beacon,13);
+ putPacket(ZT_DEFAULTS.v4Broadcast,beacon,13);
}
} catch ( ... ) {
return ZT1_RESULT_FATAL_ERROR_INTERNAL;
}
-
- if ((now - _lastBeacon) >= ZT_BEACON_INTERVAL) {
- _lastBeacon = now;
- char beacon[13];
- void *p = beacon;
- *(reinterpret_cast<uint32_t *>(p)) = RR->prng->next32();
- p = beacon + 4;
- *(reinterpret_cast<uint32_t *>(p)) = RR->prng->next32();
- RR->identity.address().copyTo(beacon + 8,5);
- RR->antiRec->logOutgoingZT(beacon,13);
- putPacket(ZT_DEFAULTS.v4Broadcast,beacon,13);
- }
}
if ((now - _lastHousekeepingRun) >= ZT_HOUSEKEEPING_PERIOD) {
- _lastHousekeepingRun = now;
-
try {
+ _lastHousekeepingRun = now;
RR->topology->clean(now);
RR->sa->clean(now);
- } catch ( ... ) {
- return ZT1_RESULT_FATAL_ERROR_INTERNAL;
- }
-
- try {
RR->mc->clean(now);
} catch ( ... ) {
return ZT1_RESULT_FATAL_ERROR_INTERNAL;
diff --git a/node/OutboundMulticast.cpp b/node/OutboundMulticast.cpp
index 80dd661c..f62046be 100644
--- a/node/OutboundMulticast.cpp
+++ b/node/OutboundMulticast.cpp
@@ -108,14 +108,14 @@ void OutboundMulticast::sendOnly(const RuntimeEnvironment *RR,const Address &toA
_packetWithCom.newInitializationVector();
_packetWithCom.setDestination(toAddr);
//TRACE(">>MC %.16llx -> %s (with COM)",(unsigned long long)this,toAddr.toString().c_str());
- RR->sw->send(_packetWithCom,true);
+ RR->sw->send(_packetWithCom,true,_nwid);
return;
}
}
//TRACE(">>MC %.16llx -> %s (without COM)",(unsigned long long)this,toAddr.toString().c_str());
_packetNoCom.newInitializationVector();
_packetNoCom.setDestination(toAddr);
- RR->sw->send(_packetNoCom,true);
+ RR->sw->send(_packetNoCom,true,_nwid);
}
} // namespace ZeroTier
diff --git a/node/Salsa20.hpp b/node/Salsa20.hpp
index 0c1f3be4..9631a6db 100644
--- a/node/Salsa20.hpp
+++ b/node/Salsa20.hpp
@@ -7,10 +7,16 @@
#ifndef ZT_SALSA20_HPP
#define ZT_SALSA20_HPP
+#include <stdio.h>
#include <stdint.h>
+#include <stdlib.h>
#include "Constants.hpp"
+#if (!defined(ZT_SALSA20_SSE)) && (defined(__SSE2__) || defined(__WINDOWS__))
+#define ZT_SALSA20_SSE 1
+#endif
+
#ifdef ZT_SALSA20_SSE
#include <emmintrin.h>
#endif // ZT_SALSA20_SSE
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;
}
diff --git a/node/Switch.hpp b/node/Switch.hpp
index e944c843..0ba4c138 100644
--- a/node/Switch.hpp
+++ b/node/Switch.hpp
@@ -111,8 +111,9 @@ public:
*
* @param packet Packet to send
* @param encrypt Encrypt packet payload? (always true except for HELLO)
+ * @param nwid Network ID or 0 if message is not related to a specific network
*/
- void send(const Packet &packet,bool encrypt);
+ void send(const Packet &packet,bool encrypt,uint64_t nwid);
/**
* Send RENDEZVOUS to two peers to permit them to directly connect
@@ -183,15 +184,8 @@ private:
void _handleRemotePacketFragment(const InetAddress &fromAddr,const void *data,unsigned int len);
void _handleRemotePacketHead(const InetAddress &fromAddr,const void *data,unsigned int len);
void _handleBeacon(const InetAddress &fromAddr,const Buffer<ZT_PROTO_BEACON_LENGTH> &data);
-
- Address _sendWhoisRequest(
- const Address &addr,
- const Address *peersAlreadyConsulted,
- unsigned int numPeersAlreadyConsulted);
-
- bool _trySend(
- const Packet &packet,
- bool encrypt);
+ Address _sendWhoisRequest(const Address &addr,const Address *peersAlreadyConsulted,unsigned int numPeersAlreadyConsulted);
+ bool _trySend(const Packet &packet,bool encrypt,uint64_t nwid);
const RuntimeEnvironment *const RR;
volatile uint64_t _lastBeacon;
@@ -226,13 +220,15 @@ private:
struct TXQueueEntry
{
TXQueueEntry() {}
- TXQueueEntry(uint64_t ct,const Packet &p,bool enc) :
+ TXQueueEntry(uint64_t ct,const Packet &p,bool enc,uint64_t nw) :
creationTime(ct),
+ nwid(nw),
packet(p),
encrypt(enc) {}
uint64_t creationTime;
- Packet packet; // unencrypted/untagged for TX queue
+ uint64_t nwid;
+ Packet packet; // unencrypted/unMAC'd packet -- this is done at send time
bool encrypt;
};
std::multimap< Address,TXQueueEntry > _txQueue;
diff --git a/node/Topology.hpp b/node/Topology.hpp
index 63c81016..56a9709f 100644
--- a/node/Topology.hpp
+++ b/node/Topology.hpp
@@ -157,11 +157,6 @@ public:
}
/**
- * @return True if this node's identity is in the supernode set
- */
- inline bool amSupernode() const { return _amSupernode; }
-
- /**
* Clean and flush database
*/
void clean(uint64_t now);