forked from I2P_Developers/i2p.i2p
I2NP: Implement DatabaseLookupMessage search type field,
to replace all-zeros hash, and ease implementation for separate LS and RI databases, as documented in i2np spec.
This commit is contained in:
@ -1,3 +1,6 @@
|
|||||||
|
2014-10-14 zzz
|
||||||
|
* I2NP: Implement DatabaseLookupMessage search type field
|
||||||
|
|
||||||
2014-10-13 zzz
|
2014-10-13 zzz
|
||||||
* i2ptunnel: Set default sig type to ECDSA-P256 for client types
|
* i2ptunnel: Set default sig type to ECDSA-P256 for client types
|
||||||
Standard, IRC, and Socks IRC, if non-shared.
|
Standard, IRC, and Socks IRC, if non-shared.
|
||||||
|
@ -40,6 +40,7 @@ public class DatabaseLookupMessage extends FastI2NPMessageImpl {
|
|||||||
private List<Hash> _dontIncludePeers;
|
private List<Hash> _dontIncludePeers;
|
||||||
private SessionKey _replyKey;
|
private SessionKey _replyKey;
|
||||||
private SessionTag _replyTag;
|
private SessionTag _replyTag;
|
||||||
|
private Type _type;
|
||||||
|
|
||||||
//private static volatile long _currentLookupPeriod = 0;
|
//private static volatile long _currentLookupPeriod = 0;
|
||||||
//private static volatile int _currentLookupCount = 0;
|
//private static volatile int _currentLookupCount = 0;
|
||||||
@ -52,7 +53,26 @@ public class DatabaseLookupMessage extends FastI2NPMessageImpl {
|
|||||||
private static final int MAX_NUM_PEERS = 512;
|
private static final int MAX_NUM_PEERS = 512;
|
||||||
|
|
||||||
private static final byte FLAG_TUNNEL = 0x01;
|
private static final byte FLAG_TUNNEL = 0x01;
|
||||||
|
// any flags below here will confuse routers 0.9.5 or lower
|
||||||
private static final byte FLAG_ENCRYPT = 0x02;
|
private static final byte FLAG_ENCRYPT = 0x02;
|
||||||
|
private static final byte FLAG_TYPE_MASK = 0x0c;
|
||||||
|
private static final byte FLAG_TYPE_ANY = 0;
|
||||||
|
private static final byte FLAG_TYPE_LS = 0x04;
|
||||||
|
private static final byte FLAG_TYPE_RI = 0x08;
|
||||||
|
private static final byte FLAG_TYPE_EXPL = 0x0c;
|
||||||
|
|
||||||
|
/** @since 0.9.16 */
|
||||||
|
public enum Type {
|
||||||
|
/** default - LS or RI */
|
||||||
|
ANY,
|
||||||
|
/** lease set only */
|
||||||
|
LS,
|
||||||
|
/** router info only */
|
||||||
|
RI,
|
||||||
|
/** exploratory - return closest non-floodfill router infos */
|
||||||
|
EXPL
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It's not supported until 0.9.7, but as of
|
* It's not supported until 0.9.7, but as of
|
||||||
@ -86,6 +106,7 @@ public class DatabaseLookupMessage extends FastI2NPMessageImpl {
|
|||||||
// + " messages so far)", new Exception("Flood cause"));
|
// + " messages so far)", new Exception("Flood cause"));
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
_type = Type.ANY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -130,6 +151,30 @@ public class DatabaseLookupMessage extends FastI2NPMessageImpl {
|
|||||||
_key = key;
|
_key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the type of data being searched for.
|
||||||
|
* Default ANY.
|
||||||
|
*
|
||||||
|
* @return non-null
|
||||||
|
* @since 0.9.16
|
||||||
|
*/
|
||||||
|
public Type getSearchType() { return _type; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the type of data being searched for.
|
||||||
|
* Default ANY.
|
||||||
|
* Must be ANY for queried routers 0.9.5 or lower, but there are few if
|
||||||
|
* any floodfills that old left, so not even worth checking.
|
||||||
|
*
|
||||||
|
* @param type non-null
|
||||||
|
* @since 0.9.16
|
||||||
|
*/
|
||||||
|
public void setSearchType(Type type) {
|
||||||
|
if (type == null)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains the router who requested this lookup
|
* Contains the router who requested this lookup
|
||||||
*
|
*
|
||||||
@ -285,6 +330,21 @@ public class DatabaseLookupMessage extends FastI2NPMessageImpl {
|
|||||||
// TODO store the whole flag byte
|
// TODO store the whole flag byte
|
||||||
boolean tunnelSpecified = (data[curIndex] & FLAG_TUNNEL) != 0;
|
boolean tunnelSpecified = (data[curIndex] & FLAG_TUNNEL) != 0;
|
||||||
boolean replyKeySpecified = (data[curIndex] & FLAG_ENCRYPT) != 0;
|
boolean replyKeySpecified = (data[curIndex] & FLAG_ENCRYPT) != 0;
|
||||||
|
switch (data[curIndex] & FLAG_TYPE_MASK) {
|
||||||
|
case FLAG_TYPE_LS:
|
||||||
|
_type = Type.LS;
|
||||||
|
break;
|
||||||
|
case FLAG_TYPE_RI:
|
||||||
|
_type = Type.RI;
|
||||||
|
break;
|
||||||
|
case FLAG_TYPE_EXPL:
|
||||||
|
_type = Type.EXPL;
|
||||||
|
break;
|
||||||
|
case FLAG_TYPE_ANY:
|
||||||
|
default:
|
||||||
|
_type = Type.ANY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
curIndex++;
|
curIndex++;
|
||||||
|
|
||||||
if (tunnelSpecified) {
|
if (tunnelSpecified) {
|
||||||
@ -348,6 +408,21 @@ public class DatabaseLookupMessage extends FastI2NPMessageImpl {
|
|||||||
byte flag = FLAG_TUNNEL;
|
byte flag = FLAG_TUNNEL;
|
||||||
if (_replyKey != null)
|
if (_replyKey != null)
|
||||||
flag |= FLAG_ENCRYPT;
|
flag |= FLAG_ENCRYPT;
|
||||||
|
switch (_type) {
|
||||||
|
case LS:
|
||||||
|
flag |= FLAG_TYPE_LS;
|
||||||
|
break;
|
||||||
|
case RI:
|
||||||
|
flag |= FLAG_TYPE_RI;
|
||||||
|
break;
|
||||||
|
case EXPL:
|
||||||
|
flag |= FLAG_TYPE_EXPL;
|
||||||
|
break;
|
||||||
|
case ANY:
|
||||||
|
default:
|
||||||
|
// flag is 0
|
||||||
|
break;
|
||||||
|
}
|
||||||
out[curIndex++] = flag;
|
out[curIndex++] = flag;
|
||||||
byte id[] = DataHelper.toLong(4, _replyTunnel.getTunnelId());
|
byte id[] = DataHelper.toLong(4, _replyTunnel.getTunnelId());
|
||||||
System.arraycopy(id, 0, out, curIndex, 4);
|
System.arraycopy(id, 0, out, curIndex, 4);
|
||||||
@ -410,6 +485,7 @@ public class DatabaseLookupMessage extends FastI2NPMessageImpl {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder buf = new StringBuilder(256);
|
StringBuilder buf = new StringBuilder(256);
|
||||||
buf.append("[DatabaseLookupMessage: ");
|
buf.append("[DatabaseLookupMessage: ");
|
||||||
|
buf.append("\n\tSearch Type: ").append(_type);
|
||||||
buf.append("\n\tSearch Key: ").append(_key);
|
buf.append("\n\tSearch Key: ").append(_key);
|
||||||
if (_replyKey != null)
|
if (_replyKey != null)
|
||||||
buf.append("\n\tReply GW: ");
|
buf.append("\n\tReply GW: ");
|
||||||
|
@ -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 = 9;
|
public final static long BUILD = 10;
|
||||||
|
|
||||||
/** for example "-test" */
|
/** for example "-test" */
|
||||||
public final static String EXTRA = "";
|
public final static String EXTRA = "";
|
||||||
|
@ -9,6 +9,7 @@ package net.i2p.router.networkdb;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.i2p.data.DatabaseEntry;
|
import net.i2p.data.DatabaseEntry;
|
||||||
@ -82,9 +83,11 @@ public class HandleDatabaseLookupMessageJob extends JobImpl {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DatabaseLookupMessage.Type lookupType = _message.getSearchType();
|
||||||
// only lookup once, then cast to correct type
|
// only lookup once, then cast to correct type
|
||||||
DatabaseEntry dbe = getContext().netDb().lookupLocally(_message.getSearchKey());
|
DatabaseEntry dbe = getContext().netDb().lookupLocally(_message.getSearchKey());
|
||||||
if (dbe != null && dbe.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
|
if (dbe != null && dbe.getType() == DatabaseEntry.KEY_TYPE_LEASESET &&
|
||||||
|
(lookupType == DatabaseLookupMessage.Type.ANY || lookupType == DatabaseLookupMessage.Type.LS)) {
|
||||||
LeaseSet ls = (LeaseSet) dbe;
|
LeaseSet ls = (LeaseSet) dbe;
|
||||||
// We have to be very careful here to decide whether or not to send out the leaseSet,
|
// We have to be very careful here to decide whether or not to send out the leaseSet,
|
||||||
// to avoid anonymity vulnerabilities.
|
// to avoid anonymity vulnerabilities.
|
||||||
@ -131,7 +134,7 @@ public class HandleDatabaseLookupMessageJob extends JobImpl {
|
|||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("We have local LS " + _message.getSearchKey() + ", NOT answering query, out of our keyspace");
|
_log.info("We have local LS " + _message.getSearchKey() + ", NOT answering query, out of our keyspace");
|
||||||
getContext().statManager().addRateData("netDb.lookupsMatchedLocalNotClosest", 1);
|
getContext().statManager().addRateData("netDb.lookupsMatchedLocalNotClosest", 1);
|
||||||
Set<Hash> routerHashSet = getNearestRouters();
|
Set<Hash> routerHashSet = getNearestRouters(lookupType);
|
||||||
sendClosest(_message.getSearchKey(), routerHashSet, fromKey, _message.getReplyTunnel());
|
sendClosest(_message.getSearchKey(), routerHashSet, fromKey, _message.getReplyTunnel());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -144,10 +147,11 @@ public class HandleDatabaseLookupMessageJob extends JobImpl {
|
|||||||
", NOT answering query - local? " + isLocal + " shouldPublish? " + shouldPublishLocal +
|
", NOT answering query - local? " + isLocal + " shouldPublish? " + shouldPublishLocal +
|
||||||
" RAP? " + ls.getReceivedAsPublished() + " RAR? " + ls.getReceivedAsReply());
|
" RAP? " + ls.getReceivedAsPublished() + " RAR? " + ls.getReceivedAsReply());
|
||||||
getContext().statManager().addRateData("netDb.lookupsMatchedRemoteNotClosest", 1);
|
getContext().statManager().addRateData("netDb.lookupsMatchedRemoteNotClosest", 1);
|
||||||
Set<Hash> routerHashSet = getNearestRouters();
|
Set<Hash> routerHashSet = getNearestRouters(lookupType);
|
||||||
sendClosest(_message.getSearchKey(), routerHashSet, fromKey, _message.getReplyTunnel());
|
sendClosest(_message.getSearchKey(), routerHashSet, fromKey, _message.getReplyTunnel());
|
||||||
}
|
}
|
||||||
} else if (dbe != null && dbe.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
|
} else if (dbe != null && dbe.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO &&
|
||||||
|
lookupType != DatabaseLookupMessage.Type.LS) {
|
||||||
RouterInfo info = (RouterInfo) dbe;
|
RouterInfo info = (RouterInfo) dbe;
|
||||||
if (info.isCurrent(EXPIRE_DELAY)) {
|
if (info.isCurrent(EXPIRE_DELAY)) {
|
||||||
if ( (info.getIdentity().isHidden()) || (isUnreachable(info) && !publishUnreachable()) ) {
|
if ( (info.getIdentity().isHidden()) || (isUnreachable(info) && !publishUnreachable()) ) {
|
||||||
@ -172,7 +176,7 @@ public class HandleDatabaseLookupMessageJob extends JobImpl {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// expired locally - return closest peer hashes
|
// expired locally - return closest peer hashes
|
||||||
Set<Hash> routerHashSet = getNearestRouters();
|
Set<Hash> routerHashSet = getNearestRouters(lookupType);
|
||||||
|
|
||||||
// ERR: see above
|
// ERR: see above
|
||||||
// // Remove hidden nodes from set..
|
// // Remove hidden nodes from set..
|
||||||
@ -190,7 +194,7 @@ public class HandleDatabaseLookupMessageJob extends JobImpl {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// not found locally - return closest peer hashes
|
// not found locally - return closest peer hashes
|
||||||
Set<Hash> routerHashSet = getNearestRouters();
|
Set<Hash> routerHashSet = getNearestRouters(lookupType);
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("We do not have key " + _message.getSearchKey() +
|
_log.debug("We do not have key " + _message.getSearchKey() +
|
||||||
" locally. sending back " + routerHashSet.size() + " peers to " + fromKey);
|
" locally. sending back " + routerHashSet.size() + " peers to " + fromKey);
|
||||||
@ -204,13 +208,23 @@ public class HandleDatabaseLookupMessageJob extends JobImpl {
|
|||||||
* Will not include us.
|
* Will not include us.
|
||||||
* Side effect - adds us to the message's dontInclude set.
|
* Side effect - adds us to the message's dontInclude set.
|
||||||
*/
|
*/
|
||||||
private Set<Hash> getNearestRouters() {
|
private Set<Hash> getNearestRouters(DatabaseLookupMessage.Type lookupType) {
|
||||||
|
// convert the new EXPL type flag to the old-style FAKE_HASH
|
||||||
|
// to pass to findNearestRouters()
|
||||||
Set<Hash> dontInclude = _message.getDontIncludePeers();
|
Set<Hash> dontInclude = _message.getDontIncludePeers();
|
||||||
Hash us = getContext().routerHash();
|
Hash us = getContext().routerHash();
|
||||||
if (dontInclude == null)
|
if (dontInclude == null && lookupType == DatabaseLookupMessage.Type.EXPL) {
|
||||||
dontInclude = Collections.singleton(us);
|
dontInclude = new HashSet<Hash>(2);
|
||||||
else
|
|
||||||
dontInclude.add(us);
|
dontInclude.add(us);
|
||||||
|
dontInclude.add(Hash.FAKE_HASH);
|
||||||
|
} else if (dontInclude == null) {
|
||||||
|
dontInclude = Collections.singleton(us);
|
||||||
|
} else if (lookupType == DatabaseLookupMessage.Type.EXPL) {
|
||||||
|
dontInclude.add(us);
|
||||||
|
dontInclude.add(Hash.FAKE_HASH);
|
||||||
|
} else {
|
||||||
|
dontInclude.add(us);
|
||||||
|
}
|
||||||
// Honor flag to exclude all floodfills
|
// Honor flag to exclude all floodfills
|
||||||
//if (dontInclude.contains(Hash.FAKE_HASH)) {
|
//if (dontInclude.contains(Hash.FAKE_HASH)) {
|
||||||
// This is handled in FloodfillPeerSelector
|
// This is handled in FloodfillPeerSelector
|
||||||
|
@ -99,6 +99,8 @@ class ExploreJob extends SearchJob {
|
|||||||
if (dontIncludePeers.add(Hash.FAKE_HASH))
|
if (dontIncludePeers.add(Hash.FAKE_HASH))
|
||||||
available--;
|
available--;
|
||||||
}
|
}
|
||||||
|
// supported as of 0.9.16. TODO remove fake hash above
|
||||||
|
msg.setSearchType(DatabaseLookupMessage.Type.EXPL);
|
||||||
|
|
||||||
KBucketSet<Hash> ks = _facade.getKBuckets();
|
KBucketSet<Hash> ks = _facade.getKBuckets();
|
||||||
Hash rkey = getContext().routingKeyGenerator().getRoutingKey(getState().getTarget());
|
Hash rkey = getContext().routingKeyGenerator().getRoutingKey(getState().getTarget());
|
||||||
|
@ -215,6 +215,7 @@ class FloodfillVerifyStoreJob extends JobImpl {
|
|||||||
m.setReplyTunnel(replyTunnelInfo.getReceiveTunnelId(0));
|
m.setReplyTunnel(replyTunnelInfo.getReceiveTunnelId(0));
|
||||||
m.setFrom(replyTunnelInfo.getPeer(0));
|
m.setFrom(replyTunnelInfo.getPeer(0));
|
||||||
m.setSearchKey(_key);
|
m.setSearchKey(_key);
|
||||||
|
m.setSearchType(_isRouterInfo ? DatabaseLookupMessage.Type.RI : DatabaseLookupMessage.Type.LS);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,6 +307,7 @@ class IterativeSearchJob extends FloodSearchJob {
|
|||||||
dlm.setMessageExpiration(getContext().clock().now() + SINGLE_SEARCH_MSG_TIME);
|
dlm.setMessageExpiration(getContext().clock().now() + SINGLE_SEARCH_MSG_TIME);
|
||||||
dlm.setReplyTunnel(replyTunnel.getReceiveTunnelId(0));
|
dlm.setReplyTunnel(replyTunnel.getReceiveTunnelId(0));
|
||||||
dlm.setSearchKey(_key);
|
dlm.setSearchKey(_key);
|
||||||
|
dlm.setSearchType(_isLease ? DatabaseLookupMessage.Type.LS : DatabaseLookupMessage.Type.RI);
|
||||||
|
|
||||||
if (_log.shouldLog(Log.INFO)) {
|
if (_log.shouldLog(Log.INFO)) {
|
||||||
int tries;
|
int tries;
|
||||||
|
@ -19,6 +19,9 @@ class SingleSearchJob extends FloodOnlySearchJob {
|
|||||||
|
|
||||||
private static final int TIMEOUT = 8*1000;
|
private static final int TIMEOUT = 8*1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param key for Router Info ONLY
|
||||||
|
*/
|
||||||
public SingleSearchJob(RouterContext ctx, Hash key, Hash to) {
|
public SingleSearchJob(RouterContext ctx, Hash key, Hash to) {
|
||||||
// warning, null FloodfillNetworkDatabaseFacade ...
|
// warning, null FloodfillNetworkDatabaseFacade ...
|
||||||
// define our own failed() and success() below so _facade isn't used.
|
// define our own failed() and success() below so _facade isn't used.
|
||||||
@ -46,6 +49,7 @@ class SingleSearchJob extends FloodOnlySearchJob {
|
|||||||
dlm.setMessageExpiration(getContext().clock().now()+5*1000);
|
dlm.setMessageExpiration(getContext().clock().now()+5*1000);
|
||||||
dlm.setReplyTunnel(replyTunnel.getReceiveTunnelId(0));
|
dlm.setReplyTunnel(replyTunnel.getReceiveTunnelId(0));
|
||||||
dlm.setSearchKey(_key);
|
dlm.setSearchKey(_key);
|
||||||
|
dlm.setSearchType(DatabaseLookupMessage.Type.RI);
|
||||||
|
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info(getJobId() + ": Single search for " + _key + " to " + _to);
|
_log.info(getJobId() + ": Single search for " + _key + " to " + _to);
|
||||||
|
Reference in New Issue
Block a user