forked from I2P_Developers/i2p.i2p
This fixes bugs introduced in MR !120, fixes minor issues from that MR that were not addressed, and merges in my proposed changes from that MR that were not used. - Don't create subdb for subsession and lose ref for primary subsession; this caused the primary LS to not be found when attempting to create subsession LS at startup, so subsession LS was not created until primary LS was rebuilt - Remove useless null checks - Simplify CCR.getFNDF() to simply return the subdb or null; nothing else is necessary because the null return is handled in FNDS. - Fix javadocs to correct errors and clearly state whether returns non-null or may be null. - Add KNDF.toString() for use in logging - Log tweaks
This commit is contained in:
@@ -375,7 +375,18 @@ public class RouterContext extends I2PAppContext {
|
||||
public SegmentedNetworkDatabaseFacade netDbSegmentor() { return _netDb; }
|
||||
public FloodfillNetworkDatabaseFacade netDb() { return _netDb.mainNetDB(); }
|
||||
public FloodfillNetworkDatabaseFacade multihomeNetDb() { return _netDb.multiHomeNetDB(); }
|
||||
|
||||
/**
|
||||
* Get the client netDb for the given id.
|
||||
* Will return the main netDb if
|
||||
* the dbid is null or the client db is not found.
|
||||
*
|
||||
* @param id may be null
|
||||
* @return non-null
|
||||
* @since 0.9.60
|
||||
*/
|
||||
public FloodfillNetworkDatabaseFacade clientNetDb(Hash id) { return _netDb.clientNetDB(id); }
|
||||
|
||||
/**
|
||||
* The actual driver of the router, where all jobs are enqueued and processed.
|
||||
*/
|
||||
|
||||
@@ -49,9 +49,8 @@ import net.i2p.router.JobImpl;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.crypto.TransientSessionKeyManager;
|
||||
import net.i2p.router.crypto.ratchet.RatchetSKM;
|
||||
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
|
||||
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseSegmentor;
|
||||
import net.i2p.router.crypto.ratchet.MuxedSKM;
|
||||
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
|
||||
import net.i2p.util.ConcurrentHashSet;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
@@ -160,8 +159,6 @@ class ClientConnectionRunner {
|
||||
_alreadyProcessed = new ArrayList<MessageId>();
|
||||
_acceptedPending = new ConcurrentHashSet<MessageId>();
|
||||
_messageId = new AtomicInteger(_context.random().nextInt());
|
||||
// Set up the per-destination FloodfillNetworkDatabaseFacade to prevent clients from being able to
|
||||
// update leaseSet entries in the floodfill netDb
|
||||
}
|
||||
|
||||
private static final AtomicInteger __id = new AtomicInteger();
|
||||
@@ -213,9 +210,6 @@ class ClientConnectionRunner {
|
||||
_acceptedPending.clear();
|
||||
if (_sessionKeyManager != null)
|
||||
_sessionKeyManager.shutdown();
|
||||
if (_floodfillNetworkDatabaseFacade != null)
|
||||
if (_floodfillNetworkDatabaseFacade.isClientDb())
|
||||
_floodfillNetworkDatabaseFacade.shutdown();
|
||||
if (_encryptedLSHash != null)
|
||||
_manager.unregisterEncryptedDestination(this, _encryptedLSHash);
|
||||
_manager.unregisterConnection(this);
|
||||
@@ -226,12 +220,12 @@ class ClientConnectionRunner {
|
||||
// _sessions will be empty.
|
||||
for (SessionParams sp : _sessions.values()) {
|
||||
LeaseSet ls = sp.currentLeaseSet;
|
||||
if (ls != null && getFloodfillNetworkDatabaseFacade() != null)
|
||||
getFloodfillNetworkDatabaseFacade().unpublish(ls);
|
||||
if (ls != null)
|
||||
_context.netDb().unpublish(ls);
|
||||
// unpublish encrypted LS also
|
||||
ls = sp.currentEncryptedLeaseSet;
|
||||
if (ls != null && getFloodfillNetworkDatabaseFacade() != null)
|
||||
getFloodfillNetworkDatabaseFacade().unpublish(ls);
|
||||
if (ls != null)
|
||||
_context.netDb().unpublish(ls);
|
||||
if (!sp.isPrimary)
|
||||
_context.tunnelManager().removeAlias(sp.dest);
|
||||
}
|
||||
@@ -242,6 +236,8 @@ class ClientConnectionRunner {
|
||||
sp.rerequestTimer.cancel();
|
||||
}
|
||||
}
|
||||
if (_floodfillNetworkDatabaseFacade != null)
|
||||
_floodfillNetworkDatabaseFacade.shutdown();
|
||||
synchronized (_alreadyProcessed) {
|
||||
_alreadyProcessed.clear();
|
||||
}
|
||||
@@ -467,12 +463,12 @@ class ClientConnectionRunner {
|
||||
// Tell client manger
|
||||
_manager.unregisterSession(id, sp.dest);
|
||||
LeaseSet ls = sp.currentLeaseSet;
|
||||
if (ls != null && getFloodfillNetworkDatabaseFacade() != null)
|
||||
getFloodfillNetworkDatabaseFacade().unpublish(ls);
|
||||
if (ls != null && _floodfillNetworkDatabaseFacade != null)
|
||||
_floodfillNetworkDatabaseFacade.unpublish(ls);
|
||||
// unpublish encrypted LS also
|
||||
ls = sp.currentEncryptedLeaseSet;
|
||||
if (ls != null && getFloodfillNetworkDatabaseFacade() != null)
|
||||
getFloodfillNetworkDatabaseFacade().unpublish(ls);
|
||||
if (ls != null && _floodfillNetworkDatabaseFacade != null)
|
||||
_floodfillNetworkDatabaseFacade.unpublish(ls);
|
||||
isPrimary = sp.isPrimary;
|
||||
if (isPrimary)
|
||||
_context.tunnelManager().removeTunnels(sp.dest);
|
||||
@@ -492,12 +488,12 @@ class ClientConnectionRunner {
|
||||
_log.info("Destroying remaining client subsession " + sp.sessionId);
|
||||
_manager.unregisterSession(sp.sessionId, sp.dest);
|
||||
LeaseSet ls = sp.currentLeaseSet;
|
||||
if (ls != null && getFloodfillNetworkDatabaseFacade() != null)
|
||||
getFloodfillNetworkDatabaseFacade().unpublish(ls);
|
||||
if (ls != null && _floodfillNetworkDatabaseFacade != null)
|
||||
_floodfillNetworkDatabaseFacade.unpublish(ls);
|
||||
// unpublish encrypted LS also
|
||||
ls = sp.currentEncryptedLeaseSet;
|
||||
if (ls != null && getFloodfillNetworkDatabaseFacade() != null)
|
||||
getFloodfillNetworkDatabaseFacade().unpublish(ls);
|
||||
if (ls != null && _floodfillNetworkDatabaseFacade != null)
|
||||
_floodfillNetworkDatabaseFacade.unpublish(ls);
|
||||
_context.tunnelManager().removeAlias(sp.dest);
|
||||
synchronized(this) {
|
||||
if (sp.rerequestTimer != null)
|
||||
@@ -572,18 +568,6 @@ class ClientConnectionRunner {
|
||||
public int sessionEstablished(SessionConfig config) {
|
||||
Destination dest = config.getDestination();
|
||||
Hash destHash = dest.calculateHash();
|
||||
if (destHash != null){
|
||||
if (_log.shouldLog(Log.DEBUG)) {
|
||||
_log.debug("Initializing subDb for client" + destHash);
|
||||
}
|
||||
_floodfillNetworkDatabaseFacade = new FloodfillNetworkDatabaseFacade(_context, destHash);
|
||||
_floodfillNetworkDatabaseFacade.startup();
|
||||
} else {
|
||||
if (_log.shouldLog(Log.ERROR)) {
|
||||
_log.error("Initializing subDb for unknown client" + dest, new Exception());
|
||||
}
|
||||
_floodfillNetworkDatabaseFacade = null;
|
||||
}
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("SessionEstablished called for destination " + destHash);
|
||||
if (_sessions.size() > MAX_SESSIONS)
|
||||
@@ -610,6 +594,7 @@ class ClientConnectionRunner {
|
||||
_dontSendMSM = "none".equals(opts.getProperty(I2PClient.PROP_RELIABILITY, "").toLowerCase(Locale.US));
|
||||
_dontSendMSMOnReceive = Boolean.parseBoolean(opts.getProperty(I2PClient.PROP_FAST_RECEIVE));
|
||||
}
|
||||
|
||||
// Set up the
|
||||
// per-destination session key manager to prevent rather easy correlation
|
||||
// based on the specified encryption types in the config
|
||||
@@ -661,6 +646,12 @@ class ClientConnectionRunner {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isPrimary && _floodfillNetworkDatabaseFacade == null && _context.netDbSegmentor().useSubDbs()) {
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Initializing subDb for client" + destHash);
|
||||
_floodfillNetworkDatabaseFacade = new FloodfillNetworkDatabaseFacade(_context, destHash);
|
||||
_floodfillNetworkDatabaseFacade.startup();
|
||||
}
|
||||
return _manager.destinationEstablished(this, dest);
|
||||
}
|
||||
|
||||
@@ -1172,29 +1163,15 @@ class ClientConnectionRunner {
|
||||
|
||||
/**
|
||||
* Get the FloodfillNetworkDatabaseFacade for this runner. This is the client
|
||||
* netDb if the router is configured to use subDbs, or the main netDb if the
|
||||
* router is configured to use a monolithic netDb.
|
||||
* netDb.
|
||||
*
|
||||
* If neither a client netDb or the main netDb is available, it will return null.
|
||||
* This should be impossible.
|
||||
* If you get the `getFloodfillNetworkDatabaseFacade is null for runner` warning,
|
||||
* the main netDb will be returned instead. If the main netDb is null, then null
|
||||
* will be returned.
|
||||
* If a session has not been created yet, it will return null.
|
||||
*
|
||||
* @return _floodfillNetworkDatabaseFacade
|
||||
* @return the client netdb or null if no session was created yet
|
||||
* @since 0.9.60
|
||||
*/
|
||||
public FloodfillNetworkDatabaseFacade getFloodfillNetworkDatabaseFacade() {
|
||||
if (!_context.netDbSegmentor().useSubDbs())
|
||||
return _context.netDb();
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("getFloodfillNetworkDatabaseFacade is getting the subDb for dbid: " + this.getDestHash());
|
||||
if (_floodfillNetworkDatabaseFacade == null) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("getFloodfillNetworkDatabaseFacade is null for runner");
|
||||
return _context.netDb();
|
||||
}
|
||||
return this._floodfillNetworkDatabaseFacade;
|
||||
return _floodfillNetworkDatabaseFacade;
|
||||
}
|
||||
|
||||
private class MessageDeliveryStatusUpdate extends JobImpl {
|
||||
|
||||
@@ -777,8 +777,9 @@ class ClientManager {
|
||||
* get the FloodfillNetworkDatabaseFacade associated with a particular client destination.
|
||||
* This is inside the runner, so it won't be there if the runner isn't ready.
|
||||
*
|
||||
* @param destHash destination hash associated with the client who's subDb we're looking for
|
||||
* @return may be null if it does not exist and the main netDb is not initialized
|
||||
* @param destHash destination hash associated with the client who's subDb we're looking for, may be null
|
||||
* @return will be null if desthash is null or client does not exist or its netDb is not initialized
|
||||
* @since 0.9.60
|
||||
*/
|
||||
public FloodfillNetworkDatabaseFacade getClientFloodfillNetworkDatabaseFacade(Hash destHash) {
|
||||
if (destHash != null) {
|
||||
@@ -801,15 +802,14 @@ class ClientManager {
|
||||
* get all of the FloodfillNetworkDatabaseFacades for all of the clients.
|
||||
*
|
||||
* @return non-null
|
||||
* @since 0.9.60
|
||||
*/
|
||||
public Set<FloodfillNetworkDatabaseFacade> getClientFloodfillNetworkDatabaseFacades() {
|
||||
Set<FloodfillNetworkDatabaseFacade> rv = new HashSet<FloodfillNetworkDatabaseFacade>();
|
||||
for (ClientConnectionRunner runner : _runners.values()) {
|
||||
if (runner != null){
|
||||
FloodfillNetworkDatabaseFacade fndf = runner.getFloodfillNetworkDatabaseFacade();
|
||||
if (fndf != null)
|
||||
rv.add(fndf);
|
||||
}
|
||||
FloodfillNetworkDatabaseFacade fndf = runner.getFloodfillNetworkDatabaseFacade();
|
||||
if (fndf != null)
|
||||
rv.add(fndf);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@@ -817,7 +817,8 @@ class ClientManager {
|
||||
/**
|
||||
* get all the primary hashes for all the clients and return them as a set
|
||||
*
|
||||
* @return
|
||||
* @return non-null
|
||||
* @since 0.9.60
|
||||
*/
|
||||
public Set<Hash> getPrimaryHashes() {
|
||||
Set<Hash> rv = new HashSet<Hash>();
|
||||
|
||||
@@ -268,12 +268,13 @@ public class FloodfillNetworkDatabaseSegmentor extends SegmentedNetworkDatabaseF
|
||||
}
|
||||
|
||||
/**
|
||||
* get the client netDb for the given id
|
||||
* Will return the "exploratory(default client)" netDb if
|
||||
* the dbid is null.
|
||||
* Get the client netDb for the given id.
|
||||
* Will return the main netDb if
|
||||
* the dbid is null or the client db is not found.
|
||||
*
|
||||
* @param id may be null
|
||||
* @return non-null
|
||||
* @since 0.9.60
|
||||
* @return may be null if the client netDb does not exist
|
||||
*/
|
||||
@Override
|
||||
public FloodfillNetworkDatabaseFacade clientNetDB(Hash id) {
|
||||
@@ -286,7 +287,7 @@ public class FloodfillNetworkDatabaseSegmentor extends SegmentedNetworkDatabaseF
|
||||
if (fndf != null)
|
||||
return fndf;
|
||||
}
|
||||
return mainNetDB();
|
||||
return _mainDbid;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -281,6 +281,8 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
|
||||
* Cannot be restarted.
|
||||
*/
|
||||
public synchronized void shutdown() {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("DB shutdown " + this);
|
||||
_initialized = false;
|
||||
if (!_context.commSystem().isDummy() && isMainDb() &&
|
||||
_context.router().getUptime() > ROUTER_INFO_EXPIRATION_FLOODFILL + 10*60*1000 + 60*1000) {
|
||||
@@ -376,7 +378,8 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
|
||||
}
|
||||
|
||||
public synchronized void startup() {
|
||||
_log.info("Starting up the kademlia network database");
|
||||
if (_log.shouldInfo())
|
||||
_log.info("Starting up the " + this);
|
||||
RouterInfo ri = _context.router().getRouterInfo();
|
||||
String dbDir = _context.getProperty(PROP_DB_DIR, DEFAULT_DB_DIR);
|
||||
_kb = new KBucketSet<Hash>(_context, ri.getIdentity().getHash(),
|
||||
@@ -1702,4 +1705,16 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
out.write(_kb.toString().replace("\n", "<br>\n"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.60
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
if (isMainDb())
|
||||
return "Main NetDB";
|
||||
if (isMultihomeDb())
|
||||
return "Multihome NetDB";
|
||||
return "Client NetDB " + _dbid.toBase64();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.i2p.data.TunnelId;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.TunnelInfo;
|
||||
import net.i2p.router.TunnelPoolSettings;
|
||||
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@@ -115,9 +116,14 @@ public class AliasedTunnelPool extends TunnelPool {
|
||||
|
||||
@Override
|
||||
protected LeaseSet locked_buildNewLeaseSet() {
|
||||
LeaseSet ls = _context.clientNetDb(_aliasOf.getSettings().getDestination()).lookupLeaseSetLocally(_aliasOf.getSettings().getDestination());
|
||||
if (ls == null)
|
||||
Hash primary = _aliasOf.getSettings().getDestination();
|
||||
FloodfillNetworkDatabaseFacade db = _context.clientNetDb(primary);
|
||||
LeaseSet ls = db.lookupLeaseSetLocally(primary);
|
||||
if (ls == null) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("No primary LS " + primary + " to copy for " + getSettings().getDestination() + " in db " + db);
|
||||
return null;
|
||||
}
|
||||
// copy everything so it isn't corrupted
|
||||
LeaseSet rv = new LeaseSet();
|
||||
for (int i = 0; i < ls.getLeaseCount(); i++) {
|
||||
|
||||
Reference in New Issue
Block a user