summaryrefslogtreecommitdiff
path: root/node/Peer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'node/Peer.cpp')
-rw-r--r--node/Peer.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/node/Peer.cpp b/node/Peer.cpp
index 73c20228..804e6e39 100644
--- a/node/Peer.cpp
+++ b/node/Peer.cpp
@@ -33,6 +33,7 @@
#include "Switch.hpp"
#include "Network.hpp"
#include "AntiRecursion.hpp"
+#include "SelfAwareness.hpp"
#include <algorithm>
@@ -229,6 +230,24 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_
_lastDirectPathPush = now;
std::vector<Path> dps(RR->node->directPaths());
+
+ /* Also push paths reported to us by non-root-server peers. This assists
+ * with NAT traversal behind NATs that engage in strange or randomized
+ * port assignment behavior. */
+ std::vector<Address> rootAddresses(RR->topology->rootAddresses());
+ std::vector< std::pair<Address,InetAddress> > surface(RR->sa->getReportedSurface());
+ for(std::vector< std::pair<Address,InetAddress> >::const_iterator s(surface.begin());s!=surface.end();++s) {
+ bool alreadyHave = false;
+ for(std::vector<Path>::const_iterator p(dps.begin());p!=dps.end();++p) {
+ if (p->address() == s->second) {
+ alreadyHave = true;
+ break;
+ }
+ }
+ if ((!alreadyHave)&&(std::find(rootAddresses.begin(),rootAddresses.end(),s->first) == rootAddresses.end()))
+ dps.push_back(Path(s->second,0,Path::TRUST_NORMAL));
+ }
+
#ifdef ZT_TRACE
{
std::string ps;