Browse Source

Add delay to NAT-t escalation stuff to try to address GitHub issue #167

Adam Ierymenko 10 years ago
parent
commit
196f27f1f0
2 changed files with 25 additions and 36 deletions
  1. 24 35
      node/Switch.cpp
  2. 1 1
      node/Switch.hpp

+ 24 - 35
node/Switch.cpp

@@ -444,42 +444,31 @@ unsigned long Switch::doTimerTasks(uint64_t now)
 					continue;
 					continue;
 				} else {
 				} else {
 					// Nope, nothing yet. Time to kill some kittens.
 					// Nope, nothing yet. Time to kill some kittens.
-
-					switch(qi->strategyIteration++) {
-
-						case 0: {
-							// First strategy: rifle method: direct packet to known port
-							qi->peer->attemptToContactAt(RR,qi->inaddr,now);
-						}	break;
-
-						case 1: {
-							// Second strategy: shotgun method up: try a few ports above
-							InetAddress tmpaddr(qi->inaddr);
-							int p = (int)qi->inaddr.port();
-							for(int i=0;i<9;++i) {
-								if (++p > 0xffff) break;
-								tmpaddr.setPort((unsigned int)p);
-								qi->peer->attemptToContactAt(RR,tmpaddr,now);
-							}
-						}	break;
-
-						case 2: {
-							// Third strategy: shotgun method down: try a few ports below
-							InetAddress tmpaddr(qi->inaddr);
-							int p = (int)qi->inaddr.port();
-							for(int i=0;i<3;++i) {
-								if (--p < 1024) break;
-								tmpaddr.setPort((unsigned int)p);
-								qi->peer->attemptToContactAt(RR,tmpaddr,now);
-							}
-
-							// We've tried all strategies
-							_contactQueue.erase(qi++);
-							continue;
-						}	break;
-
+					if (qi->strategyIteration == 0) {
+						// First stragegy: send packet directly (we already tried this but try again)
+						qi->peer->attemptToContactAt(RR,qi->inaddr,now);
+					} else if (qi->strategyIteration <= 9) {
+						// Strategies 1-9: try escalating ports
+						InetAddress tmpaddr(qi->inaddr);
+						int p = (int)qi->inaddr.port() + qi->strategyIteration;
+						if (p < 0xffff) {
+							tmpaddr.setPort((unsigned int)p);
+							qi->peer->attemptToContactAt(RR,tmpaddr,now);
+						}
+					} else if (qi->strategyIteration <= 18) {
+						// Strategies 10-18: try ports below
+						InetAddress tmpaddr(qi->inaddr);
+						int p = (int)qi->inaddr.port() - (qi->strategyIteration - 9);
+						if (p >= 1024) {
+							tmpaddr.setPort((unsigned int)p);
+							qi->peer->attemptToContactAt(RR,tmpaddr,now);
+						}
+					} else {
+						// All strategies tried, expire entry
+						_contactQueue.erase(qi++);
+						continue;
 					}
 					}
-
+					++qi->strategyIteration;
 					qi->fireAtTime = now + ZT_NAT_T_TACTICAL_ESCALATION_DELAY;
 					qi->fireAtTime = now + ZT_NAT_T_TACTICAL_ESCALATION_DELAY;
 					nextDelay = std::min(nextDelay,(unsigned long)ZT_NAT_T_TACTICAL_ESCALATION_DELAY);
 					nextDelay = std::min(nextDelay,(unsigned long)ZT_NAT_T_TACTICAL_ESCALATION_DELAY);
 				}
 				}

+ 1 - 1
node/Switch.hpp

@@ -250,7 +250,7 @@ private:
 			peer(p),
 			peer(p),
 			fireAtTime(ft),
 			fireAtTime(ft),
 			inaddr(a),
 			inaddr(a),
-			strategyIteration(1) {} // start with 2nd strategy, since first was tried at inception
+			strategyIteration(0) {}
 
 
 		SharedPtr<Peer> peer;
 		SharedPtr<Peer> peer;
 		uint64_t fireAtTime;
 		uint64_t fireAtTime;