NetDb: Prevent ISJ deadlock (ticket #2366)

This commit is contained in:
zzz
2019-01-04 13:48:38 +00:00
parent 4786081026
commit 74ed974145
6 changed files with 46 additions and 5 deletions

View File

@ -1,5 +1,11 @@
2019-01-04 zzz
* Build: Check cert validity
* Data: Add type byte to MetaLease (proposal 123)
* NetDb: Prevent ISJ deadlock (ticket #2366)
* Router: Reseed updates
2019-01-02 zzz 2019-01-02 zzz
* Console: Wizard styling * Console: Wizard styling (ticket #1473)
* Data: Encrypted LS2 progress (proposal 123) * Data: Encrypted LS2 progress (proposal 123)
2019-01-01 zzz 2019-01-01 zzz

View File

@ -40,6 +40,14 @@ public abstract class NetworkDatabaseFacade implements Service {
* @since 0.8.3 * @since 0.8.3
*/ */
public abstract DatabaseEntry lookupLocally(Hash key); public abstract DatabaseEntry lookupLocally(Hash key);
/**
* Not for use without validation
* @return RouterInfo, LeaseSet, or null, NOT validated
* @since 0.9.38
*/
public abstract DatabaseEntry lookupLocallyWithoutValidation(Hash key);
public abstract void lookupLeaseSet(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs); public abstract void lookupLeaseSet(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs);
/** /**

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */ /** deprecated */
public final static String ID = "Monotone"; public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION; public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 13; public final static long BUILD = 14;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = ""; public final static String EXTRA = "";

View File

@ -40,6 +40,7 @@ public class DummyNetworkDatabaseFacade extends NetworkDatabaseFacade {
} }
public DatabaseEntry lookupLocally(Hash key) { return null; } public DatabaseEntry lookupLocally(Hash key) { return null; }
public DatabaseEntry lookupLocallyWithoutValidation(Hash key) { return null; }
public void lookupLeaseSet(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs) {} public void lookupLeaseSet(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs) {}
public void lookupLeaseSet(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs, Hash fromLocalDest) {} public void lookupLeaseSet(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs, Hash fromLocalDest) {}
public LeaseSet lookupLeaseSetLocally(Hash key) { return null; } public LeaseSet lookupLeaseSetLocally(Hash key) { return null; }

View File

@ -492,9 +492,9 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
/** /**
* Not for use without validation * Not for use without validation
* @return RouterInfo, LeaseSet, or null, NOT validated * @return RouterInfo, LeaseSet, or null, NOT validated
* @since 0.9.9 * @since 0.9.9, public since 0.9.38
*/ */
DatabaseEntry lookupLocallyWithoutValidation(Hash key) { public DatabaseEntry lookupLocallyWithoutValidation(Hash key) {
if (!_initialized) if (!_initialized)
return null; return null;
return _ds.get(key); return _ds.get(key);
@ -638,6 +638,12 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
} }
} }
/**
* This will return immediately with the result or null.
* However, this may still fire off a lookup if the RI is present but expired (and will return null).
* This may result in deadlocks.
* For true local only, use lookupLocallyWithoutValidation()
*/
public RouterInfo lookupRouterInfoLocally(Hash key) { public RouterInfo lookupRouterInfoLocally(Hash key) {
if (!_initialized) return null; if (!_initialized) return null;
DatabaseEntry ds = _ds.get(key); DatabaseEntry ds = _ds.get(key);

View File

@ -4,6 +4,7 @@ import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import net.i2p.data.DatabaseEntry;
import net.i2p.data.DataHelper; import net.i2p.data.DataHelper;
import net.i2p.data.Hash; import net.i2p.data.Hash;
import net.i2p.data.router.RouterAddress; import net.i2p.data.router.RouterAddress;
@ -32,11 +33,30 @@ public class MaskedIPSet extends HashSet<String> {
* *
* As of 0.9.24, returned set will include netdb family as well. * As of 0.9.24, returned set will include netdb family as well.
* *
* This gets the peer from the netdb without validation,
* for efficiency and to avoid deadlocks.
* Peers are presumed to be validated elsewhere.
*
* @param peer non-null * @param peer non-null
* @param mask is 1-4 (number of bytes to match) * @param mask is 1-4 (number of bytes to match)
*/ */
public MaskedIPSet(RouterContext ctx, Hash peer, int mask) { public MaskedIPSet(RouterContext ctx, Hash peer, int mask) {
this(ctx, peer, ctx.netDb().lookupRouterInfoLocally(peer), mask); this(ctx, peer, lookupRILocally(ctx, peer), mask);
}
/**
* This gets the peer from the netdb without validation,
* for efficiency and to avoid deadlocks.
*
* @since 0.9.38
*/
private static RouterInfo lookupRILocally(RouterContext ctx, Hash peer) {
DatabaseEntry ds = ctx.netDb().lookupLocallyWithoutValidation(peer);
if (ds != null) {
if (ds.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO)
return (RouterInfo) ds;
}
return null;
} }
/** /**