forked from I2P_Developers/i2p.i2p
* NetDB:
- Encrypt DatabaseLookup messages out exploratory tunnels when we already have the RI of the ff - Don't use multiple routers from the same /16 in lookups or stores
This commit is contained in:
16
history.txt
16
history.txt
@ -1,6 +1,12 @@
|
||||
2013-02-10 zzz
|
||||
* NetDB:
|
||||
- Encrypt DatabaseLookup messages out exploratory tunnels
|
||||
when we already have the RI of the ff
|
||||
- Don't use multiple routers from the same /16 in lookups or stores
|
||||
|
||||
2013-02-06 kytv
|
||||
* German, Polish, Portuguese, Spanish, and Swedish translation updates
|
||||
from Transifex
|
||||
* German, Polish, Portuguese, Spanish, and Swedish translation updates
|
||||
from Transifex
|
||||
|
||||
2013-02-04 str4d
|
||||
* i2ptunnel:
|
||||
@ -9,8 +15,8 @@
|
||||
- Allow any domain name to be mapped, not just .i2p
|
||||
|
||||
2013-01-31 kytv
|
||||
* Add Norwegian Bokmål language to the router console
|
||||
* Add Bokmål translations from Transifex
|
||||
* Add Norwegian Bokmål language to the router console
|
||||
* Add Bokmål translations from Transifex
|
||||
|
||||
2013-01-31 zzz
|
||||
* EepGet:
|
||||
@ -18,7 +24,7 @@
|
||||
- Add port to Host header to conform to RFC 2616
|
||||
|
||||
2013-01-29 zzz
|
||||
* Console: Catch IllegalStateException storing nonces (ticket #852)
|
||||
* Console: Catch IllegalStateException storing nonces (tickets #836, #852, #858)
|
||||
* Translations:
|
||||
- Use JVM language name if available
|
||||
- Correct Estonian language code from ee to et
|
||||
|
@ -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 = 9;
|
||||
public final static long BUILD = 10;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
@ -9,6 +9,7 @@ package net.i2p.router.networkdb.kademlia;
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@ -17,6 +18,7 @@ import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.RouterAddress;
|
||||
import net.i2p.data.RouterInfo;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.peermanager.PeerProfile;
|
||||
@ -205,17 +207,29 @@ class FloodfillPeerSelector extends PeerSelector {
|
||||
}
|
||||
}
|
||||
|
||||
// 8 == FNDF.MAX_TO_FLOOD + 1
|
||||
int limit = Math.max(8, howMany);
|
||||
// 5 == FNDF.MAX_TO_FLOOD + 1
|
||||
int limit = Math.max(5, howMany);
|
||||
limit = Math.min(limit, ffs.size());
|
||||
Set<Integer> maskedIPs = new HashSet(limit + 4);
|
||||
// split sorted list into 3 sorted lists
|
||||
for (int i = 0; found < howMany && i < limit; i++) {
|
||||
Hash entry = sorted.first();
|
||||
sorted.remove(entry);
|
||||
if (entry == null)
|
||||
break; // shouldn't happen
|
||||
sorted.remove(entry);
|
||||
// put anybody in the same /16 at the end
|
||||
RouterInfo info = _context.netDb().lookupRouterInfoLocally(entry);
|
||||
if (info != null && now - info.getPublished() > 3*60*60*1000) {
|
||||
Set<Integer> entryIPs = maskedIPSet(entry, info, 2);
|
||||
boolean sameIP = false;
|
||||
for (Integer ip : entryIPs) {
|
||||
if (!maskedIPs.add(ip))
|
||||
sameIP = true;
|
||||
}
|
||||
if (sameIP) {
|
||||
badff.add(entry);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Same /16: " + entry);
|
||||
} else if (info != null && now - info.getPublished() > 3*60*60*1000) {
|
||||
badff.add(entry);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Old: " + entry);
|
||||
@ -270,6 +284,44 @@ class FloodfillPeerSelector extends PeerSelector {
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The Set of IPs for this peer, with a given mask.
|
||||
* Includes the comm system's record of the IP, and all netDb addresses.
|
||||
*
|
||||
* @param pinfo may be null
|
||||
* @return an opaque set of masked IPs for this peer
|
||||
* @since 0.9.5 modified from ProfileOrganizer
|
||||
*/
|
||||
private Set<Integer> maskedIPSet(Hash peer, RouterInfo pinfo, int mask) {
|
||||
Set<Integer> rv = new HashSet(2);
|
||||
byte[] commIP = _context.commSystem().getIP(peer);
|
||||
if (commIP != null)
|
||||
rv.add(maskedIP(commIP, mask));
|
||||
if (pinfo == null)
|
||||
return rv;
|
||||
Collection<RouterAddress> paddr = pinfo.getAddresses();
|
||||
if (paddr == null)
|
||||
return rv;
|
||||
for (RouterAddress pa : paddr) {
|
||||
byte[] pib = pa.getIP();
|
||||
if (pib == null) continue;
|
||||
rv.add(maskedIP(pib, mask));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate an arbitrary unique value for this ip/mask (mask = 1-4)
|
||||
* @since 0.9.5 copied from ProfileOrganizer
|
||||
*/
|
||||
private static Integer maskedIP(byte[] ip, int mask) {
|
||||
int rv = 0;
|
||||
for (int i = 0; i < mask; i++)
|
||||
rv = (rv << 8) | (ip[i] & 0xff);
|
||||
return Integer.valueOf(rv);
|
||||
}
|
||||
|
||||
private class FloodfillSelectionCollector implements SelectionCollector {
|
||||
private final TreeSet<Hash> _sorted;
|
||||
private final List<Hash> _floodfillMatches;
|
||||
|
@ -14,6 +14,7 @@ import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.RouterInfo;
|
||||
import net.i2p.data.i2np.DatabaseLookupMessage;
|
||||
import net.i2p.data.i2np.I2NPMessage;
|
||||
import net.i2p.router.CommSystemFacade;
|
||||
import net.i2p.router.Job;
|
||||
import net.i2p.router.MessageSelector;
|
||||
@ -225,7 +226,21 @@ class IterativeSearchJob extends FloodSearchJob {
|
||||
_log.info(getJobId() + ": Iterative search for " + _key + " to " + peer);
|
||||
long now = getContext().clock().now();
|
||||
_sentTime.put(peer, Long.valueOf(now));
|
||||
getContext().tunnelDispatcher().dispatchOutbound(dlm, outTunnel.getSendTunnelId(0), peer);
|
||||
|
||||
I2NPMessage outMsg = null;
|
||||
if (_isLease) {
|
||||
// Full ElG is fairly expensive so only do it for LS lookups
|
||||
// if we have the ff RI, garlic encrypt it
|
||||
RouterInfo ri = getContext().netDb().lookupRouterInfoLocally(peer);
|
||||
if (ri != null) {
|
||||
outMsg = MessageWrapper.wrap(getContext(), dlm, ri);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getJobId() + ": Encrypted DLM for " + _key + " to " + peer);
|
||||
}
|
||||
}
|
||||
if (outMsg == null)
|
||||
outMsg = dlm;
|
||||
getContext().tunnelDispatcher().dispatchOutbound(outMsg, outTunnel.getSendTunnelId(0), peer);
|
||||
|
||||
// The timeout job is always run (never cancelled)
|
||||
// Note that the timeout is much shorter than the message expiration (see above)
|
||||
|
@ -115,4 +115,31 @@ class MessageWrapper {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Garlic wrap a message from nobody, destined for a router,
|
||||
* to hide the contents from the OBEP.
|
||||
* Forces ElGamal.
|
||||
*
|
||||
* @return null on encrypt failure
|
||||
* @since 0.9.5
|
||||
*/
|
||||
static GarlicMessage wrap(RouterContext ctx, I2NPMessage m, RouterInfo to) {
|
||||
DeliveryInstructions instructions = new DeliveryInstructions();
|
||||
instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_LOCAL);
|
||||
|
||||
PayloadGarlicConfig payload = new PayloadGarlicConfig();
|
||||
payload.setCertificate(Certificate.NULL_CERT);
|
||||
payload.setId(ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE));
|
||||
payload.setPayload(m);
|
||||
payload.setRecipient(to);
|
||||
payload.setDeliveryInstructions(instructions);
|
||||
payload.setExpiration(m.getMessageExpiration());
|
||||
|
||||
SessionKey sentKey = ctx.keyGenerator().generateSessionKey();
|
||||
PublicKey key = to.getIdentity().getPublicKey();
|
||||
GarlicMessage msg = GarlicMessageBuilder.buildMessage(ctx, payload, null, null,
|
||||
key, sentKey, null);
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user