* ClientManager:

- Prevent client destination theft by rejecting duplicates
      - Java 5 cleanups
This commit is contained in:
zzz
2009-08-21 15:40:26 +00:00
parent 4d4538a346
commit faeb58f7e2
3 changed files with 35 additions and 24 deletions

View File

@ -85,7 +85,7 @@ public abstract class ClientManagerFacade implements Service {
* *
* @return set of Destination objects * @return set of Destination objects
*/ */
public Set listClients() { return Collections.EMPTY_SET; } public Set<Destination> listClients() { return Collections.EMPTY_SET; }
/** /**
* Return the client's current config, or null if not connected * Return the client's current config, or null if not connected

View File

@ -42,8 +42,8 @@ import net.i2p.util.Log;
public class ClientManager { public class ClientManager {
private Log _log; private Log _log;
private ClientListenerRunner _listener; private ClientListenerRunner _listener;
private final HashMap _runners; // Destination --> ClientConnectionRunner private final HashMap<Destination, ClientConnectionRunner> _runners; // Destination --> ClientConnectionRunner
private final Set _pendingRunners; // ClientConnectionRunner for clients w/out a Dest yet private final Set<ClientConnectionRunner> _pendingRunners; // ClientConnectionRunner for clients w/out a Dest yet
private RouterContext _ctx; private RouterContext _ctx;
/** ms to wait before rechecking for inbound messages to deliver to clients */ /** ms to wait before rechecking for inbound messages to deliver to clients */
@ -90,21 +90,21 @@ public class ClientManager {
public void shutdown() { public void shutdown() {
_log.info("Shutting down the ClientManager"); _log.info("Shutting down the ClientManager");
_listener.stopListening(); _listener.stopListening();
Set runners = new HashSet(); Set<ClientConnectionRunner> runners = new HashSet();
synchronized (_runners) { synchronized (_runners) {
for (Iterator iter = _runners.values().iterator(); iter.hasNext();) { for (Iterator<ClientConnectionRunner> iter = _runners.values().iterator(); iter.hasNext();) {
ClientConnectionRunner runner = (ClientConnectionRunner)iter.next(); ClientConnectionRunner runner = iter.next();
runners.add(runner); runners.add(runner);
} }
} }
synchronized (_pendingRunners) { synchronized (_pendingRunners) {
for (Iterator iter = _pendingRunners.iterator(); iter.hasNext();) { for (Iterator<ClientConnectionRunner> iter = _pendingRunners.iterator(); iter.hasNext();) {
ClientConnectionRunner runner = (ClientConnectionRunner)iter.next(); ClientConnectionRunner runner = iter.next();
runners.add(runner); runners.add(runner);
} }
} }
for (Iterator iter = runners.iterator(); iter.hasNext(); ) { for (Iterator<ClientConnectionRunner> iter = runners.iterator(); iter.hasNext(); ) {
ClientConnectionRunner runner = (ClientConnectionRunner)iter.next(); ClientConnectionRunner runner = iter.next();
runner.stopRunning(); runner.stopRunning();
} }
} }
@ -131,15 +131,26 @@ public class ClientManager {
} }
} }
/**
* Add to the clients list. Check for a dup destination.
*/
public void destinationEstablished(ClientConnectionRunner runner) { public void destinationEstablished(ClientConnectionRunner runner) {
Destination dest = runner.getConfig().getDestination();
if (_log.shouldLog(Log.DEBUG)) 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) { synchronized (_pendingRunners) {
_pendingRunners.remove(runner); _pendingRunners.remove(runner);
} }
boolean fail = false;
synchronized (_runners) { 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; return true;
} }
public Set listClients() { public Set<Destination> listClients() {
Set rv = new HashSet(); Set<Destination> rv = new HashSet();
synchronized (_runners) { synchronized (_runners) {
rv.addAll(_runners.keySet()); rv.addAll(_runners.keySet());
} }
@ -293,7 +304,7 @@ public class ClientManager {
long inLock = 0; long inLock = 0;
synchronized (_runners) { synchronized (_runners) {
inLock = _ctx.clock().now(); inLock = _ctx.clock().now();
rv = (ClientConnectionRunner)_runners.get(dest); rv = _runners.get(dest);
} }
long afterLock = _ctx.clock().now(); long afterLock = _ctx.clock().now();
if (afterLock - beforeLock > 50) { if (afterLock - beforeLock > 50) {
@ -331,8 +342,8 @@ public class ClientManager {
if (destHash == null) if (destHash == null)
return null; return null;
synchronized (_runners) { synchronized (_runners) {
for (Iterator iter = _runners.values().iterator(); iter.hasNext(); ) { for (Iterator<ClientConnectionRunner> iter = _runners.values().iterator(); iter.hasNext(); ) {
ClientConnectionRunner cur = (ClientConnectionRunner)iter.next(); ClientConnectionRunner cur = iter.next();
if (cur.getDestHash().equals(destHash)) if (cur.getDestHash().equals(destHash))
return cur; return cur;
} }
@ -354,8 +365,8 @@ public class ClientManager {
} }
} }
Set getRunnerDestinations() { Set<Destination> getRunnerDestinations() {
Set dests = new HashSet(); Set<Destination> dests = new HashSet();
long beforeLock = _ctx.clock().now(); long beforeLock = _ctx.clock().now();
long inLock = 0; long inLock = 0;
synchronized (_runners) { synchronized (_runners) {
@ -390,13 +401,13 @@ public class ClientManager {
StringBuilder buf = new StringBuilder(8*1024); StringBuilder buf = new StringBuilder(8*1024);
buf.append("<u><b>Local destinations</b></u><br>"); buf.append("<u><b>Local destinations</b></u><br>");
Map runners = null; Map<Destination, ClientConnectionRunner> runners = null;
synchronized (_runners) { synchronized (_runners) {
runners = (Map)_runners.clone(); runners = (Map)_runners.clone();
} }
for (Iterator iter = runners.keySet().iterator(); iter.hasNext(); ) { for (Iterator<Destination> iter = runners.keySet().iterator(); iter.hasNext(); ) {
Destination dest = (Destination)iter.next(); Destination dest = iter.next();
ClientConnectionRunner runner = (ClientConnectionRunner)runners.get(dest); ClientConnectionRunner runner = runners.get(dest);
buf.append("<b>*</b> ").append(dest.calculateHash().toBase64().substring(0,6)).append("<br>\n"); buf.append("<b>*</b> ").append(dest.calculateHash().toBase64().substring(0,6)).append("<br>\n");
LeaseSet ls = runner.getLeaseSet(); LeaseSet ls = runner.getLeaseSet();
if (ls == null) { if (ls == null) {

View File

@ -215,7 +215,7 @@ public class ClientManagerFacadeImpl extends ClientManagerFacade {
* @return set of Destination objects * @return set of Destination objects
*/ */
@Override @Override
public Set listClients() { public Set<Destination> listClients() {
if (_manager != null) if (_manager != null)
return _manager.listClients(); return _manager.listClients();
else else