diff --git a/apps/i2ptunnel/jsp/editClient.jsp b/apps/i2ptunnel/jsp/editClient.jsp index a51dead901..7c4e787fdc 100644 --- a/apps/i2ptunnel/jsp/editClient.jsp +++ b/apps/i2ptunnel/jsp/editClient.jsp @@ -424,9 +424,9 @@ <%=intl._("NOTE: If tunnel is currently running, most changes will not take effect until tunnel is stopped and restarted.")%>

- - + + diff --git a/apps/i2ptunnel/jsp/editServer.jsp b/apps/i2ptunnel/jsp/editServer.jsp index 90a7614f29..0f970eb7ee 100644 --- a/apps/i2ptunnel/jsp/editServer.jsp +++ b/apps/i2ptunnel/jsp/editServer.jsp @@ -341,7 +341,7 @@
@@ -457,9 +457,9 @@ <%=intl._("NOTE: If tunnel is currently running, most changes will not take effect until tunnel is stopped and restarted.")%>

- - + +
diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionManager.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionManager.java index f69a0059cb..49cc0476ac 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionManager.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionManager.java @@ -135,6 +135,14 @@ public class ConnectionManager { // active++; //} if (locked_tooManyStreams()) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Refusing connection since we have exceeded our max of " + + _maxConcurrentStreams + " connections"); + reject = true; + } else if (shouldRejectConnection(synPacket)) { + _log.error("Refusing connection since peer is " + + (_defaultOptions.isAccessListEnabled() ? "not whitelisted: " : "blacklisted: ") + + (synPacket.getOptionalFrom() == null ? "null from" : synPacket.getOptionalFrom().calculateHash().toBase64())); reject = true; } else { while (true) { @@ -151,9 +159,6 @@ public class ConnectionManager { _context.statManager().addRateData("stream.receiveActive", active, total); if (reject) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Refusing connection since we have exceeded our max of " - + _maxConcurrentStreams + " connections"); PacketLocal reply = new PacketLocal(_context, synPacket.getOptionalFrom()); reply.setFlag(Packet.FLAG_RESET); reply.setFlag(Packet.FLAG_SIGNATURE_INCLUDED); @@ -270,6 +275,21 @@ public class ConnectionManager { return (active >= _maxConcurrentStreams); } + private boolean shouldRejectConnection(Packet syn) { + // unfortunately we don't have access to the router client manager here, + // so we can't whitelist local access + Destination from = syn.getOptionalFrom(); + if (from == null) + return true; + // if the sig is absent or bad it will be caught later (in CPH) + if (_defaultOptions.isAccessListEnabled()) + return !_defaultOptions.getAccessList().contains(from.calculateHash()); + if (_defaultOptions.isBlacklistEnabled()) + return _defaultOptions.getBlacklist().contains(from.calculateHash()); + return false; + } + + public MessageHandler getMessageHandler() { return _messageHandler; } public PacketHandler getPacketHandler() { return _packetHandler; } public I2PSession getSession() { return _session; } diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java index ea4e1f069c..da3bd48f8e 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java @@ -1,6 +1,15 @@ package net.i2p.client.streaming; +import java.util.Collections; +import java.util.HashSet; import java.util.Properties; +import java.util.Set; +import java.util.StringTokenizer; + +import net.i2p.I2PAppContext; +import net.i2p.data.Hash; +import net.i2p.util.ConvertToHash; +import net.i2p.util.Log; /** * Define the current options for the con (and allow custom tweaking midstream) @@ -27,6 +36,10 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { private int _maxWindowSize; private int _congestionAvoidanceGrowthRateFactor; private int _slowStartGrowthRateFactor; + private boolean _accessListEnabled; + private boolean _blackListEnabled; + private Set _accessList; + private Set _blackList; public static final int PROFILE_BULK = 1; public static final int PROFILE_INTERACTIVE = 2; @@ -54,6 +67,9 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { public static final String PROP_CONGESTION_AVOIDANCE_GROWTH_RATE_FACTOR = "i2p.streaming.congestionAvoidanceGrowthRateFactor"; public static final String PROP_SLOW_START_GROWTH_RATE_FACTOR = "i2p.streaming.slowStartGrowthRateFactor"; public static final String PROP_ANSWER_PINGS = "i2p.streaming.answerPings"; + public static final String PROP_ENABLE_ACCESS_LIST = "i2cp.enableAccessList"; + public static final String PROP_ENABLE_BLACKLIST = "i2cp.enableBlackList"; + public static final String PROP_ACCESS_LIST = "i2cp.accessList"; private static final int TREND_COUNT = 3; static final int INITIAL_WINDOW_SIZE = 6; @@ -205,6 +221,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { setWriteTimeout(opts.getWriteTimeout()); setReadTimeout(opts.getReadTimeout()); setAnswerPings(opts.getAnswerPings()); + initLists(opts); } } @@ -230,6 +247,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { setSlowStartGrowthRateFactor(getInt(opts, PROP_SLOW_START_GROWTH_RATE_FACTOR, 1)); setConnectTimeout(getInt(opts, PROP_CONNECT_TIMEOUT, Connection.DISCONNECT_TIMEOUT)); setAnswerPings(getBool(opts, PROP_ANSWER_PINGS, DEFAULT_ANSWER_PINGS)); + initLists(opts); } @Override @@ -272,6 +290,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { setConnectTimeout(getInt(opts, PROP_CONNECT_TIMEOUT, Connection.DISCONNECT_TIMEOUT)); if (opts.containsKey(PROP_ANSWER_PINGS)) setAnswerPings(getBool(opts, PROP_ANSWER_PINGS, DEFAULT_ANSWER_PINGS)); + initLists(opts); } /** @@ -504,6 +523,57 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { public int getSlowStartGrowthRateFactor() { return _slowStartGrowthRateFactor; } public void setSlowStartGrowthRateFactor(int factor) { _slowStartGrowthRateFactor = factor; } + public boolean isAccessListEnabled() { return _accessListEnabled; } + public boolean isBlacklistEnabled() { return _blackListEnabled; } + public Set getAccessList() { return _accessList; } + public Set getBlacklist() { return _blackList; } + + private void initLists(ConnectionOptions opts) { + _accessListEnabled = opts.isAccessListEnabled(); + _blackListEnabled = opts.isBlacklistEnabled(); + _accessList = opts.getAccessList(); + _blackList = opts.getBlacklist(); + } + + private void initLists(Properties opts) { + _accessListEnabled = getBool(opts, PROP_ENABLE_ACCESS_LIST, false); + _blackListEnabled = getBool(opts, PROP_ENABLE_BLACKLIST, false); + if (_accessListEnabled) + _accessList = new HashSet(); + else + _accessList = Collections.EMPTY_SET; + if (_blackListEnabled) + _blackList = new HashSet(); + else + _blackList = Collections.EMPTY_SET; + if (!(_accessListEnabled || _blackListEnabled)) + return; + String hashes = opts.getProperty(PROP_ACCESS_LIST); + if (hashes == null) + return; + StringTokenizer tok = new StringTokenizer(hashes, ", "); + while (tok.hasMoreTokens()) { + String hashstr = tok.nextToken(); + Hash h = ConvertToHash.getHash(hashstr); + if (h == null) + error("bad list hash: " + hashstr); + else if (_blackListEnabled) + _blackList.add(h); + else + _accessList.add(h); + } + if (_accessListEnabled && _accessList.isEmpty()) + error("Connection access list enabled but no valid entries; no peers can connect"); + else if (_blackListEnabled && _blackList.isEmpty()) + error("Connection blacklist enabled but no valid entries; all peers can connect"); + } + + private static void error(String s) { + I2PAppContext ctx = I2PAppContext.getGlobalContext(); + Log log = ctx.logManager().getLog(ConnectionOptions.class); + log.error(s); + } + @Override public String toString() { StringBuilder buf = new StringBuilder(128); diff --git a/history.txt b/history.txt index 0b07ff3327..ac6f60dd69 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,14 @@ +2010-04-12 zzz + * configstats.jsp: Fix full stats checkbox default + * i2psnark: + - Concurrent, limit, display, log tweaks + * i2ptunnel: Implement access lists for TCP servers. + Enter b32 or b64 hash or dest into list box, and + check enable for whitelist. Uncheck enable and enter + i2cp.enableBlackList=true in advanced i2cp options for + blacklist. Todo: make black/whitelists radio buttons. + * LogManager: Concurrent + 2010-04-10 zzz * i2psnark: - Disconnect seeds that connect to a seed diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index a6204817e3..f2522cd4ed 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -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 = 8; + public final static long BUILD = 9; /** for example "-test" */ public final static String EXTRA = "";