- Sort introducers in router address, so we won't force a republish
due to a different ordering of the same introducers
- Don't publish an address if we need introducers but don't have any,
so the user won't see a 'firewalled with inbound NTCP enabled' message
This commit is contained in:
zzz
2015-01-29 20:34:49 +00:00
parent 86b45ab1e5
commit 175806115b
4 changed files with 51 additions and 9 deletions

View File

@ -1,5 +1,10 @@
2015-01-29 zzz
* SSU: Fix replaceExternalAddress churn when firewalled
* SSU:
- Fix replaceExternalAddress churn when firewalled
- Sort introducers in router address, so we won't force a republish
due to a different ordering of the same introducers
- Don't publish an address if we need introducers but don't have any,
so the user won't see a 'firewalled with inbound NTCP enabled' message
2015-01-28 zzz
* UPnP:

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */
public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 13;
public final static long BUILD = 14;
/** for example "-test" */
public final static String EXTRA = "";

View File

@ -3,6 +3,7 @@ package net.i2p.router.transport.udp;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -176,6 +177,7 @@ class IntroductionManager {
// if not too many to choose from, be less picky
if (sz <= howMany + 2)
inactivityCutoff -= UDPTransport.EXPIRE_TIMEOUT / 4;
List<Introducer> introducers = new ArrayList<Introducer>(howMany);
for (int i = 0; i < sz && found < howMany; i++) {
PeerState cur = peers.get((start + i) % sz);
RouterInfo ri = _context.netDb().lookupRouterInfoLocally(cur.getRemotePeer());
@ -222,19 +224,45 @@ class IntroductionManager {
byte[] ikey = ura.getIntroKey();
if (ikey == null)
continue;
ssuOptions.setProperty(UDPAddress.PROP_INTRO_HOST_PREFIX + found, Addresses.toString(ip));
ssuOptions.setProperty(UDPAddress.PROP_INTRO_PORT_PREFIX + found, String.valueOf(port));
ssuOptions.setProperty(UDPAddress.PROP_INTRO_KEY_PREFIX + found, Base64.encode(ikey));
ssuOptions.setProperty(UDPAddress.PROP_INTRO_TAG_PREFIX + found, String.valueOf(cur.getTheyRelayToUsAs()));
introducers.add(new Introducer(ip, port, ikey, cur.getTheyRelayToUsAs()));
found++;
}
// we sort them so a change in order only won't happen, and won't cause a republish
Collections.sort(introducers);
for (int i = 0; i < found; i++) {
Introducer in = introducers.get(i);
ssuOptions.setProperty(UDPAddress.PROP_INTRO_HOST_PREFIX + i, in.sip);
ssuOptions.setProperty(UDPAddress.PROP_INTRO_PORT_PREFIX + i, in.sport);
ssuOptions.setProperty(UDPAddress.PROP_INTRO_KEY_PREFIX + i, in.skey);
ssuOptions.setProperty(UDPAddress.PROP_INTRO_TAG_PREFIX + i, in.stag);
}
// FIXME failsafe if found == 0, relax inactivityCutoff and try again?
pingIntroducers();
return found;
}
/**
* So we can sort them
* @since 0.9.18
*/
private static class Introducer implements Comparable<Introducer> {
public final String sip, sport, skey, stag;
public Introducer(byte[] ip, int port, byte[] key, long tag) {
sip = Addresses.toString(ip);
sport = String.valueOf(port);
skey = Base64.encode(key);
stag = String.valueOf(tag);
}
public int compareTo(Introducer i) {
return skey.compareTo(i.skey);
}
}
/**
* Was part of pickInbound(), moved out so we can call it more often
* @since 0.8.11

View File

@ -1878,9 +1878,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
boolean introducersIncluded = false;
if (introducersRequired) {
// FIXME intro manager doesn't sort introducers, so
// deepEquals() below can fail even with same introducers.
// Only a problem when we have very very few peers to pick from.
// intro manager now sorts introducers, so
// deepEquals() below will not fail even with same introducers.
// Was only a problem when we had very very few peers to pick from.
int found = _introManager.pickInbound(options, PUBLIC_RELAY_COUNT);
if (found > 0) {
if (_log.shouldLog(Log.INFO))
@ -1974,6 +1974,15 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
_log.warn("Wanted to rebuild my SSU address, but couldn't specify either the direct or indirect info (needs introducers? "
+ introducersRequired + ")", new Exception("source"));
_needsRebuild = true;
if (hasCurrentAddress()) {
// We must remove current address, otherwise the user will see
// "firewalled with inbound NTCP enabled" warning in console.
// Unfortunately this will remove any IPv6 also,
// but we don't have a method to remove just the IPv4 address. FIXME
replaceAddress(null);
if (allowRebuildRouterInfo)
_context.router().rebuildRouterInfo();
}
return null;
}
}