Try bringing back TTL escalation -- may help with Docker (IP-MASQ) type NAT

This commit is contained in:
Adam Ierymenko 2015-11-09 15:44:13 -08:00
commit 2cc50bdb10
7 changed files with 58 additions and 19 deletions

View file

@ -149,9 +149,10 @@ public:
* @param addr Destination address
* @param data Packet data
* @param len Packet length
* @param ttl Desired TTL (default: 0 for unchanged/default TTL)
* @return True if packet appears to have been sent
*/
inline bool putPacket(const InetAddress &localAddress,const InetAddress &addr,const void *data,unsigned int len)
inline bool putPacket(const InetAddress &localAddress,const InetAddress &addr,const void *data,unsigned int len,unsigned int ttl = 0)
{
return (_wirePacketSendFunction(
reinterpret_cast<ZT_Node *>(this),
@ -159,7 +160,8 @@ public:
reinterpret_cast<const struct sockaddr_storage *>(&localAddress),
reinterpret_cast<const struct sockaddr_storage *>(&addr),
data,
len) == 0);
len,
ttl) == 0);
}
/**

View file

@ -211,7 +211,7 @@ void Peer::received(
}
}
void Peer::sendHELLO(const RuntimeEnvironment *RR,const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now)
void Peer::sendHELLO(const RuntimeEnvironment *RR,const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,unsigned int ttl)
{
// _lock not required here since _id is immutable and nothing else is accessed
@ -228,7 +228,7 @@ void Peer::sendHELLO(const RuntimeEnvironment *RR,const InetAddress &localAddr,c
outp.armor(_key,false); // HELLO is sent in the clear
RR->antiRec->logOutgoingZT(outp.data(),outp.size());
RR->node->putPacket(localAddr,atAddress,outp.data(),outp.size());
RR->node->putPacket(localAddr,atAddress,outp.data(),outp.size(),ttl);
}
bool Peer::doPingAndKeepalive(const RuntimeEnvironment *RR,uint64_t now,int inetAddressFamily)

View file

@ -170,8 +170,9 @@ public:
* @param localAddr Local address
* @param atAddress Destination address
* @param now Current time
* @param ttl Desired IP TTL (default: 0 to leave alone)
*/
void sendHELLO(const RuntimeEnvironment *RR,const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now);
void sendHELLO(const RuntimeEnvironment *RR,const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,unsigned int ttl = 0);
/**
* Send pings or keepalives depending on configured timeouts

View file

@ -435,7 +435,7 @@ void Switch::rendezvous(const SharedPtr<Peer> &peer,const InetAddress &localAddr
{
TRACE("sending NAT-t message to %s(%s)",peer->address().toString().c_str(),atAddr.toString().c_str());
const uint64_t now = RR->node->now();
peer->sendHELLO(RR,localAddr,atAddr,now);
peer->sendHELLO(RR,localAddr,atAddr,now,2); // first attempt: send low-TTL packet to 'open' local NAT
{
Mutex::Lock _l(_contactQueue_m);
_contactQueue.push_back(ContactQueueEntry(peer,now + ZT_NAT_T_TACTICAL_ESCALATION_DELAY,localAddr,atAddr));
@ -509,8 +509,8 @@ unsigned long Switch::doTimerTasks(uint64_t now)
if (qi->strategyIteration == 0) {
// First strategy: send packet directly to destination
qi->peer->sendHELLO(RR,qi->localAddr,qi->inaddr,now);
} else if (qi->strategyIteration <= 4) {
// Strategies 1-4: try escalating ports for symmetric NATs that remap sequentially
} else if (qi->strategyIteration <= 3) {
// Strategies 1-3: try escalating ports for symmetric NATs that remap sequentially
InetAddress tmpaddr(qi->inaddr);
int p = (int)qi->inaddr.port() + qi->strategyIteration;
if (p < 0xffff) {