I2CP: Remove tunnels immediately on client disconnect

This commit is contained in:
zzz
2020-11-02 11:21:52 +00:00
parent fc0a78dd7b
commit 5625caebda
4 changed files with 30 additions and 1 deletions

View File

@ -148,6 +148,12 @@ public interface TunnelManagerFacade extends Service {
*/ */
public void buildTunnels(Destination client, ClientTunnelSettings settings); public void buildTunnels(Destination client, ClientTunnelSettings settings);
/**
* Must be called AFTER deregistration by the client manager.
* @since 0.9.48
*/
public void removeTunnels(Destination client);
/** /**
* Add another destination to the same tunnels. * Add another destination to the same tunnels.
* Must have same encryption key and a different signing key. * Must have same encryption key and a different signing key.

View File

@ -212,6 +212,9 @@ class ClientConnectionRunner {
_manager.unregisterConnection(this); _manager.unregisterConnection(this);
// netdb may be null in unit tests // netdb may be null in unit tests
if (_context.netDb() != null) { if (_context.netDb() != null) {
// Note that if the client sent us a destroy message,
// removeSession() was called just before this, and
// _sessions will be empty.
for (SessionParams sp : _sessions.values()) { for (SessionParams sp : _sessions.values()) {
LeaseSet ls = sp.currentLeaseSet; LeaseSet ls = sp.currentLeaseSet;
if (ls != null) if (ls != null)
@ -223,6 +226,10 @@ class ClientConnectionRunner {
if (!sp.isPrimary) if (!sp.isPrimary)
_context.tunnelManager().removeAlias(sp.dest); _context.tunnelManager().removeAlias(sp.dest);
} }
for (SessionParams sp : _sessions.values()) {
if (sp.isPrimary)
_context.tunnelManager().removeTunnels(sp.dest);
}
} }
synchronized (_alreadyProcessed) { synchronized (_alreadyProcessed) {
_alreadyProcessed.clear(); _alreadyProcessed.clear();
@ -455,7 +462,9 @@ class ClientConnectionRunner {
if (ls != null) if (ls != null)
_context.netDb().unpublish(ls); _context.netDb().unpublish(ls);
isPrimary = sp.isPrimary; isPrimary = sp.isPrimary;
if (!isPrimary) if (isPrimary)
_context.tunnelManager().removeTunnels(sp.dest);
else
_context.tunnelManager().removeAlias(sp.dest); _context.tunnelManager().removeAlias(sp.dest);
break; break;
} }
@ -475,6 +484,7 @@ class ClientConnectionRunner {
_context.netDb().unpublish(ls); _context.netDb().unpublish(ls);
_context.tunnelManager().removeAlias(sp.dest); _context.tunnelManager().removeAlias(sp.dest);
} }
_sessions.clear();
} }
} }

View File

@ -51,6 +51,7 @@ public class DummyTunnelManagerFacade implements TunnelManagerFacade {
public int getOutboundClientTunnelCount(Hash destination) { return 0; } public int getOutboundClientTunnelCount(Hash destination) { return 0; }
public long getLastParticipatingExpiration() { return -1; } public long getLastParticipatingExpiration() { return -1; }
public void buildTunnels(Destination client, ClientTunnelSettings settings) {} public void buildTunnels(Destination client, ClientTunnelSettings settings) {}
public void removeTunnels(Destination client) {}
public boolean addAlias(Destination dest, ClientTunnelSettings settings, Destination existingClient) { return false; } public boolean addAlias(Destination dest, ClientTunnelSettings settings, Destination existingClient) { return false; }
public void removeAlias(Destination dest) {} public void removeAlias(Destination dest) {}
public TunnelPoolSettings getInboundSettings() { return null; } public TunnelPoolSettings getInboundSettings() { return null; }

View File

@ -533,9 +533,21 @@ public class TunnelPoolManager implements TunnelManagerFacade {
} }
} }
/**
* Must be called AFTER deregistration by the client manager.
*
* @since 0.9.48
*/
public void removeTunnels(Destination dest) {
removeTunnels(dest.calculateHash());
}
/** /**
* This will be called twice, once by the inbound and once by the outbound pool. * This will be called twice, once by the inbound and once by the outbound pool.
* Synched with buildTunnels() above. * Synched with buildTunnels() above.
*
* Must be called AFTER deregistration by the client manager.
*
*/ */
public synchronized void removeTunnels(Hash destination) { public synchronized void removeTunnels(Hash destination) {
if (destination == null) return; if (destination == null) return;