forked from I2P_Developers/i2p.i2p
* IP Lookup:
- Add caching in RouterAddress with secondary caching in Addresses; use caches to speed up transport bids, blocklist checks, geoip lookups, and profile organizer checks (ticket #707) - Limit IP cache size in TransportImpl - Clear caches at shutdown * RouterAddress: Remove unused expiration field to save space
This commit is contained in:
@ -24,6 +24,7 @@ import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.RouterAddress;
|
||||
import net.i2p.data.RouterInfo;
|
||||
@ -438,14 +439,8 @@ public class Blocklist {
|
||||
* of IP ranges read in from the file.
|
||||
*/
|
||||
public void add(String ip) {
|
||||
InetAddress pi;
|
||||
try {
|
||||
pi = InetAddress.getByName(ip);
|
||||
} catch (UnknownHostException uhe) {
|
||||
return;
|
||||
}
|
||||
if (pi == null) return;
|
||||
byte[] pib = pi.getAddress();
|
||||
byte[] pib = Addresses.getIP(ip);
|
||||
if (pib == null) return;
|
||||
add(pib);
|
||||
}
|
||||
|
||||
@ -478,21 +473,13 @@ public class Blocklist {
|
||||
List<byte[]> rv = new ArrayList(1);
|
||||
RouterInfo pinfo = _context.netDb().lookupRouterInfoLocally(peer);
|
||||
if (pinfo == null) return rv;
|
||||
String oldphost = null;
|
||||
byte[] oldpib = null;
|
||||
// for each peer address
|
||||
for (RouterAddress pa : pinfo.getAddresses()) {
|
||||
String phost = pa.getOption("host");
|
||||
if (phost == null) continue;
|
||||
if (oldphost != null && oldphost.equals(phost)) continue;
|
||||
oldphost = phost;
|
||||
InetAddress pi;
|
||||
try {
|
||||
pi = InetAddress.getByName(phost);
|
||||
} catch (UnknownHostException uhe) {
|
||||
continue;
|
||||
}
|
||||
if (pi == null) continue;
|
||||
byte[] pib = pi.getAddress();
|
||||
byte[] pib = pa.getIP();
|
||||
if (pib == null) continue;
|
||||
if (DataHelper.eq(oldpib, pib)) continue;
|
||||
oldpib = pib;
|
||||
rv.add(pib);
|
||||
}
|
||||
return rv;
|
||||
@ -520,14 +507,8 @@ public class Blocklist {
|
||||
* calling this externally won't shitlist the peer, this is just an IP check
|
||||
*/
|
||||
public boolean isBlocklisted(String ip) {
|
||||
InetAddress pi;
|
||||
try {
|
||||
pi = InetAddress.getByName(ip);
|
||||
} catch (UnknownHostException uhe) {
|
||||
return false;
|
||||
}
|
||||
if (pi == null) return false;
|
||||
byte[] pib = pi.getAddress();
|
||||
byte[] pib = Addresses.getIP(ip);
|
||||
if (pib == null) return false;
|
||||
return isBlocklisted(pib);
|
||||
}
|
||||
|
||||
|
@ -1261,16 +1261,8 @@ public class ProfileOrganizer {
|
||||
if (paddr == null)
|
||||
return rv;
|
||||
for (RouterAddress pa : paddr) {
|
||||
String phost = pa.getOption("host");
|
||||
if (phost == null) continue;
|
||||
InetAddress pi;
|
||||
try {
|
||||
pi = InetAddress.getByName(phost);
|
||||
} catch (UnknownHostException uhe) {
|
||||
continue;
|
||||
}
|
||||
if (pi == null) continue;
|
||||
byte[] pib = pi.getAddress();
|
||||
byte[] pib = pa.getIP();
|
||||
if (pib == null) continue;
|
||||
rv.add(maskedIP(pib, mask));
|
||||
}
|
||||
return rv;
|
||||
|
@ -62,6 +62,7 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
||||
public void shutdown() {
|
||||
if (_manager != null)
|
||||
_manager.shutdown();
|
||||
_geoIP.shutdown();
|
||||
}
|
||||
|
||||
public void restart() {
|
||||
@ -250,7 +251,7 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
||||
props.setProperty(NTCPAddress.PROP_PORT, port);
|
||||
RouterAddress addr = new RouterAddress();
|
||||
addr.setCost(NTCPAddress.DEFAULT_COST);
|
||||
addr.setExpiration(null);
|
||||
//addr.setExpiration(null);
|
||||
addr.setOptions(props);
|
||||
addr.setTransportStyle(NTCPTransport.STYLE);
|
||||
//if (isNew) {
|
||||
|
@ -21,6 +21,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.Addresses;
|
||||
import net.i2p.util.ConcurrentHashSet;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
@ -72,6 +73,17 @@ class GeoIP {
|
||||
static final String COUNTRY_FILE_DEFAULT = "countries.txt";
|
||||
public static final String PROP_IP_COUNTRY = "i2np.lastCountry";
|
||||
|
||||
/**
|
||||
* @since 0.9.3
|
||||
*/
|
||||
public void shutdown() {
|
||||
_codeToName.clear();
|
||||
_codeCache.clear();
|
||||
_IPToCountry.clear();
|
||||
_pendingSearch.clear();
|
||||
_notFound.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire off a thread to lookup all pending IPs.
|
||||
* There is no indication of completion.
|
||||
@ -297,14 +309,8 @@ class GeoIP {
|
||||
* Add to the list needing lookup
|
||||
*/
|
||||
public void add(String ip) {
|
||||
InetAddress pi;
|
||||
try {
|
||||
pi = InetAddress.getByName(ip);
|
||||
} catch (UnknownHostException uhe) {
|
||||
return;
|
||||
}
|
||||
if (pi == null) return;
|
||||
byte[] pib = pi.getAddress();
|
||||
byte[] pib = Addresses.getIP(ip);
|
||||
if (pib == null) return;
|
||||
add(pib);
|
||||
}
|
||||
|
||||
@ -325,14 +331,8 @@ class GeoIP {
|
||||
* @return lower-case code, generally two letters, or null.
|
||||
*/
|
||||
public String get(String ip) {
|
||||
InetAddress pi;
|
||||
try {
|
||||
pi = InetAddress.getByName(ip);
|
||||
} catch (UnknownHostException uhe) {
|
||||
return null;
|
||||
}
|
||||
if (pi == null) return null;
|
||||
byte[] pib = pi.getAddress();
|
||||
byte[] pib = Addresses.getIP(ip);
|
||||
if (pib == null) return null;
|
||||
return get(pib);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ import java.util.Set;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.RouterAddress;
|
||||
import net.i2p.data.RouterIdentity;
|
||||
@ -35,6 +36,7 @@ import net.i2p.router.Router;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
|
||||
import net.i2p.util.ConcurrentHashSet;
|
||||
import net.i2p.util.LHMCache;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SimpleScheduler;
|
||||
import net.i2p.util.SimpleTimer;
|
||||
@ -53,7 +55,18 @@ public abstract class TransportImpl implements Transport {
|
||||
private final Map<Hash, Long> _unreachableEntries;
|
||||
private final Set<Hash> _wasUnreachableEntries;
|
||||
/** global router ident -> IP */
|
||||
private static final Map<Hash, byte[]> _IPMap = new ConcurrentHashMap(128);
|
||||
private static final Map<Hash, byte[]> _IPMap;
|
||||
|
||||
static {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemory == Long.MAX_VALUE)
|
||||
maxMemory = 96*1024*1024l;
|
||||
long min = 512;
|
||||
long max = 4096;
|
||||
// 1024 nominal for 128 MB
|
||||
int size = (int) Math.max(min, Math.min(max, 1 + (maxMemory / (128*1024))));
|
||||
_IPMap = new LHMCache(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the new transport
|
||||
@ -585,12 +598,27 @@ public abstract class TransportImpl implements Transport {
|
||||
}
|
||||
|
||||
public void setIP(Hash peer, byte[] ip) {
|
||||
_IPMap.put(peer, ip);
|
||||
_context.commSystem().queueLookup(ip);
|
||||
byte[] old;
|
||||
synchronized (_IPMap) {
|
||||
old = _IPMap.put(peer, ip);
|
||||
}
|
||||
if (!DataHelper.eq(old, ip))
|
||||
_context.commSystem().queueLookup(ip);
|
||||
}
|
||||
|
||||
public static byte[] getIP(Hash peer) {
|
||||
return _IPMap.get(peer);
|
||||
synchronized (_IPMap) {
|
||||
return _IPMap.get(peer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.3
|
||||
*/
|
||||
static void clearCaches() {
|
||||
synchronized(_IPMap) {
|
||||
_IPMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/** @param addr non-null */
|
||||
|
@ -185,6 +185,8 @@ public class TransportManager implements TransportEventListener {
|
||||
public void shutdown() {
|
||||
stopListening();
|
||||
_dhThread.shutdown();
|
||||
Addresses.clearCaches();
|
||||
TransportImpl.clearCaches();
|
||||
}
|
||||
|
||||
public Transport getTransport(String style) {
|
||||
|
@ -8,13 +8,13 @@ package net.i2p.router.transport.ntcp;
|
||||
*
|
||||
*/
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.RouterAddress;
|
||||
import net.i2p.router.transport.TransportImpl;
|
||||
import net.i2p.util.Addresses;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@ -25,9 +25,9 @@ public class NTCPAddress {
|
||||
private final String _host;
|
||||
//private InetAddress _addr;
|
||||
/** Port number used in RouterAddress definitions */
|
||||
public final static String PROP_PORT = "port";
|
||||
public final static String PROP_PORT = RouterAddress.PROP_PORT;
|
||||
/** Host name used in RouterAddress definitions */
|
||||
public final static String PROP_HOST = "host";
|
||||
public final static String PROP_HOST = RouterAddress.PROP_HOST;
|
||||
public static final int DEFAULT_COST = 10;
|
||||
|
||||
public NTCPAddress(String host, int port) {
|
||||
@ -59,23 +59,8 @@ public class NTCPAddress {
|
||||
_port = -1;
|
||||
return;
|
||||
}
|
||||
String host = addr.getOption(PROP_HOST);
|
||||
int iport = -1;
|
||||
if (host == null) {
|
||||
_host = null;
|
||||
} else {
|
||||
_host = host.trim();
|
||||
String port = addr.getOption(PROP_PORT);
|
||||
if ( (port != null) && (port.trim().length() > 0) && !("null".equals(port)) ) {
|
||||
try {
|
||||
iport = Integer.parseInt(port.trim());
|
||||
} catch (NumberFormatException nfe) {
|
||||
Log log = I2PAppContext.getGlobalContext().logManager().getLog(NTCPAddress.class);
|
||||
log.error("Invalid port [" + port + "]", nfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
_port = iport;
|
||||
_host = addr.getOption(PROP_HOST);
|
||||
_port = addr.getPort();
|
||||
}
|
||||
|
||||
public RouterAddress toRouterAddress() {
|
||||
@ -85,7 +70,7 @@ public class NTCPAddress {
|
||||
RouterAddress addr = new RouterAddress();
|
||||
|
||||
addr.setCost(DEFAULT_COST);
|
||||
addr.setExpiration(null);
|
||||
//addr.setExpiration(null);
|
||||
|
||||
Properties props = new Properties();
|
||||
props.setProperty(PROP_HOST, _host);
|
||||
@ -106,24 +91,11 @@ public class NTCPAddress {
|
||||
public boolean isPubliclyRoutable() {
|
||||
return isPubliclyRoutable(_host);
|
||||
}
|
||||
|
||||
public static boolean isPubliclyRoutable(String host) {
|
||||
if (host == null) return false;
|
||||
try {
|
||||
InetAddress addr = InetAddress.getByName(host);
|
||||
byte quad[] = addr.getAddress();
|
||||
// allow ipv6 for ntcpaddress, since we've still got ssu
|
||||
//if (quad.length != 4) {
|
||||
// if (_log.shouldLog(Log.ERROR))
|
||||
// _log.error("Refusing IPv6 address (" + host + " / " + addr.getHostAddress() + ") "
|
||||
// + " since not all peers support it, and we don't support restricted routes");
|
||||
// return false;
|
||||
//}
|
||||
return TransportImpl.isPubliclyRoutable(quad);
|
||||
} catch (Throwable t) {
|
||||
//if (_log.shouldLog(Log.WARN))
|
||||
// _log.warn("Error checking routability", t);
|
||||
return false;
|
||||
}
|
||||
byte quad[] = Addresses.getIP(host);
|
||||
return TransportImpl.isPubliclyRoutable(quad);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -298,8 +298,8 @@ public class NTCPTransport extends TransportImpl {
|
||||
_log.debug("no bid when trying to send to " + peer.toBase64() + " as they don't have an ntcp address");
|
||||
return null;
|
||||
}
|
||||
NTCPAddress naddr = new NTCPAddress(addr);
|
||||
if ( (naddr.getPort() <= 0) || (naddr.getHost() == null) ) {
|
||||
byte[] ip = addr.getIP();
|
||||
if ( (addr.getPort() <= 0) || (ip == null) ) {
|
||||
_context.statManager().addRateData("ntcp.connectFailedInvalidPort", 1);
|
||||
markUnreachable(peer);
|
||||
//_context.shitlist().shitlistRouter(toAddress.getIdentity().calculateHash(), "Invalid NTCP address", STYLE);
|
||||
@ -307,7 +307,7 @@ public class NTCPTransport extends TransportImpl {
|
||||
_log.debug("no bid when trying to send to " + peer.toBase64() + " as they don't have a valid ntcp address");
|
||||
return null;
|
||||
}
|
||||
if (!naddr.isPubliclyRoutable()) {
|
||||
if (!isPubliclyRoutable(ip)) {
|
||||
if (! _context.getProperty("i2np.ntcp.allowLocal", "false").equals("true")) {
|
||||
_context.statManager().addRateData("ntcp.bidRejectedLocalAddress", 1);
|
||||
markUnreachable(peer);
|
||||
|
@ -9,6 +9,7 @@ import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.RouterAddress;
|
||||
import net.i2p.data.RouterInfo;
|
||||
import net.i2p.data.SessionKey;
|
||||
import net.i2p.router.CommSystemFacade;
|
||||
@ -584,7 +585,13 @@ class PeerTestManager {
|
||||
aliceIntroKey = new SessionKey(new byte[SessionKey.KEYSIZE_BYTES]);
|
||||
testInfo.readIntroKey(aliceIntroKey.getData(), 0);
|
||||
|
||||
UDPAddress addr = new UDPAddress(charlieInfo.getTargetAddress(UDPTransport.STYLE));
|
||||
RouterAddress raddr = charlieInfo.getTargetAddress(UDPTransport.STYLE);
|
||||
if (raddr == null) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Unable to pick a charlie");
|
||||
return;
|
||||
}
|
||||
UDPAddress addr = new UDPAddress(raddr);
|
||||
SessionKey charlieIntroKey = new SessionKey(addr.getIntroKey());
|
||||
|
||||
//UDPPacket packet = _packetBuilder.buildPeerTestToAlice(aliceIP, from.getPort(), aliceIntroKey, charlieIntroKey, nonce);
|
||||
|
@ -12,9 +12,9 @@ import net.i2p.data.SessionKey;
|
||||
* FIXME public for ConfigNetHelper
|
||||
*/
|
||||
public class UDPAddress {
|
||||
private String _host;
|
||||
private final String _host;
|
||||
private InetAddress _hostAddress;
|
||||
private int _port;
|
||||
private final int _port;
|
||||
private byte[] _introKey;
|
||||
private String _introHosts[];
|
||||
private InetAddress _introAddresses[];
|
||||
@ -23,8 +23,8 @@ public class UDPAddress {
|
||||
private long _introTags[];
|
||||
private int _mtu;
|
||||
|
||||
public static final String PROP_PORT = "port";
|
||||
public static final String PROP_HOST = "host";
|
||||
public static final String PROP_PORT = RouterAddress.PROP_PORT;
|
||||
public static final String PROP_HOST = RouterAddress.PROP_HOST;
|
||||
public static final String PROP_INTRO_KEY = "key";
|
||||
public static final String PROP_MTU = "mtu";
|
||||
|
||||
@ -40,16 +40,13 @@ public class UDPAddress {
|
||||
|
||||
public UDPAddress(RouterAddress addr) {
|
||||
// TODO make everything final
|
||||
if (addr == null) return;
|
||||
_host = addr.getOption(PROP_HOST);
|
||||
if (_host != null) _host = _host.trim();
|
||||
try {
|
||||
String port = addr.getOption(PROP_PORT);
|
||||
if (port != null)
|
||||
_port = Integer.parseInt(port);
|
||||
} catch (NumberFormatException nfe) {
|
||||
_port = -1;
|
||||
if (addr == null) {
|
||||
_host = null;
|
||||
_port = 0;
|
||||
return;
|
||||
}
|
||||
_host = addr.getOption(PROP_HOST);
|
||||
_port = addr.getPort();
|
||||
try {
|
||||
String mtu = addr.getOption(PROP_MTU);
|
||||
if (mtu != null)
|
||||
@ -146,7 +143,7 @@ public class UDPAddress {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 0 if unset; -1 if invalid
|
||||
* @return 0 if unset or invalid
|
||||
*/
|
||||
public int getPort() { return _port; }
|
||||
|
||||
|
@ -1203,27 +1203,14 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
//UDPAddress ua = new UDPAddress(addr);
|
||||
//if (ua.getIntroducerCount() <= 0) {
|
||||
if (addr.getOption("ihost0") == null) {
|
||||
String host = addr.getOption(UDPAddress.PROP_HOST);
|
||||
String port = addr.getOption(UDPAddress.PROP_PORT);
|
||||
if (host == null || port == null) {
|
||||
byte[] ip = addr.getIP();
|
||||
int port = addr.getPort();
|
||||
if (ip == null || port <= 0 ||
|
||||
(!isValid(ip)) ||
|
||||
Arrays.equals(ip, getExternalIP())) {
|
||||
markUnreachable(to);
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
InetAddress ia = InetAddress.getByName(host);
|
||||
int iport = Integer.parseInt(port);
|
||||
if (iport <= 0 || iport > 65535 || (!isValid(ia.getAddress())) ||
|
||||
Arrays.equals(ia.getAddress(), getExternalIP())) {
|
||||
markUnreachable(to);
|
||||
return null;
|
||||
}
|
||||
} catch (UnknownHostException uhe) {
|
||||
markUnreachable(to);
|
||||
return null;
|
||||
} catch (NumberFormatException nfe) {
|
||||
markUnreachable(to);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (!allowConnection())
|
||||
return _cachedBid[TRANSIENT_FAIL_BID];
|
||||
@ -1338,6 +1325,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
_fragments.add(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* "injected" message from the EstablishmentManager
|
||||
*/
|
||||
void send(I2NPMessage msg, PeerState peer) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Injecting a data message to a new peer: " + peer);
|
||||
@ -1447,7 +1437,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
addr.setCost(DEFAULT_COST + 1);
|
||||
else
|
||||
addr.setCost(DEFAULT_COST);
|
||||
addr.setExpiration(null);
|
||||
//addr.setExpiration(null);
|
||||
addr.setTransportStyle(STYLE);
|
||||
addr.setOptions(options);
|
||||
|
||||
|
Reference in New Issue
Block a user