* UDP: Bid lower than NTCP when we need introducers and don't

have enough; was preventing firewalled routers from
      being reachable
This commit is contained in:
zzz
2009-12-26 20:25:32 +00:00
parent 72a588bfbf
commit d92dfec1bf
2 changed files with 38 additions and 11 deletions

View File

@ -23,9 +23,9 @@ public class IntroductionManager {
private UDPTransport _transport; private UDPTransport _transport;
private PacketBuilder _builder; private PacketBuilder _builder;
/** map of relay tag to PeerState that should receive the introduction */ /** map of relay tag to PeerState that should receive the introduction */
private Map _outbound; private Map<Long, PeerState> _outbound;
/** list of peers (PeerState) who have given us introduction tags */ /** list of peers (PeerState) who have given us introduction tags */
private final List _inbound; private final List<PeerState> _inbound;
public IntroductionManager(RouterContext ctx, UDPTransport transport) { public IntroductionManager(RouterContext ctx, UDPTransport transport) {
_context = ctx; _context = ctx;
@ -74,7 +74,7 @@ public class IntroductionManager {
} }
public PeerState get(long id) { public PeerState get(long id) {
return (PeerState)_outbound.get(new Long(id)); return _outbound.get(new Long(id));
} }
/** /**
@ -90,7 +90,7 @@ public class IntroductionManager {
* and we want to keep our introducers valid. * and we want to keep our introducers valid.
*/ */
public int pickInbound(Properties ssuOptions, int howMany) { public int pickInbound(Properties ssuOptions, int howMany) {
List peers = null; List<PeerState> peers = null;
int start = _context.random().nextInt(Integer.MAX_VALUE); int start = _context.random().nextInt(Integer.MAX_VALUE);
synchronized (_inbound) { synchronized (_inbound) {
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
@ -103,7 +103,7 @@ public class IntroductionManager {
int found = 0; int found = 0;
long inactivityCutoff = _context.clock().now() - (UDPTransport.EXPIRE_TIMEOUT / 2); long inactivityCutoff = _context.clock().now() - (UDPTransport.EXPIRE_TIMEOUT / 2);
for (int i = 0; i < sz && found < howMany; i++) { for (int i = 0; i < sz && found < howMany; i++) {
PeerState cur = (PeerState)peers.get((start + i) % sz); PeerState cur = peers.get((start + i) % sz);
RouterInfo ri = _context.netDb().lookupRouterInfoLocally(cur.getRemotePeer()); RouterInfo ri = _context.netDb().lookupRouterInfoLocally(cur.getRemotePeer());
if (ri == null) { if (ri == null) {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
@ -144,7 +144,7 @@ public class IntroductionManager {
long pingCutoff = _context.clock().now() - (2 * 60 * 60 * 1000); long pingCutoff = _context.clock().now() - (2 * 60 * 60 * 1000);
inactivityCutoff = _context.clock().now() - (UDPTransport.EXPIRE_TIMEOUT / 4); inactivityCutoff = _context.clock().now() - (UDPTransport.EXPIRE_TIMEOUT / 4);
for (int i = 0; i < sz; i++) { for (int i = 0; i < sz; i++) {
PeerState cur = (PeerState)peers.get(i); PeerState cur = peers.get(i);
if (cur.getIntroducerTime() > pingCutoff && if (cur.getIntroducerTime() > pingCutoff &&
cur.getLastSendTime() < inactivityCutoff) { cur.getLastSendTime() < inactivityCutoff) {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
@ -157,6 +157,18 @@ public class IntroductionManager {
return found; return found;
} }
/**
* Not as elaborate as pickInbound() above.
* Just a quick check to see how many volunteers we know,
* which the Transport uses to see if we need more.
* @return number of peers that have volunteerd to introduce us
*/
int introducerCount() {
synchronized(_inbound) {
return _inbound.size();
}
}
void receiveRelayIntro(RemoteHostId bob, UDPPacketReader reader) { void receiveRelayIntro(RemoteHostId bob, UDPPacketReader reader) {
if (_context.router().isHidden()) if (_context.router().isHidden())
return; return;

View File

@ -461,13 +461,15 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
boolean updated = false; boolean updated = false;
boolean fireTest = false; boolean fireTest = false;
if (_log.shouldLog(Log.WARN))
_log.warn("Change address? status = " + _reachabilityStatus +
" diff = " + (_context.clock().now() - _reachabilityStatusLastUpdated) +
" old = " + _externalListenHost + ':' + _externalListenPort +
" new = " + DataHelper.toString(ourIP) + ':' + ourPort);
synchronized (this) { synchronized (this) {
if ( (_externalListenHost == null) || if ( (_externalListenHost == null) ||
(!eq(_externalListenHost.getAddress(), _externalListenPort, ourIP, ourPort)) ) { (!eq(_externalListenHost.getAddress(), _externalListenPort, ourIP, ourPort)) ) {
if (_log.shouldLog(Log.WARN))
_log.warn("Change address? status = " + _reachabilityStatus +
" diff = " + (_context.clock().now() - _reachabilityStatusLastUpdated) +
" old = " + _externalListenHost + ':' + _externalListenPort);
if ( (_reachabilityStatus != CommSystemFacade.STATUS_OK) || if ( (_reachabilityStatus != CommSystemFacade.STATUS_OK) ||
(_externalListenHost == null) || (_externalListenPort <= 0) || (_externalListenHost == null) || (_externalListenPort <= 0) ||
(_context.clock().now() - _reachabilityStatusLastUpdated > 2*TEST_FREQUENCY) ) { (_context.clock().now() - _reachabilityStatusLastUpdated > 2*TEST_FREQUENCY) ) {
@ -968,6 +970,11 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
return _endpoint.send(packet); return _endpoint.send(packet);
} }
/** minimum active peers to maintain IP detection, etc. */
private static final int MIN_PEERS = 3;
/** minimum peers volunteering to be introducers if we need that */
private static final int MIN_INTRODUCER_POOL = 4;
public TransportBid bid(RouterInfo toAddress, long dataSize) { public TransportBid bid(RouterInfo toAddress, long dataSize) {
if (dataSize > OutboundMessageState.MAX_MSG_SIZE) { if (dataSize > OutboundMessageState.MAX_MSG_SIZE) {
// NTCP max is lower, so msg will get dropped // NTCP max is lower, so msg will get dropped
@ -1015,11 +1022,16 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
// Try to maintain at least 3 peers so we can determine our IP address and // Try to maintain at least 3 peers so we can determine our IP address and
// we have a selection to run peer tests with. // we have a selection to run peer tests with.
// If we are firewalled, and we don't have enough peers that volunteered to
// also introduce us, also bid aggressively so we are preferred over NTCP.
// (Otherwise we only talk UDP to those that are firewalled, and we will
// never get any introducers)
int count; int count;
synchronized (_peersByIdent) { synchronized (_peersByIdent) {
count = _peersByIdent.size(); count = _peersByIdent.size();
} }
if (alwaysPreferUDP() || count < 3) if (alwaysPreferUDP() || count < MIN_PEERS ||
(introducersRequired() && _introManager.introducerCount() < MIN_INTRODUCER_POOL))
return _slowPreferredBid; return _slowPreferredBid;
else if (preferUDP()) else if (preferUDP())
return _slowBid; return _slowBid;
@ -1157,6 +1169,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
_log.info("Picked peers: " + found); _log.info("Picked peers: " + found);
_introducersSelectedOn = _context.clock().now(); _introducersSelectedOn = _context.clock().now();
introducersIncluded = true; introducersIncluded = true;
} else {
if (_log.shouldLog(Log.WARN))
_log.warn("Need introducers but we don't know any");
} }
} }