diff --git a/router/java/src/net/i2p/router/ClientManagerFacade.java b/router/java/src/net/i2p/router/ClientManagerFacade.java index 0ce20df6a..b6c377b70 100644 --- a/router/java/src/net/i2p/router/ClientManagerFacade.java +++ b/router/java/src/net/i2p/router/ClientManagerFacade.java @@ -85,7 +85,7 @@ public abstract class ClientManagerFacade implements Service { * * @return set of Destination objects */ - public Set listClients() { return Collections.EMPTY_SET; } + public Set listClients() { return Collections.EMPTY_SET; } /** * Return the client's current config, or null if not connected diff --git a/router/java/src/net/i2p/router/client/ClientManager.java b/router/java/src/net/i2p/router/client/ClientManager.java index 5b4a4fb53..8221a0bca 100644 --- a/router/java/src/net/i2p/router/client/ClientManager.java +++ b/router/java/src/net/i2p/router/client/ClientManager.java @@ -42,8 +42,8 @@ import net.i2p.util.Log; public class ClientManager { private Log _log; private ClientListenerRunner _listener; - private final HashMap _runners; // Destination --> ClientConnectionRunner - private final Set _pendingRunners; // ClientConnectionRunner for clients w/out a Dest yet + private final HashMap _runners; // Destination --> ClientConnectionRunner + private final Set _pendingRunners; // ClientConnectionRunner for clients w/out a Dest yet private RouterContext _ctx; /** ms to wait before rechecking for inbound messages to deliver to clients */ @@ -90,21 +90,21 @@ public class ClientManager { public void shutdown() { _log.info("Shutting down the ClientManager"); _listener.stopListening(); - Set runners = new HashSet(); + Set runners = new HashSet(); synchronized (_runners) { - for (Iterator iter = _runners.values().iterator(); iter.hasNext();) { - ClientConnectionRunner runner = (ClientConnectionRunner)iter.next(); + for (Iterator iter = _runners.values().iterator(); iter.hasNext();) { + ClientConnectionRunner runner = iter.next(); runners.add(runner); } } synchronized (_pendingRunners) { - for (Iterator iter = _pendingRunners.iterator(); iter.hasNext();) { - ClientConnectionRunner runner = (ClientConnectionRunner)iter.next(); + for (Iterator iter = _pendingRunners.iterator(); iter.hasNext();) { + ClientConnectionRunner runner = iter.next(); runners.add(runner); } } - for (Iterator iter = runners.iterator(); iter.hasNext(); ) { - ClientConnectionRunner runner = (ClientConnectionRunner)iter.next(); + for (Iterator iter = runners.iterator(); iter.hasNext(); ) { + ClientConnectionRunner runner = iter.next(); runner.stopRunning(); } } @@ -131,15 +131,26 @@ public class ClientManager { } } + /** + * Add to the clients list. Check for a dup destination. + */ public void destinationEstablished(ClientConnectionRunner runner) { + Destination dest = runner.getConfig().getDestination(); if (_log.shouldLog(Log.DEBUG)) - _log.debug("DestinationEstablished called for destination " + runner.getConfig().getDestination().calculateHash().toBase64()); + _log.debug("DestinationEstablished called for destination " + dest.calculateHash().toBase64()); synchronized (_pendingRunners) { _pendingRunners.remove(runner); } + boolean fail = false; synchronized (_runners) { - _runners.put(runner.getConfig().getDestination(), runner); + fail = _runners.containsKey(dest); + if (!fail) + _runners.put(dest, runner); + } + if (fail) { + _log.log(Log.CRIT, "Client attempted to register duplicate destination " + dest.calculateHash().toBase64()); + runner.disconnectClient("Duplicate destination"); } } @@ -278,8 +289,8 @@ public class ClientManager { return true; } - public Set listClients() { - Set rv = new HashSet(); + public Set listClients() { + Set rv = new HashSet(); synchronized (_runners) { rv.addAll(_runners.keySet()); } @@ -293,7 +304,7 @@ public class ClientManager { long inLock = 0; synchronized (_runners) { inLock = _ctx.clock().now(); - rv = (ClientConnectionRunner)_runners.get(dest); + rv = _runners.get(dest); } long afterLock = _ctx.clock().now(); if (afterLock - beforeLock > 50) { @@ -331,8 +342,8 @@ public class ClientManager { if (destHash == null) return null; synchronized (_runners) { - for (Iterator iter = _runners.values().iterator(); iter.hasNext(); ) { - ClientConnectionRunner cur = (ClientConnectionRunner)iter.next(); + for (Iterator iter = _runners.values().iterator(); iter.hasNext(); ) { + ClientConnectionRunner cur = iter.next(); if (cur.getDestHash().equals(destHash)) return cur; } @@ -354,8 +365,8 @@ public class ClientManager { } } - Set getRunnerDestinations() { - Set dests = new HashSet(); + Set getRunnerDestinations() { + Set dests = new HashSet(); long beforeLock = _ctx.clock().now(); long inLock = 0; synchronized (_runners) { @@ -390,13 +401,13 @@ public class ClientManager { StringBuilder buf = new StringBuilder(8*1024); buf.append("Local destinations
"); - Map runners = null; + Map runners = null; synchronized (_runners) { runners = (Map)_runners.clone(); } - for (Iterator iter = runners.keySet().iterator(); iter.hasNext(); ) { - Destination dest = (Destination)iter.next(); - ClientConnectionRunner runner = (ClientConnectionRunner)runners.get(dest); + for (Iterator iter = runners.keySet().iterator(); iter.hasNext(); ) { + Destination dest = iter.next(); + ClientConnectionRunner runner = runners.get(dest); buf.append("* ").append(dest.calculateHash().toBase64().substring(0,6)).append("
\n"); LeaseSet ls = runner.getLeaseSet(); if (ls == null) { diff --git a/router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java b/router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java index 9e706beda..360cdb611 100644 --- a/router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java +++ b/router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java @@ -215,7 +215,7 @@ public class ClientManagerFacadeImpl extends ClientManagerFacade { * @return set of Destination objects */ @Override - public Set listClients() { + public Set listClients() { if (_manager != null) return _manager.listClients(); else