Router: LS2 handling for proposal 123

This commit is contained in:
zzz
2018-11-13 18:00:05 +00:00
parent ddfc7c05ef
commit b695242daf
12 changed files with 81 additions and 38 deletions

View File

@@ -38,7 +38,6 @@ public class Lease2 extends Lease {
return DataHelper.eq(_end, lse.getEndDate())
&& DataHelper.eq(_tunnelId, lse.getTunnelId())
&& DataHelper.eq(_gateway, lse.getGateway());
}
@Override

View File

@@ -1,5 +1,12 @@
2018-11-13 zzz
* Console:
- New M-Lab NDT subsystem
- Setup wizard (WIP)
* Router: LS2 handling for proposal 123
2018-10-13 zzz
* Build: Add javac.classpath to junit.compileTest targets (ticket #2333)
* Data: Add LS2 classes for proposal 123
2018-10-11 zzz
* Console: Remove static Server reference

View File

@@ -18,6 +18,7 @@ import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.data.LeaseSet;
import net.i2p.data.LeaseSet2;
import net.i2p.data.router.RouterInfo;
import net.i2p.data.TunnelId;
@@ -113,7 +114,8 @@ public class DatabaseStoreMessage extends FastI2NPMessageImpl {
curIndex += Hash.HASH_LENGTH;
// as of 0.9.18, ignore other 7 bits of the type byte, in preparation for future options
int dbType = data[curIndex] & 0x01;
// as of 0.9.38, ignore other 4 bits of the type byte, in preparation for future options
int dbType = data[curIndex] & 0x0f;
curIndex++;
_replyToken = DataHelper.fromLong(data, curIndex, 4);
@@ -141,7 +143,16 @@ public class DatabaseStoreMessage extends FastI2NPMessageImpl {
} catch (IOException ioe) {
throw new I2NPMessageException("Error reading the leaseSet", ioe);
}
} else { // dbType == DatabaseEntry.KEY_TYPE_ROUTERINFO
} else if (dbType == DatabaseEntry.KEY_TYPE_LS2) {
_dbEntry = new LeaseSet2();
try {
_dbEntry.readBytes(new ByteArrayInputStream(data, curIndex, data.length-curIndex));
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Error reading the leaseSet", dfe);
} catch (IOException ioe) {
throw new I2NPMessageException("Error reading the leaseSet", ioe);
}
} else if ((dbType & 0x01) == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
_dbEntry = new RouterInfo();
int compressedSize = (int)DataHelper.fromLong(data, curIndex, 2);
curIndex += 2;
@@ -160,8 +171,12 @@ public class DatabaseStoreMessage extends FastI2NPMessageImpl {
} catch (DataFormatException dfe) {
throw new I2NPMessageException("Error reading the routerInfo", dfe);
} catch (IOException ioe) {
//net.i2p.util.Log log = new net.i2p.util.Log(DatabaseStoreMessage.class);
//log.error("Corrupt compressed routerInfo size = " + compressedSize + " key " + _key, ioe);
throw new I2NPMessageException("Corrupt compressed routerInfo size = " + compressedSize, ioe);
}
} else {
throw new I2NPMessageException("Unknown type " + dbType);
}
//if (!key.equals(_dbEntry.getHash()))
// throw new I2NPMessageException("Hash mismatch in DSM");
@@ -269,7 +284,11 @@ public class DatabaseStoreMessage extends FastI2NPMessageImpl {
buf.append("\n\tReply tunnel: ").append(_replyTunnel);
buf.append("\n\tReply gateway: ").append(_replyGateway);
}
buf.append("\n\tKey: ").append(getKey());
buf.append("\n\tKey: ");
if (_dbEntry.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO)
buf.append(getKey());
else
buf.append(getKey().toBase32());
buf.append("\n\tEntry: ").append(_dbEntry);
buf.append(']');
return buf.toString();

View File

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

View File

@@ -94,7 +94,8 @@ public class HandleDatabaseLookupMessageJob extends JobImpl {
DatabaseLookupMessage.Type lookupType = _message.getSearchType();
// only lookup once, then cast to correct type
DatabaseEntry dbe = getContext().netDb().lookupLocally(_message.getSearchKey());
if (dbe != null && dbe.getType() == DatabaseEntry.KEY_TYPE_LEASESET &&
int type = dbe != null ? dbe.getType() : -1;
if ((type == DatabaseEntry.KEY_TYPE_LEASESET || type == DatabaseEntry.KEY_TYPE_LS2) &&
(lookupType == DatabaseLookupMessage.Type.ANY || lookupType == DatabaseLookupMessage.Type.LS)) {
LeaseSet ls = (LeaseSet) dbe;
// We have to be very careful here to decide whether or not to send out the leaseSet,
@@ -158,7 +159,7 @@ public class HandleDatabaseLookupMessageJob extends JobImpl {
Set<Hash> routerHashSet = getNearestRouters(lookupType);
sendClosest(_message.getSearchKey(), routerHashSet, fromKey, _message.getReplyTunnel());
}
} else if (dbe != null && dbe.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO &&
} else if (type == DatabaseEntry.KEY_TYPE_ROUTERINFO &&
lookupType != DatabaseLookupMessage.Type.LS) {
RouterInfo info = (RouterInfo) dbe;
if (info.isCurrent(EXPIRE_DELAY)) {
@@ -259,7 +260,8 @@ public class HandleDatabaseLookupMessageJob extends JobImpl {
_log.debug("Sending data matching key " + key + " to peer " + toPeer
+ " tunnel " + replyTunnel);
DatabaseStoreMessage msg = new DatabaseStoreMessage(getContext());
if (data.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
int type = data.getType();
if (type == DatabaseEntry.KEY_TYPE_LEASESET || type == DatabaseEntry.KEY_TYPE_LS2) {
getContext().statManager().addRateData("netDb.lookupsMatchedLeaseSet", 1);
}
msg.setEntry(data);

View File

@@ -61,7 +61,9 @@ class ExpireLeasesJob extends JobImpl {
Set<Hash> toExpire = new HashSet<Hash>(128);
for (Map.Entry<Hash, DatabaseEntry> entry : _facade.getDataStore().getMapEntries()) {
DatabaseEntry obj = entry.getValue();
if (obj.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
int type = obj.getType();
if (type == DatabaseEntry.KEY_TYPE_LEASESET ||
type == DatabaseEntry.KEY_TYPE_LS2) {
LeaseSet ls = (LeaseSet)obj;
if (!ls.isCurrent(Router.CLOCK_FUDGE_FACTOR))
toExpire.add(entry.getKey());

View File

@@ -52,15 +52,22 @@ class FloodOnlyLookupMatchJob extends JobImpl implements ReplyJob {
// We do it here first to make sure it is in the DB before
// runJob() and search.success() is called???
// Should we just pass the DataStructure directly back to somebody?
if (dsm.getEntry().getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
DatabaseEntry entry = dsm.getEntry();
int type = entry.getType();
if (type == DatabaseEntry.KEY_TYPE_LEASESET ||
type == DatabaseEntry.KEY_TYPE_LS2) {
// Since HFDSMJ wants to setReceivedAsPublished(), we have to
// set a flag saying this was really the result of a query,
// so don't do that.
LeaseSet ls = (LeaseSet) dsm.getEntry();
ls.setReceivedAsReply();
getContext().netDb().store(dsm.getKey(), ls);
} else {
} else if (type == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
getContext().netDb().store(dsm.getKey(), (RouterInfo) dsm.getEntry());
} else {
if (_log.shouldWarn())
_log.warn(_search.getJobId() + ": got a DSM of unknown type " + type
+ " for " + dsm.getKey().toBase64());
}
} catch (UnsupportedCryptoException uce) {
_search.failed();

View File

@@ -69,7 +69,9 @@ class HandleFloodfillDatabaseStoreMessageJob extends JobImpl {
RouterInfo prevNetDb = null;
Hash key = _message.getKey();
DatabaseEntry entry = _message.getEntry();
if (entry.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
int type = entry.getType();
if (type == DatabaseEntry.KEY_TYPE_LEASESET ||
type == DatabaseEntry.KEY_TYPE_LS2) {
getContext().statManager().addRateData("netDb.storeLeaseSetHandled", 1);
if (_log.shouldLog(Log.INFO))
_log.info("Handling dbStore of leaseset " + _message);
@@ -135,7 +137,7 @@ class HandleFloodfillDatabaseStoreMessageJob extends JobImpl {
} catch (IllegalArgumentException iae) {
invalidMessage = iae.getMessage();
}
} else if (entry.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
} else if (type == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
RouterInfo ri = (RouterInfo) entry;
getContext().statManager().addRateData("netDb.storeRouterInfoHandled", 1);
if (_log.shouldLog(Log.INFO))
@@ -181,7 +183,7 @@ class HandleFloodfillDatabaseStoreMessageJob extends JobImpl {
}
} else {
if (_log.shouldLog(Log.ERROR))
_log.error("Invalid DatabaseStoreMessage data type - " + entry.getType()
_log.error("Invalid DatabaseStoreMessage data type - " + type
+ ": " + _message);
// don't ack or flood
return;

View File

@@ -438,7 +438,8 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
//return _ds.countLeaseSets();
int rv = 0;
for (DatabaseEntry ds : _ds.getEntries()) {
if (ds.getType() == DatabaseEntry.KEY_TYPE_LEASESET &&
int type = ds.getType();
if ((type == DatabaseEntry.KEY_TYPE_LEASESET || type == DatabaseEntry.KEY_TYPE_LS2) &&
((LeaseSet)ds).getReceivedAsPublished())
rv++;
}
@@ -466,13 +467,14 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
DatabaseEntry rv = _ds.get(key);
if (rv == null)
return null;
if (rv.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
int type = rv.getType();
if (type == DatabaseEntry.KEY_TYPE_LEASESET || type == DatabaseEntry.KEY_TYPE_LS2) {
LeaseSet ls = (LeaseSet)rv;
if (ls.isCurrent(Router.CLOCK_FUDGE_FACTOR))
return rv;
else
fail(key);
} else if (rv.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
} else if (type == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
try {
if (validate((RouterInfo)rv) == null)
return rv;
@@ -551,7 +553,8 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
if (!_initialized) return null;
DatabaseEntry ds = _ds.get(key);
if (ds != null) {
if (ds.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
int type = ds.getType();
if (type == DatabaseEntry.KEY_TYPE_LEASESET || type == DatabaseEntry.KEY_TYPE_LS2) {
LeaseSet ls = (LeaseSet)ds;
if (ls.isCurrent(Router.CLOCK_FUDGE_FACTOR)) {
return ls;
@@ -604,7 +607,8 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
if (!_initialized) return null;
DatabaseEntry ds = _ds.get(key);
if (ds != null) {
if (ds.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
int type = ds.getType();
if (type == DatabaseEntry.KEY_TYPE_LEASESET || type == DatabaseEntry.KEY_TYPE_LS2) {
LeaseSet ls = (LeaseSet)ds;
return ls.getDestination();
}
@@ -1077,7 +1081,8 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
*/
private void processStoreFailure(Hash h, DatabaseEntry entry) throws UnsupportedCryptoException {
if (entry.getHash().equals(h)) {
if (entry.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
int etype = entry.getType();
if (etype == DatabaseEntry.KEY_TYPE_LEASESET || etype == DatabaseEntry.KEY_TYPE_LS2) {
LeaseSet ls = (LeaseSet) entry;
Destination d = ls.getDestination();
Certificate c = d.getCertificate();
@@ -1094,7 +1099,7 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
}
} catch (DataFormatException dfe) {}
}
} else if (entry.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
} else if (etype == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
RouterInfo ri = (RouterInfo) entry;
RouterIdentity id = ri.getIdentity();
Certificate c = id.getCertificate();
@@ -1237,7 +1242,8 @@ public abstract class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacad
if (!_initialized) return null;
Set<LeaseSet> leases = new HashSet<LeaseSet>();
for (DatabaseEntry o : getDataStore().getEntries()) {
if (o.getType() == DatabaseEntry.KEY_TYPE_LEASESET)
int type = o.getType();
if (type == DatabaseEntry.KEY_TYPE_LEASESET || type == DatabaseEntry.KEY_TYPE_LS2)
leases.add((LeaseSet)o);
}
return leases;

View File

@@ -294,9 +294,7 @@ public class PersistentDataStore extends TransientDataStore {
try {
String filename = null;
if (data.getType() == DatabaseEntry.KEY_TYPE_LEASESET)
filename = getLeaseSetName(key);
else if (data.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO)
if (data.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO)
filename = getRouterInfoName(key);
else
throw new IOException("We don't know how to write objects of type " + data.getClass().getName());
@@ -624,18 +622,12 @@ public class PersistentDataStore extends TransientDataStore {
}
}
private final static String LEASESET_PREFIX = "leaseSet-";
private final static String LEASESET_SUFFIX = ".dat";
private final static String ROUTERINFO_PREFIX = "routerInfo-";
private final static String ROUTERINFO_SUFFIX = ".dat";
/** @since 0.9.34 */
public static final FileFilter RI_FILTER = new FileSuffixFilter(ROUTERINFO_PREFIX, ROUTERINFO_SUFFIX);
private static String getLeaseSetName(Hash hash) {
return LEASESET_PREFIX + hash.toBase64() + LEASESET_SUFFIX;
}
private String getRouterInfoName(Hash hash) {
String b64 = hash.toBase64();
if (_flat)

View File

@@ -78,7 +78,8 @@ abstract class StoreJob extends JobImpl {
_timeoutMs = timeoutMs;
_expiration = context.clock().now() + timeoutMs;
_peerSelector = facade.getPeerSelector();
if (data.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
int type = data.getType();
if (type == DatabaseEntry.KEY_TYPE_LEASESET || type == DatabaseEntry.KEY_TYPE_LS2) {
_connectChecker = null;
_connectMask = 0;
} else {
@@ -308,10 +309,11 @@ abstract class StoreJob extends JobImpl {
return;
}
DatabaseStoreMessage msg = new DatabaseStoreMessage(getContext());
if (_state.getData().getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
int type = _state.getData().getType();
if (type == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
if (responseTime > MAX_DIRECT_EXPIRATION)
responseTime = MAX_DIRECT_EXPIRATION;
} else if (_state.getData().getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
} else if (type == DatabaseEntry.KEY_TYPE_LEASESET || type == DatabaseEntry.KEY_TYPE_LS2) {
} else {
throw new IllegalArgumentException("Storing an unknown data type! " + _state.getData());
}
@@ -338,7 +340,8 @@ abstract class StoreJob extends JobImpl {
*
*/
private void sendStore(DatabaseStoreMessage msg, RouterInfo peer, long expiration) {
if (msg.getEntry().getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
int type = msg.getEntry().getType();
if (type == DatabaseEntry.KEY_TYPE_LEASESET || type == DatabaseEntry.KEY_TYPE_LS2) {
getContext().statManager().addRateData("netDb.storeLeaseSetSent", 1);
// if it is an encrypted leaseset...
if (getContext().keyRing().get(msg.getKey()) != null)

View File

@@ -99,7 +99,9 @@ class TransientDataStore implements DataStore {
public int countLeaseSets() {
int count = 0;
for (DatabaseEntry d : _data.values()) {
if (d.getType() == DatabaseEntry.KEY_TYPE_LEASESET)
int type = d.getType();
if (type == DatabaseEntry.KEY_TYPE_LEASESET ||
type == DatabaseEntry.KEY_TYPE_LS2)
count++;
}
return count;
@@ -122,7 +124,8 @@ class TransientDataStore implements DataStore {
_log.debug("Storing key " + key);
DatabaseEntry old = _data.putIfAbsent(key, data);
boolean rv = false;
if (data.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
int type = data.getType();
if (type == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
// Don't do this here so we don't reset it at router startup;
// the StoreMessageJob calls this
//_context.profileManager().heardAbout(key);
@@ -148,7 +151,8 @@ class TransientDataStore implements DataStore {
_log.info("New router for " + key + ": published on " + new Date(ri.getPublished()));
rv = true;
}
} else if (data.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
} else if (type == DatabaseEntry.KEY_TYPE_LEASESET ||
type == DatabaseEntry.KEY_TYPE_LS2) {
LeaseSet ls = (LeaseSet)data;
if (old != null) {
LeaseSet ols = (LeaseSet)old;