Router: Remove ancient version check in BuildRequestor

Add method to get all connected peers from transports, for efficiency
Don't try to build non-zero-hop tunnels in VMCommSystem
This commit is contained in:
zzz
2018-03-07 13:29:11 +00:00
parent 0eb04facec
commit 665f58d62a
10 changed files with 123 additions and 13 deletions

View File

@ -12,6 +12,7 @@ import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
@ -39,14 +40,14 @@ public abstract class CommSystemFacade implements Service {
* How many peers are we currently connected to, that we have * How many peers are we currently connected to, that we have
* sent a message to or received a message from in the last five minutes. * sent a message to or received a message from in the last five minutes.
*/ */
public int countActivePeers() { return 0; } public abstract int countActivePeers();
/** /**
* How many peers are we currently connected to, that we have * How many peers are we currently connected to, that we have
* sent a message to in the last minute. * sent a message to in the last minute.
* Unused for anything, to be removed. * Unused for anything, to be removed.
*/ */
public int countActiveSendPeers() { return 0; } public abstract int countActiveSendPeers();
public boolean haveInboundCapacity(int pct) { return true; } public boolean haveInboundCapacity(int pct) { return true; }
public boolean haveOutboundCapacity(int pct) { return true; } public boolean haveOutboundCapacity(int pct) { return true; }
@ -90,7 +91,7 @@ public abstract class CommSystemFacade implements Service {
public boolean isBacklogged(Hash peer) { return false; } public boolean isBacklogged(Hash peer) { return false; }
public boolean wasUnreachable(Hash peer) { return false; } public boolean wasUnreachable(Hash peer) { return false; }
public boolean isEstablished(Hash peer) { return false; } public abstract boolean isEstablished(Hash peer);
public byte[] getIP(Hash dest) { return null; } public byte[] getIP(Hash dest) { return null; }
public void queueLookup(byte[] ip) {} public void queueLookup(byte[] ip) {}
@ -128,6 +129,16 @@ public abstract class CommSystemFacade implements Service {
return new TreeMap<String, Transport>(); return new TreeMap<String, Transport>();
} }
/**
* Get all the peers we are connected to.
* This should be more efficient than repeated calls to isEstablished()
* if you have to check a lot.
*
* @return the hashes of all the routers we are connected to, non-null
* @since 0.9.34
*/
public abstract Set<Hash> getEstablished();
/** @since 0.8.13 */ /** @since 0.8.13 */
public boolean isDummy() { return true; } public boolean isDummy() { return true; }

View File

@ -4,7 +4,9 @@ import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import net.i2p.data.Hash; import net.i2p.data.Hash;
import net.i2p.data.i2np.I2NPMessage; import net.i2p.data.i2np.I2NPMessage;
@ -47,6 +49,23 @@ public class VMCommSystem extends CommSystemFacade {
_context.statManager().createRequiredRateStat("transport.sendProcessingTime", "Time to process and send a message (ms)", "Transport", new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000l }); _context.statManager().createRequiredRateStat("transport.sendProcessingTime", "Time to process and send a message (ms)", "Transport", new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
} }
public int countActivePeers() { return _commSystemFacades.size() - 1; }
public int countActiveSendPeers() { return _commSystemFacades.size() - 1; }
public boolean isEstablished(Hash peer) { return _commSystemFacades.containsKey(peer); }
public Set<Hash> getEstablished() {
Set<Hash> rv;
synchronized (_commSystemFacades) {
rv = new HashSet<Hash>(_commSystemFacades.keySet());
}
Hash us = _context.routerHash();
if (us != null)
rv.remove(us);
return rv;
}
/** /**
* The router wants us to send the given message to the peer. Do so, or fire * The router wants us to send the given message to the peer. Do so, or fire
* off the failing job. * off the failing job.

View File

@ -576,10 +576,11 @@ public class ProfileOrganizer {
*/ */
public void selectActiveNotFailingPeers(int howMany, Set<Hash> exclude, Set<Hash> matches) { public void selectActiveNotFailingPeers(int howMany, Set<Hash> exclude, Set<Hash> matches) {
if (matches.size() < howMany) { if (matches.size() < howMany) {
Set<Hash> connected = _context.commSystem().getEstablished();
getReadLock(); getReadLock();
try { try {
for (Hash peer : _notFailingPeers.keySet()) { for (Hash peer : _notFailingPeers.keySet()) {
if (!_context.commSystem().isEstablished(peer)) if (!connected.contains(peer))
exclude.add(peer); exclude.add(peer);
} }
locked_selectPeers(_notFailingPeers, howMany, exclude, matches, 0); locked_selectPeers(_notFailingPeers, howMany, exclude, matches, 0);
@ -602,12 +603,14 @@ public class ProfileOrganizer {
*/ */
private void selectActiveNotFailingPeers2(int howMany, Set<Hash> exclude, Set<Hash> matches, int mask) { private void selectActiveNotFailingPeers2(int howMany, Set<Hash> exclude, Set<Hash> matches, int mask) {
if (matches.size() < howMany) { if (matches.size() < howMany) {
Map<Hash, PeerProfile> activePeers = new HashMap<Hash, PeerProfile>(); Set<Hash> connected = _context.commSystem().getEstablished();
Map<Hash, PeerProfile> activePeers = new HashMap<Hash, PeerProfile>(connected.size());
getReadLock(); getReadLock();
try { try {
for (Map.Entry<Hash, PeerProfile> e : _notFailingPeers.entrySet()) { for (Hash peer : connected) {
if (_context.commSystem().isEstablished(e.getKey())) PeerProfile prof = _notFailingPeers.get(peer);
activePeers.put(e.getKey(), e.getValue()); if (prof != null)
activePeers.put(peer, prof);
} }
locked_selectPeers(activePeers, howMany, exclude, matches, mask); locked_selectPeers(activePeers, howMany, exclude, matches, mask);
} finally { releaseReadLock(); } } finally { releaseReadLock(); }

View File

@ -14,6 +14,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.Vector; import java.util.Vector;
@ -164,7 +165,15 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
public boolean isEstablished(Hash peer) { public boolean isEstablished(Hash peer) {
return _manager.isEstablished(peer); return _manager.isEstablished(peer);
} }
/**
* @return a new set, may be modified
* @since 0.9.34
*/
public Set<Hash> getEstablished() {
return _manager.getEstablished();
}
@Override @Override
public boolean wasUnreachable(Hash peer) { public boolean wasUnreachable(Hash peer) {
return _manager.wasUnreachable(peer); return _manager.wasUnreachable(peer);

View File

@ -11,6 +11,7 @@ package net.i2p.router.transport;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.Vector; import java.util.Vector;
import net.i2p.data.Hash; import net.i2p.data.Hash;
@ -141,6 +142,12 @@ public interface Transport {
/** The unique identity of this Transport */ /** The unique identity of this Transport */
public String getStyle(); public String getStyle();
/**
* @return may or may not be modifiable; check implementation
* @since 0.9.34
*/
public Set<Hash> getEstablished();
public int countPeers(); public int countPeers();
public int countActivePeers(); public int countActivePeers();
public int countActiveSendPeers(); public int countActiveSendPeers();

View File

@ -515,6 +515,24 @@ public class TransportManager implements TransportEventListener {
return false; return false;
} }
/**
* @return a new set, may be modified
* @since 0.9.34
*/
public Set<Hash> getEstablished() {
// for efficiency. NTCP is modifiable, SSU isn't
Transport t = _transports.get("NTCP");
Set<Hash> rv;
if (t != null)
rv = t.getEstablished();
else
rv = new HashSet<Hash>(256);
t = _transports.get("SSU");
if (t != null)
rv.addAll(t.getEstablished());
return rv;
}
/** /**
* Tell the transports that we may disconnect from this peer. * Tell the transports that we may disconnect from this peer.
* This is advisory only. * This is advisory only.

View File

@ -535,6 +535,22 @@ public class NTCPTransport extends TransportImpl {
public Collection<NTCPConnection> getPeers() { public Collection<NTCPConnection> getPeers() {
return _conByIdent.values(); return _conByIdent.values();
} }
/**
* Connected peers.
*
* @return a copy, modifiable
* @since 0.9.34
*/
public Set<Hash> getEstablished() {
Set<Hash> rv = new HashSet<Hash>(_conByIdent.keySet());
for (Map.Entry<Hash, NTCPConnection> e : _conByIdent.entrySet()) {
NTCPConnection con = e.getValue();
if (!con.isEstablished() || con.isClosed())
rv.remove(e.getKey());
}
return rv;
}
/** /**
* How many peers have we talked to in the last 5 minutes? * How many peers have we talked to in the last 5 minutes?

View File

@ -1174,6 +1174,16 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
public Collection<PeerState> getPeers() { public Collection<PeerState> getPeers() {
return _peersByIdent.values(); return _peersByIdent.values();
} }
/**
* Connected peers.
*
* @return not a copy, do not modify
* @since 0.9.34
*/
public Set<Hash> getEstablished() {
return _peersByIdent.keySet();
}
/** /**
* Remove and add to peersByRemoteHost map * Remove and add to peersByRemoteHost map
@ -2638,7 +2648,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
@Override @Override
public boolean isEstablished(Hash dest) { public boolean isEstablished(Hash dest) {
return getPeerState(dest) != null; return _peersByIdent.containsKey(dest);
} }
/** /**

View File

@ -12,6 +12,7 @@ import net.i2p.data.DataHelper;
import net.i2p.data.Hash; import net.i2p.data.Hash;
import net.i2p.data.i2np.I2NPMessage; import net.i2p.data.i2np.I2NPMessage;
import net.i2p.data.router.RouterInfo; import net.i2p.data.router.RouterInfo;
import net.i2p.router.CommSystemFacade;
import net.i2p.router.CommSystemFacade.Status; import net.i2p.router.CommSystemFacade.Status;
import net.i2p.router.RouterContext; import net.i2p.router.RouterContext;
import net.i2p.router.TunnelManagerFacade; import net.i2p.router.TunnelManagerFacade;
@ -111,7 +112,10 @@ class BuildExecutor implements Runnable {
} }
private int allowed() { private int allowed() {
if (_context.commSystem().getStatus() == Status.DISCONNECTED) CommSystemFacade csf = _context.commSystem();
if (csf.getStatus() == Status.DISCONNECTED)
return 0;
if (csf.isDummy() && csf.getEstablished().size() <= 0)
return 0; return 0;
int maxKBps = _context.bandwidthLimiter().getOutboundKBytesPerSecond(); int maxKBps = _context.bandwidthLimiter().getOutboundKBytesPerSecond();
int allowed = maxKBps / 6; // Max. 1 concurrent build per 6 KB/s outbound int allowed = maxKBps / 6; // Max. 1 concurrent build per 6 KB/s outbound

View File

@ -25,7 +25,7 @@ import net.i2p.util.VersionComparator;
*/ */
abstract class BuildRequestor { abstract class BuildRequestor {
private static final List<Integer> ORDER = new ArrayList<Integer>(TunnelBuildMessage.MAX_RECORD_COUNT); private static final List<Integer> ORDER = new ArrayList<Integer>(TunnelBuildMessage.MAX_RECORD_COUNT);
private static final String MIN_VARIABLE_VERSION = "0.7.12"; //private static final String MIN_VARIABLE_VERSION = "0.7.12";
private static final boolean SEND_VARIABLE = true; private static final boolean SEND_VARIABLE = true;
private static final int SHORT_RECORDS = 4; private static final int SHORT_RECORDS = 4;
private static final List<Integer> SHORT_ORDER = new ArrayList<Integer>(SHORT_RECORDS); private static final List<Integer> SHORT_ORDER = new ArrayList<Integer>(SHORT_RECORDS);
@ -239,6 +239,9 @@ abstract class BuildRequestor {
} }
/** @since 0.7.12 */ /** @since 0.7.12 */
/****
we can assume everybody supports variable now...
keep this here for the next time we change the build protocol
private static boolean supportsVariable(RouterContext ctx, Hash h) { private static boolean supportsVariable(RouterContext ctx, Hash h) {
RouterInfo ri = ctx.netDb().lookupRouterInfoLocally(h); RouterInfo ri = ctx.netDb().lookupRouterInfoLocally(h);
if (ri == null) if (ri == null)
@ -246,6 +249,7 @@ abstract class BuildRequestor {
String v = ri.getVersion(); String v = ri.getVersion();
return VersionComparator.comp(v, MIN_VARIABLE_VERSION) >= 0; return VersionComparator.comp(v, MIN_VARIABLE_VERSION) >= 0;
} }
****/
/** /**
* If the tunnel is short enough, and everybody in the tunnel, and the * If the tunnel is short enough, and everybody in the tunnel, and the
@ -258,11 +262,15 @@ abstract class BuildRequestor {
TunnelInfo pairedTunnel, BuildExecutor exec) { TunnelInfo pairedTunnel, BuildExecutor exec) {
Log log = ctx.logManager().getLog(BuildRequestor.class); Log log = ctx.logManager().getLog(BuildRequestor.class);
long replyTunnel = 0; long replyTunnel = 0;
Hash replyRouter = null; Hash replyRouter;
boolean useVariable = SEND_VARIABLE && cfg.getLength() <= MEDIUM_RECORDS; boolean useVariable = SEND_VARIABLE && cfg.getLength() <= MEDIUM_RECORDS;
if (cfg.isInbound()) { if (cfg.isInbound()) {
//replyTunnel = 0; // as above //replyTunnel = 0; // as above
replyRouter = ctx.routerHash(); replyRouter = ctx.routerHash();
/****
we can assume everybody supports variable now...
keep this here for the next time we change the build protocol
if (useVariable) { if (useVariable) {
// check the reply OBEP and all the tunnel peers except ourselves // check the reply OBEP and all the tunnel peers except ourselves
if (!supportsVariable(ctx, pairedTunnel.getPeer(pairedTunnel.getLength() - 1))) { if (!supportsVariable(ctx, pairedTunnel.getPeer(pairedTunnel.getLength() - 1))) {
@ -276,9 +284,13 @@ abstract class BuildRequestor {
} }
} }
} }
****/
} else { } else {
replyTunnel = pairedTunnel.getReceiveTunnelId(0).getTunnelId(); replyTunnel = pairedTunnel.getReceiveTunnelId(0).getTunnelId();
replyRouter = pairedTunnel.getPeer(0); replyRouter = pairedTunnel.getPeer(0);
/****
we can assume everybody supports variable now
keep this here for the next time we change the build protocol
if (useVariable) { if (useVariable) {
// check the reply IBGW and all the tunnel peers except ourselves // check the reply IBGW and all the tunnel peers except ourselves
if (!supportsVariable(ctx, replyRouter)) { if (!supportsVariable(ctx, replyRouter)) {
@ -292,6 +304,7 @@ abstract class BuildRequestor {
} }
} }
} }
****/
} }
// populate and encrypt the message // populate and encrypt the message