summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--node/Constants.hpp5
-rw-r--r--node/Packet.hpp1
-rw-r--r--node/Peer.cpp63
-rw-r--r--node/Peer.hpp3
4 files changed, 67 insertions, 5 deletions
diff --git a/node/Constants.hpp b/node/Constants.hpp
index ac9dbc99..1f0d8426 100644
--- a/node/Constants.hpp
+++ b/node/Constants.hpp
@@ -320,6 +320,11 @@
#define ZT_MIN_PATH_CONFIRMATION_INTERVAL 5000
/**
+ * Interval between direct path pushes in milliseconds
+ */
+#define ZT_DIRECT_PATH_PUSH_INTERVAL 300000
+
+/**
* Sanity limit on maximum bridge routes
*
* If the number of bridge routes exceeds this, we cull routes from the
diff --git a/node/Packet.hpp b/node/Packet.hpp
index 14fac1bf..9b86709a 100644
--- a/node/Packet.hpp
+++ b/node/Packet.hpp
@@ -892,7 +892,6 @@ public:
VERB_SET_EPHEMERAL_KEY = 15,
/* Push of potential endpoints for direct communication:
- * <[1] flags (unused, must be zero)>
* <[2] 16-bit number of paths>
* <[...] paths>
*
diff --git a/node/Peer.cpp b/node/Peer.cpp
index cb046b9b..ec04357a 100644
--- a/node/Peer.cpp
+++ b/node/Peer.cpp
@@ -208,9 +208,66 @@ void Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now)
}
}
-//void Peer::pushDirectPaths(const std::vector<Path> &dps,uint64_t now,bool force)
-//{
-//}
+void Peer::pushDirectPaths(const RuntimeEnvironment *RR,const std::vector<Path> &dps,uint64_t now,bool force)
+{
+ if (((now - _lastDirectPathPush) >= ZT_DIRECT_PATH_PUSH_INTERVAL)||(force)) {
+ _lastDirectPathPush = now;
+
+ std::vector<Path>::const_iterator p(dps.begin());
+ while (p != dps.end()) {
+ Packet outp(_id.address(),RR->identity.address(),Packet::VERB_PUSH_DIRECT_PATHS);
+ outp.addSize(2); // leave room for count
+
+ unsigned int count = 0;
+ while ((p != dps.end())&&((outp.size() + 24) < ZT_PROTO_MAX_PACKET_LENGTH)) {
+ uint8_t addressType = 4;
+ switch(p->address().ss_family) {
+ case AF_INET:
+ break;
+ case AF_INET6:
+ addressType = 6;
+ break;
+ default:
+ ++p;
+ continue;
+ }
+
+ uint8_t flags = 0;
+ if (p->metric() < 0)
+ flags |= (0x01 | 0x02); // forget and blacklist
+ else {
+ if (p->reliable())
+ flags |= 0x04; // no NAT keepalives and such
+ switch(p->trust()) {
+ default:
+ break;
+ case Path::TRUST_PRIVACY:
+ flags |= 0x08; // no encryption
+ break;
+ case Path::TRUST_ULTIMATE:
+ flags |= (0x08 | 0x10); // no encryption, no authentication (redundant but go ahead and set both)
+ break;
+ }
+ }
+
+ outp.append(flags);
+ outp.append((uint8_t)((p->metric() >= 0) ? ((p->metric() <= 255) ? p->metric() : 255) : 0));
+ outp.append((uint16_t)0);
+ outp.append(addressType);
+ outp.append(p->address().rawIpData(),((addressType == 4) ? 4 : 16));
+ outp.append((uint16_t)p->address().port());
+
+ ++count;
+ ++p;
+ }
+
+ if (count) {
+ outp.setAt(ZT_PACKET_IDX_PAYLOAD,(uint16_t)count);
+ RR->sw->send(outp,true,0);
+ }
+ }
+ }
+}
void Peer::addPath(const RemotePath &newp)
{
diff --git a/node/Peer.hpp b/node/Peer.hpp
index 6ca29393..2af3b9e6 100644
--- a/node/Peer.hpp
+++ b/node/Peer.hpp
@@ -181,11 +181,12 @@ public:
/**
* Push direct paths (if within rate limit)
*
+ * @param RR Runtime environment
* @param dps Direct paths to me to push to this peer
* @param now Current time
* @param force If true, force regardless of when we pushed direct paths last
*/
- void pushDirectPaths(const std::vector<InetAddress> &dps,uint64_t now,bool force);
+ void pushDirectPaths(const RuntimeEnvironment *RR,const std::vector<Path> &dps,uint64_t now,bool force);
/**
* @return All known direct paths to this peer