merge of '8bf9850eb3fe4fcfb63053838a188969b7ba9c5b'

and 'a40ea9b5f7545281195f00a80e31ae879197e76b'
This commit is contained in:
str4d
2016-11-20 06:08:40 +00:00
82 changed files with 1052 additions and 259 deletions

View File

@@ -283,7 +283,7 @@ Applications:
Bundles systray4j-2.4.1:
See licenses/LICENSE-LGPLv2.1.txt
Tomcat 6.0.47:
Tomcat 6.0.48:
Copyright 1999-2016 The Apache Software Foundation
See licenses/LICENSE-Apache2.0.txt
See licenses/NOTICE-Tomcat.txt

View File

@@ -86,6 +86,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>
@@ -106,6 +108,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</war>
<delete dir="${dist}/tmp"/>

View File

@@ -83,6 +83,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>

View File

@@ -84,6 +84,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>
@@ -130,6 +132,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</war>
</target>

View File

@@ -123,6 +123,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
private final AtomicLong _rxBytes = new AtomicLong();
private final AtomicLong _txBytes = new AtomicLong();
private long _started;
private long _nodesLastSaved;
/** all-zero NID used for pings */
public static final NID FAKE_NID = new NID(new byte[NID.HASH_LENGTH]);
@@ -156,6 +157,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
private static final long CLEAN_TIME = 63*1000;
private static final long EXPLORE_TIME = 877*1000;
private static final long BLACKLIST_CLEAN_TIME = 17*60*1000;
private static final long NODES_SAVE_TIME = 3*60*60*1000;
public static final String DHT_FILE_SUFFIX = ".dht.dat";
private static final int SEND_CRYPTO_TAGS = 8;
@@ -635,6 +637,7 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
_txBytes.set(0);
_rxBytes.set(0);
_started = _context.clock().now();
_nodesLastSaved = _started;
}
/**
@@ -1675,6 +1678,10 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
if (nid.lastSeen() < expire)
iter.remove();
}
if (now - _nodesLastSaved > NODES_SAVE_TIME) {
PersistDHT.saveDHT(_knownNodes, false, _dhtFile);
_nodesLastSaved = now;
}
// TODO sent queries?
if (_log.shouldLog(Log.DEBUG))
_log.debug("KRPC cleaner done, now with " +

View File

@@ -72,6 +72,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.j.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
<jar destfile="./build/temp-beans.jar" basedir="./build/obj" includes="**/ui/*.class **/EditBean.class **/IndexBean.class" />
@@ -103,6 +105,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.j.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>
@@ -241,6 +245,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.w.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</war>
</target>

View File

@@ -304,7 +304,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
return AuthResult.AUTH_GOOD;
}
}
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user);
_log.logAlways(Log.WARN, "HTTP proxy authentication failed, user: " + user);
} catch (UnsupportedEncodingException uee) {
_log.error(getPrefix(requestId) + "No UTF-8 support? B64: " + authorization, uee);
} catch (ArrayIndexOutOfBoundsException aioobe) {
@@ -363,7 +363,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
String ha1 = getTunnel().getClientOptions().getProperty(PROP_PROXY_DIGEST_PREFIX + user +
PROP_PROXY_DIGEST_SUFFIX);
if (ha1 == null) {
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user);
_log.logAlways(Log.WARN, "HTTP proxy authentication failed, user: " + user);
return AuthResult.AUTH_BAD;
}
// get H(A2)
@@ -373,7 +373,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
String kd = ha1 + ':' + nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2;
String hkd = PasswordManager.md5Hex(kd);
if (!response.equals(hkd)) {
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user);
_log.logAlways(Log.WARN, "HTTP proxy authentication failed, user: " + user);
if (_log.shouldLog(Log.INFO))
_log.info("Bad digest auth: " + DataHelper.toString(args));
return AuthResult.AUTH_BAD;

View File

@@ -131,26 +131,32 @@ class SOCKS5Server extends SOCKSServer {
*/
private void verifyPassword(DataInputStream in, DataOutputStream out) throws IOException, SOCKSException {
int c = in.readUnsignedByte();
if (c != AUTH_VERSION)
if (c != AUTH_VERSION) {
_log.logAlways(Log.WARN, "SOCKS proxy authentication failed");
throw new SOCKSException("Unsupported authentication version");
}
c = in.readUnsignedByte();
if (c <= 0)
if (c <= 0) {
_log.logAlways(Log.WARN, "SOCKS proxy authentication failed");
throw new SOCKSException("Bad authentication");
}
byte[] user = new byte[c];
String u = new String(user, "UTF-8");
in.readFully(user);
c = in.readUnsignedByte();
if (c <= 0)
if (c <= 0) {
_log.logAlways(Log.WARN, "SOCKS proxy authentication failed, user: " + u);
throw new SOCKSException("Bad authentication");
}
byte[] pw = new byte[c];
in.readFully(pw);
// Hopefully these are in UTF-8, since that's what our config file is in
// these throw UnsupportedEncodingException which is an IOE
String u = new String(user, "UTF-8");
String p = new String(pw, "UTF-8");
String configUser = props.getProperty(I2PTunnelHTTPClientBase.PROP_USER);
String configPW = props.getProperty(I2PTunnelHTTPClientBase.PROP_PW);
if ((!u.equals(configUser)) || (!p.equals(configPW))) {
_log.error("SOCKS authorization failure");
_log.logAlways(Log.WARN, "SOCKS proxy authentication failed, user: " + u);
sendAuthReply(AUTH_FAILURE, out);
throw new SOCKSException("SOCKS authorization failure");
}
@@ -591,9 +597,13 @@ class SOCKS5Server extends SOCKSServer {
// todo pass the response through?
} catch (IOException e) {
try { destSock.close(); } catch (IOException ioe) {}
if (in != null) try { in.close(); } catch (IOException ioe) {}
if (out != null) try { out.close(); } catch (IOException ioe) {}
throw e;
} catch (SOCKSException e) {
try { destSock.close(); } catch (IOException ioe) {}
if (in != null) try { in.close(); } catch (IOException ioe) {}
if (out != null) try { out.close(); } catch (IOException ioe) {}
throw e;
}
// that's it, caller will send confirmation to our client
@@ -601,9 +611,10 @@ class SOCKS5Server extends SOCKSServer {
}
// This isn't really the right place for this, we can't stop the tunnel once it starts.
static SOCKSUDPTunnel _tunnel;
static final Object _startLock = new Object();
static byte[] dummyIP = new byte[4];
private static SOCKSUDPTunnel _tunnel;
private static final Object _startLock = new Object();
private static final byte[] dummyIP = new byte[4];
/**
* We got a UDP associate command.
* Loop here looking for more, never return normally,

View File

@@ -71,6 +71,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>

View File

@@ -75,6 +75,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</war>
</target>

View File

@@ -17,6 +17,7 @@
</target>
<!-- only used if not set by a higher build.xml -->
<property name="javac.version" value="1.7" />
<property name="javac.compilerargs7" value="" />
<target name="compile" depends="depend">
@@ -39,7 +40,7 @@
<mkdir dir="./buildTest/obj" />
<javac
srcdir="./test/junit"
debug="true" deprecation="on" source="1.7" target="1.7"
debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
includeAntRuntime="false"
destdir="./buildTest/obj"
classpath="./build/zxing.jar" >
@@ -75,6 +76,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>

View File

@@ -2,7 +2,7 @@ This is Apache Tomcat 6.x, supporting Servlet 2.5 and JSP 2.1.
The Glassfish JSP 2.1 bundled in Jetty 6 is way too old.
Retrieved from the file
apache-tomcat-6.0.44-deployer.tar.gz
apache-tomcat-6.0.48-deployer.tar.gz
minus the following files and directores:

View File

@@ -1,7 +1,7 @@
This is Apache Tomcat 6.x, supporting Servlet 2.5 and JSP 2.1.
Retrieved from the file
apache-tomcat-6.0.44.tar.gz
apache-tomcat-6.0.48.tar.gz
containing only a small subset of lib/tomcat-coyote.jar.

View File

@@ -22,7 +22,7 @@
<property name="javac.compilerargs" value="" />
<property name="javac.version" value="1.7" />
<property name="tomcat.lib" value="apache-tomcat-deployer/lib" />
<property name="tomcat.ver" value="6.0.47" />
<property name="tomcat.ver" value="6.0.48" />
<property name="tomcat2.lib" value="apache-tomcat-${tomcat.ver}/lib" />
<property name="tomcat2.lib.small" value="apache-tomcat/lib" />
@@ -340,6 +340,8 @@
<!-- needed by JettyStart for pre-0.7.5 wrapper.config -->
<attribute name="Class-Path" value="jetty-deploy.jar jetty-xml.jar" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>

View File

@@ -13,6 +13,9 @@
cache="../../../build"
srcdir="./src"
destdir="./build/obj" >
<classpath>
<pathelement location="../../../core/java/build/i2p.jar" />
</classpath>
</depend>
</target>
@@ -32,6 +35,9 @@
includeAntRuntime="false"
includes="**/*.java" >
<compilerarg line="${javac.compilerargs}" />
<classpath>
<pathelement location="../../../core/java/build/i2p.jar" />
</classpath>
</javac>
</target>
@@ -54,6 +60,7 @@
<property name="workspace.changes.tr" value="" />
<jar destfile="./build/jrobin.jar" basedir="./build/obj" includes="**/*.class">
<manifest>
<attribute name="Class-Path" value="i2p.jar" />
<attribute name="Implementation-Version" value="1.6.0-1" />
<attribute name="Built-By" value="${build.built-by}" />
<attribute name="Build-Date" value="${build.timestamp}" />

View File

@@ -31,8 +31,10 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.i2p.I2PAppContext;
import net.i2p.util.Log;
/**
* Helper to deallocate memory on the native heap allocated during the creation
@@ -56,12 +58,16 @@ import java.util.logging.Logger;
*/
public class DeallocationHelper {
private final Log logger = I2PAppContext.getGlobalContext().logManager().getLog(DeallocationHelper.class);
/**
* tool responsible for releasing the native memory of a deallocatable byte
* buffer
*/
public static abstract class Deallocator {
protected final Log logger = I2PAppContext.getGlobalContext().logManager().getLog(DeallocationHelper.class);
public Deallocator() {
super();
}
@@ -101,7 +107,7 @@ public class DeallocationHelper {
cleanerCleanMethod = cleanerClass.getDeclaredMethod("clean");
}
} catch (ClassNotFoundException | NoSuchMethodException e) {
logger.log(Level.WARNING,
logger.warn(
"The initialization of the deallocator for Oracle Java, Sun Java and OpenJDK has failed", e);
}
}
@@ -122,7 +128,7 @@ public class DeallocationHelper {
success = true;
}
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
logger.log(Level.WARNING, "The deallocation of a direct NIO buffer has failed", e);
logger.warn("The deallocation of a direct NIO buffer has failed", e);
} finally {
directByteBufferCleanerMethod.setAccessible(directByteBufferCleanerMethodWasAccessible);
cleanerCleanMethod.setAccessible(cleanerCleanMethodWasAccessible);
@@ -142,7 +148,7 @@ public class DeallocationHelper {
final Class<?> directByteBufferClass = Class.forName("java.nio.DirectByteBuffer");
directByteBufferFreeMethod = directByteBufferClass.getDeclaredMethod("free");
} catch (ClassNotFoundException | NoSuchMethodException e) {
logger.log(Level.WARNING, "The initialization of the deallocator for Android has failed", e);
logger.warn("The initialization of the deallocator for Android has failed", e);
}
}
@@ -156,7 +162,7 @@ public class DeallocationHelper {
directByteBufferFreeMethod.invoke(directByteBuffer);
success = true;
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
logger.log(Level.WARNING, "The deallocation of a direct NIO buffer has failed", e);
logger.warn("The deallocation of a direct NIO buffer has failed", e);
} finally {
directByteBufferFreeMethod.setAccessible(directByteBufferFreeMethodWasAccessible);
}
@@ -180,7 +186,7 @@ public class DeallocationHelper {
gnuClasspathPointerClass);
bufferAddressField = Buffer.class.getDeclaredField("address");
} catch (ClassNotFoundException | NoSuchMethodException | NoSuchFieldException e) {
logger.log(Level.WARNING, "The initialization of the deallocator for GNU Classpath has failed", e);
logger.warn("The initialization of the deallocator for GNU Classpath has failed", e);
}
}
@@ -199,7 +205,7 @@ public class DeallocationHelper {
success = true;
}
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
logger.log(Level.WARNING, "The deallocation of a direct NIO buffer has failed", e);
logger.warn("The deallocation of a direct NIO buffer has failed", e);
} finally {
bufferAddressField.setAccessible(bufferAddressFieldWasAccessible);
vmDirectByteBufferFreeMethod.setAccessible(vmDirectByteBufferFreeMethodWasAccessible);
@@ -219,7 +225,7 @@ public class DeallocationHelper {
final Class<?> directByteBufferClass = Class.forName("java.nio.DirectByteBuffer");
directByteBufferFreeMethod = directByteBufferClass.getDeclaredMethod("free");
} catch (ClassNotFoundException | NoSuchMethodException e) {
logger.log(Level.WARNING, "The initialization of the deallocator for Apache Harmony has failed", e);
logger.warn("The initialization of the deallocator for Apache Harmony has failed", e);
}
}
@@ -233,7 +239,7 @@ public class DeallocationHelper {
directByteBufferFreeMethod.invoke(directByteBuffer);
success = true;
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
logger.log(Level.WARNING, "The deallocation of a direct NIO buffer has failed", e);
logger.warn("The deallocation of a direct NIO buffer has failed", e);
} finally {
directByteBufferFreeMethod.setAccessible(directByteBufferFreeMethodWasAccessible);
}
@@ -242,8 +248,6 @@ public class DeallocationHelper {
}
}
private static final Logger logger = Logger.getLogger(DeallocationHelper.class.getName());
private Map<Class<?>, Field> attachmentOrByteBufferFieldMap;
private Set<Class<?>> deallocatableBufferClassSet;
@@ -431,7 +435,7 @@ public class DeallocationHelper {
}
superClassesMsg = builder.toString();
}
logger.warning("The field " + fieldname + " hasn't been found in the class " + classname
logger.warn("The field " + fieldname + " hasn't been found in the class " + classname
+ superClassesMsg);
} else {// the field has been found, stores it into the map
attachmentOrByteBufferFieldMap.put(bufferClass, bufferField);
@@ -449,7 +453,7 @@ public class DeallocationHelper {
final String msg = "The class " + classname
+ " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor
+ " Java version: " + javaVersion;
logger.log(Level.WARNING, msg, cnfe);
logger.warn(msg, cnfe);
}
}
// if a known implementation has drastically changed or if the current
@@ -567,7 +571,7 @@ public class DeallocationHelper {
break;
}
} catch (IllegalAccessException iae) {
logger.log(Level.WARNING, "Cannot access the field " + field.getName()
logger.warn("Cannot access the field " + field.getName()
+ " of the class " + bufferIntermediaryClass.getName(), iae);
} finally {
field.setAccessible(fieldWasAccessible);
@@ -594,7 +598,7 @@ public class DeallocationHelper {
final String msg = "The class " + directByteBufferClassName
+ " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor
+ " Java version: " + javaVersion;
logger.log(Level.WARNING, msg, cnfe);
logger.warn(msg, cnfe);
}
if (directByteBufferClass != null)
deallocatableBufferClassSet.add(directByteBufferClass);
@@ -607,7 +611,7 @@ public class DeallocationHelper {
final String msg = "The class " + readOnlyDirectByteBufferClassName
+ " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor
+ " Java version: " + javaVersion;
logger.log(Level.WARNING, msg, cnfe);
logger.warn(msg, cnfe);
}
if (readOnlyDirectByteBufferClass != null)
deallocatableBufferClassSet.add(readOnlyDirectByteBufferClass);
@@ -619,7 +623,7 @@ public class DeallocationHelper {
final String msg = "The class " + readWriteDirectByteBufferClassName
+ " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor
+ " Java version: " + javaVersion;
logger.log(Level.WARNING, msg, cnfe);
logger.warn(msg, cnfe);
}
if (readWriteDirectByteBufferClass != null)
deallocatableBufferClassSet.add(readWriteDirectByteBufferClass);
@@ -632,7 +636,7 @@ public class DeallocationHelper {
final String msg = "The class " + readOnlyDirectByteBufferClassName
+ " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor
+ " Java version: " + javaVersion;
logger.log(Level.WARNING, msg, cnfe);
logger.warn(msg, cnfe);
}
if (readOnlyDirectByteBufferClass != null)
deallocatableBufferClassSet.add(readOnlyDirectByteBufferClass);
@@ -644,7 +648,7 @@ public class DeallocationHelper {
final String msg = "The class " + readWriteDirectByteBufferClassName
+ " hasn't been found while initializing the deallocator. Java vendor: " + javaVendor
+ " Java version: " + javaVersion;
logger.log(Level.WARNING, msg, cnfe);
logger.warn(msg, cnfe);
}
if (readWriteDirectByteBufferClass != null)
deallocatableBufferClassSet.add(readWriteDirectByteBufferClass);
@@ -730,7 +734,7 @@ public class DeallocationHelper {
// deallocatable buffer
deallocatableDirectByteBuffer = null;
final String bufferClassName = bufferClass.getName();
logger.warning("No deallocatable buffer has been found for an instance of the class "
logger.warn("No deallocatable buffer has been found for an instance of the class "
+ bufferClassName + " whereas it is a direct NIO buffer");
}
} else {// the passed buffer contains another buffer, looks for a

View File

@@ -188,7 +188,7 @@ public class RRDFile implements Constants {
if(this.debug) {
System.out.println(value);
}
return (int)value;
return value;
}
String readString(int maxLength) throws IOException, RrdException {

View File

@@ -86,6 +86,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>

View File

@@ -130,6 +130,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.j.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>
@@ -302,6 +304,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.w.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</war>
</target>

View File

@@ -172,6 +172,23 @@ public class NewsManager implements ClientApp {
return parseNews(newsContent, false);
}
/**
* The initial (welcome to i2p) news
*
* @return entry with first-installed date stamp, or null
* @since 0.9.28
*/
public NewsEntry getInitialNews() {
List<NewsEntry> list = parseInitialNews();
if (list.isEmpty())
return null;
NewsEntry rv = list.get(0);
long installed = _context.getProperty("router.firstInstalled", 0L);
if (installed > 0)
rv.updated = installed;
return rv;
}
private List<NewsEntry> parseInitialNews() {
NewsEntry entry = new NewsEntry();
File file = new File(_context.getBaseDir(), "docs/initialNews/initialNews.xml");

View File

@@ -52,6 +52,7 @@ public class ConfigNetHandler extends FormHandler {
private boolean _udpDisabled;
private String _ipv6Mode;
private boolean _ipv4Firewalled;
private boolean _ipv6Firewalled;
private final Map<String, String> changes = new HashMap<String, String>();
private static final String PROP_HIDDEN = Router.PROP_HIDDEN_HIDDEN; // see Router for other choice
@@ -87,6 +88,9 @@ public class ConfigNetHandler extends FormHandler {
/** @since 0.9.20 */
public void setIPv4Firewalled(String moo) { _ipv4Firewalled = true; }
/** @since 0.9.28 */
public void setIPv6Firewalled(String moo) { _ipv6Firewalled = true; }
public void setHostname(String hostname) {
_hostname = (hostname != null ? hostname.trim() : null);
@@ -366,6 +370,16 @@ public class ConfigNetHandler extends FormHandler {
}
changes.put(TransportUtil.PROP_IPV4_FIREWALLED, "" + _ipv4Firewalled);
if (Boolean.parseBoolean(_context.getProperty(TransportUtil.PROP_IPV6_FIREWALLED)) !=
_ipv6Firewalled) {
if (_ipv6Firewalled)
addFormNotice(_t("Disabling inbound IPv6"));
else
addFormNotice(_t("Enabling inbound IPv6"));
restartRequired = true;
}
changes.put(TransportUtil.PROP_IPV6_FIREWALLED, "" + _ipv6Firewalled);
if (_context.getBooleanPropertyDefaultTrue(TransportManager.PROP_ENABLE_UDP) !=
!_udpDisabled) {
if (_udpDisabled)

View File

@@ -90,6 +90,11 @@ public class ConfigNetHelper extends HelperBase {
return getChecked(TransportUtil.PROP_IPV4_FIREWALLED);
}
/** @since 0.9.28 */
public String getIPv6FirewalledChecked() {
return getChecked(TransportUtil.PROP_IPV6_FIREWALLED);
}
public String getTcpAutoPortChecked(int mode) {
String port = _context.getProperty(PROP_I2NP_NTCP_PORT);
boolean specified = port != null && port.length() > 0;

View File

@@ -31,7 +31,9 @@ public class ConfigStatsHandler extends FormHandler {
@Override
protected void processForm() {
saveChanges();
if (_action != null && _action.equals("foo")) {
saveChanges();
}
}
public void setFilename(String filename) {

View File

@@ -50,9 +50,9 @@ public class HomeHelper extends HelperBase {
_x("FAQ") + S + _x("Frequently Asked Questions") + S + "http://i2p-projekt.i2p/faq" + S + I + "question.png" + S +
_x("Forum") + S + _x("Community forum") + S + "http://forum.i2p/" + S + I + "group.png" + S +
_x("Anonymous Git Hosting") + S + _x("A public anonymous Git hosting site - supports pulling via Git and HTTP and pushing via SSH") + S + "http://git.repo.i2p/" + S + I + "git-logo.png" + S +
"hiddengate.i2p" + S + _x("HiddenGate") + S + "http://hiddengate.i2p/" + S + I + "hglogo32.png" + S +
//"hiddengate.i2p" + S + _x("HiddenGate") + S + "http://hiddengate.i2p/" + S + I + "hglogo32.png" + S +
_x("I2P Wiki") + S + _x("Anonymous wiki - share the knowledge") + S + "http://i2pwiki.i2p/" + S + I + "i2pwiki_logo.png" + S +
"Ident " + _x("Microblog") + S + _x("Your premier microblogging service on I2P") + S + "http://id3nt.i2p/" + S + I + "ident_icon_blue.png" + S +
//"Ident " + _x("Microblog") + S + _x("Your premier microblogging service on I2P") + S + "http://id3nt.i2p/" + S + I + "ident_icon_blue.png" + S +
//_x("Javadocs") + S + _x("Technical documentation") + S + "http://i2p-javadocs.i2p/" + S + I + "education.png" + S +
//"jisko.i2p" + S + _x("Simple and fast microblogging website") + S + "http://jisko.i2p/" + S + I + "jisko_console_icon.png" + S +
//_x("Key Server") + S + _x("OpenPGP Keyserver") + S + "http://keys.i2p/" + S + I + "education.png" + S +
@@ -63,14 +63,14 @@ public class HomeHelper extends HelperBase {
_x("Plugins") + S + _x("Add-on directory") + S + "http://i2pwiki.i2p/index.php?title=Plugins" + S + I + "plugin.png" + S +
_x("Postman's Tracker") + S + _x("Bittorrent tracker") + S + "http://tracker2.postman.i2p/" + S + I + "magnet.png" + S +
_x("Project Website") + S + _x("I2P home page") + S + "http://i2p-projekt.i2p/" + S + I + "info_rhombus.png" + S +
_x("Russian News Feed") + S + "lenta.i2p" + S + "http://lenta.i2p/" + S + I + "lenta_main_logo.png" + S +
//_x("Russian News Feed") + S + "lenta.i2p" + S + "http://lenta.i2p/" + S + I + "lenta_main_logo.png" + S +
//"Salt" + S + "salt.i2p" + S + "http://salt.i2p/" + S + I + "salt_console.png" + S +
"stats.i2p" + S + _x("I2P Network Statistics") + S + "http://stats.i2p/cgi-bin/dashboard.cgi" + S + I + "chart_line.png" + S +
_x("Technical Docs") + S + _x("Technical documentation") + S + "http://i2p-projekt.i2p/how" + S + I + "education.png" + S +
_x("The Tin Hat") + S + _x("Privacy guides and tutorials") + S + "http://secure.thetinhat.i2p/" + S + I + "thetinhat.png" + S +
_x("Trac Wiki") + S + S + "http://trac.i2p2.i2p/" + S + I + "billiard_marker.png" + S +
//_x("Ugha's Wiki") + S + S + "http://ugha.i2p/" + S + I + "billiard_marker.png" + S +
_x("Sponge's main site") + S + _x("Seedless and the Robert BitTorrent applications") + S + "http://sponge.i2p/" + S + I + "user_astronaut.png" + S +
//_x("Sponge's main site") + S + _x("Seedless and the Robert BitTorrent applications") + S + "http://sponge.i2p/" + S + I + "user_astronaut.png" + S +
"";

View File

@@ -7,6 +7,7 @@ public class NetDbHelper extends HelperBase {
private String _routerPrefix;
private String _version;
private String _country;
private String _family;
private int _full;
private boolean _lease;
private boolean _debug;
@@ -49,6 +50,12 @@ public class NetDbHelper extends HelperBase {
_country = DataHelper.stripHTML(c); // XSS
}
/** @since 0.9.28 */
public void setFamily(String c) {
if (c != null)
_family = DataHelper.stripHTML(c); // XSS
}
public void setFull(String f) {
try {
_full = Integer.parseInt(f);
@@ -75,8 +82,8 @@ public class NetDbHelper extends HelperBase {
NetDbRenderer renderer = new NetDbRenderer(_context);
try {
renderNavBar();
if (_routerPrefix != null || _version != null || _country != null)
renderer.renderRouterInfoHTML(_out, _routerPrefix, _version, _country);
if (_routerPrefix != null || _version != null || _country != null || _family != null)
renderer.renderRouterInfoHTML(_out, _routerPrefix, _version, _country, _family);
else if (_lease)
renderer.renderLeaseSetHTML(_out, _debug);
else if (_full == 3)

View File

@@ -85,8 +85,10 @@ class NetDbRenderer {
* @param routerPrefix may be null. "." for our router only
* @param version may be null
* @param country may be null
* @param family may be null
*/
public void renderRouterInfoHTML(Writer out, String routerPrefix, String version, String country) throws IOException {
public void renderRouterInfoHTML(Writer out, String routerPrefix, String version,
String country, String family) throws IOException {
StringBuilder buf = new StringBuilder(4*1024);
if (".".equals(routerPrefix)) {
renderRouterInfo(buf, _context.router().getRouterInfo(), true, true);
@@ -97,7 +99,8 @@ class NetDbRenderer {
Hash key = ri.getIdentity().getHash();
if ((routerPrefix != null && key.toBase64().startsWith(routerPrefix)) ||
(version != null && version.equals(ri.getVersion())) ||
(country != null && country.equals(_context.commSystem().getCountry(key)))) {
(country != null && country.equals(_context.commSystem().getCountry(key))) ||
(family != null && family.equals(ri.getOption("family")))) {
renderRouterInfo(buf, ri, false, true);
notFound = false;
}
@@ -110,6 +113,8 @@ class NetDbRenderer {
buf.append(version);
else if (country != null)
buf.append(country);
else if (family != null)
buf.append(_t("Family")).append(' ').append(family);
buf.append(' ').append(_t("not found in network database"));
}
}

View File

@@ -50,8 +50,18 @@ public class NewsFeedHelper extends HelperBase {
ClientAppManager cmgr = ctx.clientAppManager();
if (cmgr != null) {
NewsManager nmgr = (NewsManager) cmgr.getRegisteredApp(NewsManager.APP_NAME);
if (nmgr != null)
if (nmgr != null) {
entries = nmgr.getEntries();
NewsEntry init = nmgr.getInitialNews();
if (init != null) {
// crude check to see if it's already in there
if (entries.size() != 1 || !DataHelper.eq(entries.get(0).title, init.title))
if (entries.isEmpty())
entries = Collections.singletonList(init); // in case it was an emtpyList
else
entries.add(init);
}
}
}
if (!entries.isEmpty()) {
DateFormat fmt = DateFormat.getDateInstance(DateFormat.SHORT);

View File

@@ -48,6 +48,7 @@ import org.eclipse.jetty.server.AbstractConnector;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.NCSARequestLog;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.server.bio.SocketConnector;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.DefaultHandler;
@@ -848,7 +849,8 @@ public class RouterConsoleRunner implements RouterApp {
enable = false;
ctx.router().saveConfig(PROP_CONSOLE_PW, "false");
} else {
HashLoginService realm = new HashLoginService(JETTY_REALM);
HashLoginService realm = new CustomHashLoginService(JETTY_REALM, context.getContextPath(),
ctx.logManager().getLog(RouterConsoleRunner.class));
sec.setLoginService(realm);
sec.setAuthenticator(authenticator);
String[] role = new String[] {JETTY_ROLE};
@@ -932,6 +934,30 @@ public class RouterConsoleRunner implements RouterApp {
context.setSecurityHandler(sec);
}
/**
* For logging authentication failures
* @since 0.9.28
*/
private static class CustomHashLoginService extends HashLoginService {
private final String _webapp;
private final net.i2p.util.Log _log;
public CustomHashLoginService(String realm, String webapp, net.i2p.util.Log log) {
super(realm);
_webapp = webapp;
_log = log;
}
@Override
public UserIdentity login(String username, Object credentials) {
UserIdentity rv = super.login(username, credentials);
if (rv == null)
//_log.logAlways(net.i2p.util.Log.WARN, "Console authentication failed, webapp: " + _webapp + ", user: " + username);
_log.logAlways(net.i2p.util.Log.WARN, "Console authentication failed, user: " + username);
return rv;
}
}
/** @since 0.8.8 */
private class ServerShutdown implements Runnable {
public void run() {

View File

@@ -4,6 +4,7 @@ import java.io.IOException;
import java.io.Serializable;
import java.io.Writer;
import java.math.BigInteger;
import java.text.Collator;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
@@ -24,6 +25,7 @@ import net.i2p.data.router.RouterInfo;
import net.i2p.data.router.RouterKeyGenerator;
import net.i2p.router.RouterContext;
import net.i2p.router.TunnelPoolSettings;
import net.i2p.router.crypto.FamilyKeyCrypto;
import net.i2p.router.peermanager.DBHistory;
import net.i2p.router.peermanager.PeerProfile;
import net.i2p.router.tunnel.pool.TunnelPool;
@@ -61,6 +63,8 @@ class SybilRenderer {
private static final double POINTS_US24 = 25.0;
private static final double POINTS_US16 = 10.0;
private static final double POINTS_FAMILY = -2.0;
private static final double POINTS_BAD_OUR_FAMILY = 100.0;
private static final double POINTS_OUR_FAMILY = -100.0;
private static final double MIN_CLOSE = 242.0;
private static final double PAIR_DISTANCE_FACTOR = 2.0;
private static final double OUR_KEY_FACTOR = 4.0;
@@ -370,6 +374,7 @@ class SybilRenderer {
private static class FoofComparator implements Comparator<String>, Serializable {
private final ObjectCounter<String> _o;
private final Collator _comp = Collator.getInstance();
public FoofComparator(ObjectCounter<String> o) { _o = o;}
public int compare(String l, String r) {
// reverse by count
@@ -377,7 +382,7 @@ class SybilRenderer {
if (rv != 0)
return rv;
// foward by name
return l.compareTo(r);
return _comp.compare(l, r);
}
}
@@ -578,11 +583,14 @@ class SybilRenderer {
}
List<String> foo = new ArrayList<String>(oc.objects());
Collections.sort(foo, new FoofComparator(oc));
FamilyKeyCrypto fkc = _context.router().getFamilyKeyCrypto();
String ourFamily = fkc != null ? fkc.getOurFamilyName() : null;
boolean found = false;
for (String s : foo) {
int count = oc.count(s);
buf.append("<p><b>").append(count).append(" floodfills in declared family \"").append(DataHelper.escapeHTML(s) + '"')
.append("</b></p>");
String ss = DataHelper.escapeHTML(s);
buf.append("<p><b>").append(count).append(" floodfills in declared family \"<a href=\"/netdb?fam=")
.append(ss).append("\">").append(ss).append("</a>\"</b></p>");
for (RouterInfo info : ris) {
String fam = info.getOption("family");
if (fam == null)
@@ -593,10 +601,16 @@ class SybilRenderer {
// limit display
//renderRouterInfo(buf, info, null, false, false);
double point = POINTS_FAMILY;
if (count > 1)
if (fkc != null && s.equals(ourFamily)) {
if (fkc.verifyOurFamily(info))
addPoints(points, info.getHash(), POINTS_OUR_FAMILY, "Our family \"" + DataHelper.escapeHTML(s) + "\" with " + (count - 1) + " other" + (( count > 2) ? "s" : ""));
else
addPoints(points, info.getHash(), POINTS_BAD_OUR_FAMILY, "Spoofed our family \"" + DataHelper.escapeHTML(s) + "\" with " + (count - 1) + " other" + (( count > 2) ? "s" : ""));
} else if (count > 1) {
addPoints(points, info.getHash(), point, "Same declared family \"" + DataHelper.escapeHTML(s) + "\" with " + (count - 1) + " other" + (( count > 2) ? "s" : ""));
else
} else {
addPoints(points, info.getHash(), point, "Declared family \"" + DataHelper.escapeHTML(s) + '"');
}
}
}
if (!found)

View File

@@ -56,6 +56,8 @@
<%=intl._t("Disable inbound (Firewalled by Carrier-grade NAT or DS-Lite)")%>
</p><p>
<%=intl._t("IPv6 Configuration")%>:<br>
<input type="checkbox" class="optbox" name="IPv6Firewalled" value="true" <jsp:getProperty name="nethelper" property="IPv6FirewalledChecked" /> >
<%=intl._t("Disable inbound (Firewalled by Carrier-grade NAT or DS-Lite)")%><br>
<input type="radio" class="optbox" name="ipv6" value="false" <%=nethelper.getIPv6Checked("false") %> >
<%=intl._t("Disable IPv6")%><br>
<input type="radio" class="optbox" name="ipv6" value="enable" <%=nethelper.getIPv6Checked("enable") %> >

View File

@@ -25,5 +25,6 @@
<jsp:setProperty name="netdbHelper" property="lease" value="<%=request.getParameter(\"l\")%>" />
<jsp:setProperty name="netdbHelper" property="version" value="<%=request.getParameter(\"v\")%>" />
<jsp:setProperty name="netdbHelper" property="country" value="<%=request.getParameter(\"c\")%>" />
<jsp:setProperty name="netdbHelper" property="family" value="<%=request.getParameter(\"fam\")%>" />
<jsp:getProperty name="netdbHelper" property="netDbSummary" />
</div></div></body></html>

View File

@@ -77,6 +77,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>

View File

@@ -91,14 +91,23 @@ class SAMHandlerFactory {
if (Boolean.parseBoolean(i2cpProps.getProperty(SAMBridge.PROP_AUTH))) {
String user = props.getProperty("USER");
String pw = props.getProperty("PASSWORD");
if (user == null || pw == null)
if (user == null || pw == null) {
if (user == null)
log.logAlways(Log.WARN, "SAM authentication failed");
else
log.logAlways(Log.WARN, "SAM authentication failed, user: " + user);
throw new SAMException("USER and PASSWORD required");
}
String savedPW = i2cpProps.getProperty(SAMBridge.PROP_PW_PREFIX + user + SAMBridge.PROP_PW_SUFFIX);
if (savedPW == null)
if (savedPW == null) {
log.logAlways(Log.WARN, "SAM authentication failed, user: " + user);
throw new SAMException("Authorization failed");
}
PasswordManager pm = new PasswordManager(I2PAppContext.getGlobalContext());
if (!pm.checkHash(savedPW, pw))
if (!pm.checkHash(savedPW, pw)) {
log.logAlways(Log.WARN, "SAM authentication failed, user: " + user);
throw new SAMException("Authorization failed");
}
}
// Let's answer positively

View File

@@ -213,6 +213,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>

View File

@@ -117,6 +117,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</war>
</target>

View File

@@ -81,6 +81,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</war>
</target>

View File

@@ -87,6 +87,7 @@ public class WebMail extends HttpServlet
private static final int version = 13;
private static final long serialVersionUID = 1L;
private static final String LOGIN_NONCE = Long.toString(I2PAppContext.getGlobalContext().random().nextLong());
private static final String DEFAULT_HOST = "127.0.0.1";
private static final int DEFAULT_POP3PORT = 7660;
@@ -466,6 +467,8 @@ public class WebMail extends HttpServlet
/** @since 0.9.27 */
public boolean isValidNonce(String nonce) {
if (state == STATE_AUTH && LOGIN_NONCE.equals(nonce))
return true;
synchronized(nonces) {
return nonces.contains(nonce);
}
@@ -856,7 +859,7 @@ public class WebMail extends HttpServlet
}
sessionObject.info += _t("User logged out.") + '\n';
sessionObject.state = STATE_AUTH;
} else if( sessionObject.mailbox == null ) {
} else if( sessionObject.mailbox == null && !buttonPressed(request, CANCEL)) {
sessionObject.error += _t("Internal error, lost connection.") + '\n';
sessionObject.state = STATE_AUTH;
}
@@ -878,7 +881,7 @@ public class WebMail extends HttpServlet
if( sessionObject.state == STATE_AUTH && isPOST )
processLogin( sessionObject, request );
if( sessionObject.state != STATE_AUTH && sessionObject.state != STATE_CONFIG )
if( sessionObject.state != STATE_AUTH )
processLogout( sessionObject, request, isPOST );
/*
@@ -1797,7 +1800,8 @@ public class WebMail extends HttpServlet
out.println("<script src=\"/susimail/js/folder.js\" type=\"text/javascript\"></script>");
}
out.print("</head>\n<body" + (sessionObject.state == STATE_LIST ? " onload=\"deleteboxclicked()\">" : ">"));
String nonce = Long.toString(ctx.random().nextLong());
String nonce = sessionObject.state == STATE_AUTH ? LOGIN_NONCE :
Long.toString(ctx.random().nextLong());
sessionObject.addNonce(nonce);
out.println(
"<div class=\"page\"><div class=\"header\"><img class=\"header\" src=\"" + sessionObject.imgPath + "susimail.png\" alt=\"Susimail\"></div>\n" +
@@ -2409,6 +2413,7 @@ public class WebMail extends HttpServlet
out.println(button2(DELETE, _t("Delete")));
else
out.println(button(DELETE, _t("Delete")));
out.println(spacer + button(LOGOUT, _t("Logout") ));
out.println("<br>" +
( sessionObject.folder.isFirstElement( sessionObject.showUIDL ) ? button2( PREV, _t("Previous") ) : button( PREV, _t("Previous") ) ) + spacer +
button( LIST, _t("Back to Folder") ) + spacer +
@@ -2416,7 +2421,6 @@ public class WebMail extends HttpServlet
out.println("</div>");
//if (Config.hasConfigFile())
// out.println(button( RELOAD, _t("Reload Config") ) + spacer);
//out.println(button( LOGOUT, _t("Logout") ) );
if( mail != null ) {
out.println( "<table cellspacing=\"0\" cellpadding=\"5\">\n" +
"<tr><td colspan=\"2\" align=\"center\"><hr></td></tr>\n" +
@@ -2473,6 +2477,8 @@ public class WebMail extends HttpServlet
out.println("<br>");
out.println(button(SAVE, _t("Save Configuration")));
out.println(button(CANCEL, _t("Cancel")));
if (sessionObject.folder != null)
out.println(spacer + button(LOGOUT, _t("Logout") ));
out.println("</div>");
}

View File

@@ -65,6 +65,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>

View File

@@ -400,7 +400,7 @@
<copy file="core/java/build/i2p.jar" todir="build/" />
</target>
<target name="buildJrobin" depends="buildProperties" >
<target name="buildJrobin" depends="buildCore" >
<ant dir="apps/jrobin/java/" target="jar" />
<copy file="apps/jrobin/java/build/jrobin.jar" todir="build/" />
</target>
@@ -1184,7 +1184,7 @@
</target>
<!-- see targets below for conditional copying -->
<target name="preppkg-base" depends="build, preplicenses, prepConsoleDocs, prepthemeupdates, prepCertificates, prepRouterInfos, copyjetty, copytomcat-unlesspkg, copyjstl-unlesspkg, copystandard-unlesspkg">
<target name="preppkg-base" depends="build, preplicenses, prepConsoleDocs, prepthemeupdates, prepCertificates, prepRouterInfos, copyjetty, copytomcat-unlesspkg, copyjstl-unlesspkg, copystandard-unlesspkg, truncatehistory">
<!-- if updater200 was run previously, it left *.pack files in pkg-temp -->
<!-- Also remove deletelist.txt used for updater only -->
<delete>
@@ -1218,8 +1218,6 @@
<copy file="installer/resources/wrapper.config" todir="pkg-temp/" />
<copy file="installer/resources/hosts.txt" todir="pkg-temp/" />
<copy file="INSTALL-headless.txt" todir="pkg-temp/" />
<!-- overwrite the truncated history put in by the updater -->
<copy file="history.txt" todir="pkg-temp/" overwrite="true" />
<mkdir dir="pkg-temp/scripts" />
<copy file="apps/proxyscript/i2pProxy.pac" todir="pkg-temp/scripts/" />
<copy file="apps/apparmor/home.i2p.i2prouter" todir="pkg-temp/scripts/" />
@@ -1506,7 +1504,7 @@
</exec>
</target>
<target name="prepupdate" depends="build2, prepupdateSmall, prepConsoleDocUpdates, prepCertificates, prep-script-translation">
<target name="prepupdate" depends="build2, prepupdateSmall, prepConsoleDocUpdates, prepCertificates, prep-script-translation, truncatehistory">
<copy file="build/BOB.jar" todir="pkg-temp/lib/" />
<copy file="build/sam.jar" todir="pkg-temp/lib/" />
<copy file="build/i2psnark.jar" todir="pkg-temp/lib" />
@@ -1523,6 +1521,14 @@
<copy file="apps/susidns/src/lib/standard.jar" todir="pkg-temp/lib/" />
-->
<copy file="build/i2psnark.war" todir="pkg-temp/webapps/" />
<copy file="installer/resources/deletelist.txt" todir="pkg-temp/" />
<copy file="installer/resources/blocklist.txt" todir="pkg-temp/" />
<copy todir="pkg-temp/man/">
<fileset dir="installer/resources/man/" />
</copy>
</target>
<target name="truncatehistory">
<copy file="history.txt" todir="pkg-temp/" />
<!-- the following overwrites history.txt on unix to shrink the update file -->
<copy file="history.txt" tofile="pkg-temp/history.txt" overwrite="true">
@@ -1530,12 +1536,7 @@
<headfilter lines="1500" />
</filterchain>
</copy>
<concat append="true" destfile="pkg-temp/history.txt">&#10;&#10;----------------&#10;&#10;EARLIER HISTORY IS AVAILABLE IN THE SOURCE PACKAGE"</concat>
<copy file="installer/resources/deletelist.txt" todir="pkg-temp/" />
<copy file="installer/resources/blocklist.txt" todir="pkg-temp/" />
<copy todir="pkg-temp/man/">
<fileset dir="installer/resources/man/" />
</copy>
<concat append="true" destfile="pkg-temp/history.txt">&#10;&#10;----------------&#10;&#10;EARLIER HISTORY IS AVAILABLE IN THE SOURCE PACKAGE</concat>
</target>
<target name="prepupdateSmall" depends="buildSmall, prepupdateRouter, prepjupdatefixes, prepthemeupdates">

View File

@@ -108,6 +108,8 @@
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Main-Class" value="net.i2p.util.CommandLine" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>

View File

@@ -9,6 +9,7 @@ package net.i2p.client.impl;
*
*/
import java.io.EOFException;
import java.security.GeneralSecurityException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -185,7 +186,16 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
} catch (DataFormatException dfe) {
session.propogateError("Error signing the leaseSet", dfe);
} catch (I2PSessionException ise) {
session.propogateError("Error sending the signed leaseSet", ise);
if (session.isClosed()) {
// race, closed while signing leaseset
// EOFExceptions are logged at WARN level (see I2PSessionImpl.propogateError())
// so the user won't see this
EOFException eof = new EOFException("Session closed while signing leaseset");
eof.initCause(ise);
session.propogateError("Session closed while signing leaseset", eof);
} else {
session.propogateError("Error sending the signed leaseSet", ise);
}
}
}

View File

@@ -535,8 +535,6 @@ public final class CertUtil {
}
/****
public static final void main(String[] args) {
if (args.length < 2) {
System.out.println("Usage: [loadcert | loadcrl | loadcrldir | loadcrldirs | isrevoked | loadprivatekey] file");
@@ -545,7 +543,8 @@ public final class CertUtil {
try {
File f = new File(args[1]);
if (args[0].equals("loadcert")) {
loadCert(f);
X509Certificate cert = loadCert(f);
System.out.println(net.i2p.util.HexDump.dump(cert.getEncoded()));
} else if (args[0].equals("loadcrl")) {
loadCRL(f);
} else if (args[0].equals("loadcrldir")) {
@@ -569,5 +568,4 @@ public final class CertUtil {
System.exit(1);
}
}
****/
}

View File

@@ -264,11 +264,11 @@ public final class SelfSignedGenerator {
// a0 ???, int = 2
byte[] version = { (byte) 0xa0, 3, 2, 1, 2 };
// postive serial number (int)
byte[] serial = new byte[6];
// positive serial number (long)
byte[] serial = new byte[10];
serial[0] = 2;
serial[1] = 4;
RandomSource.getInstance().nextBytes(serial, 2, 4);
serial[1] = 8;
RandomSource.getInstance().nextBytes(serial, 2, 8);
serial[2] &= 0x7f;
// going to use this for both issuer and subject

View File

@@ -2,7 +2,7 @@ package net.i2p.crypto.eddsa.math;
import net.i2p.crypto.eddsa.Utils;
public class Constants {
final class Constants {
public static final byte[] ZERO = Utils.hexToBytes("0000000000000000000000000000000000000000000000000000000000000000");
public static final byte[] ONE = Utils.hexToBytes("0100000000000000000000000000000000000000000000000000000000000000");
public static final byte[] TWO = Utils.hexToBytes("0200000000000000000000000000000000000000000000000000000000000000");

View File

@@ -4,14 +4,21 @@ package net.i2p.util;
* public domain
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -21,6 +28,8 @@ import java.util.TreeSet;
import org.apache.http.conn.util.InetAddressUtils;
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
/**
* Methods to get the local addresses, and other IP utilities
@@ -30,6 +39,16 @@ import net.i2p.I2PAppContext;
*/
public abstract class Addresses {
private static final File IF_INET6_FILE = new File("/proc/net/if_inet6");
private static final long INET6_CACHE_EXPIRE = 10*60*1000;
private static final boolean INET6_CACHE_ENABLED = !SystemVersion.isMac() && !SystemVersion.isWindows() &&
!SystemVersion.isAndroid() && IF_INET6_FILE.exists();
private static final int FLAG_PERMANENT = 0x80;
private static final int FLAG_DEPRECATED = 0x20;
private static final int FLAG_TEMPORARY = 0x01;
private static long _ifCacheTime;
private static final Map<Inet6Address, Inet6Addr> _ifCache = INET6_CACHE_ENABLED ? new HashMap<Inet6Address, Inet6Addr>(8) : null;
/**
* Do we have any non-loop, non-wildcard IPv4 address at all?
* @since 0.9.4
@@ -101,18 +120,25 @@ public abstract class Addresses {
boolean haveIPv4 = false;
boolean haveIPv6 = false;
SortedSet<String> rv = new TreeSet<String>();
final boolean omitDeprecated = INET6_CACHE_ENABLED && !includeSiteLocal && includeIPv6;
try {
InetAddress localhost = InetAddress.getLocalHost();
InetAddress[] allMyIps = InetAddress.getAllByName(localhost.getCanonicalHostName());
if (allMyIps != null) {
for (int i = 0; i < allMyIps.length; i++) {
if (allMyIps[i] instanceof Inet4Address)
boolean isv4 = allMyIps[i] instanceof Inet4Address;
if (isv4)
haveIPv4 = true;
else
haveIPv6 = true;
if (omitDeprecated && !isv4) {
if (isDeprecated((Inet6Address) allMyIps[i]))
continue;
}
if (shouldInclude(allMyIps[i], includeSiteLocal,
includeLoopbackAndWildcard, includeIPv6))
includeLoopbackAndWildcard, includeIPv6)) {
rv.add(stripScope(allMyIps[i].getHostAddress()));
}
}
}
} catch (UnknownHostException e) {}
@@ -124,13 +150,19 @@ public abstract class Addresses {
NetworkInterface ifc = ifcs.nextElement();
for(Enumeration<InetAddress> addrs = ifc.getInetAddresses(); addrs.hasMoreElements();) {
InetAddress addr = addrs.nextElement();
if (addr instanceof Inet4Address)
boolean isv4 = addr instanceof Inet4Address;
if (isv4)
haveIPv4 = true;
else
haveIPv6 = true;
if (omitDeprecated && !isv4) {
if (isDeprecated((Inet6Address) addr))
continue;
}
if (shouldInclude(addr, includeSiteLocal,
includeLoopbackAndWildcard, includeIPv6))
includeLoopbackAndWildcard, includeIPv6)) {
rv.add(stripScope(addr.getHostAddress()));
}
}
}
}
@@ -333,8 +365,8 @@ public abstract class Addresses {
/**
* For literal IP addresses, this is the same as getIP(String).
* For host names, will return the preferred type (IPv4/v6) if available,
* else the other type if available.
* For host names, may return multiple addresses, both IPv4 and IPv6,
* even if those addresses are not reachable due to configuration or available interfaces.
* Will resolve but not cache DNS host names.
*
* Note that order of returned results, and whether
@@ -370,6 +402,136 @@ public abstract class Addresses {
return null;
}
//////// IPv6 Cache Utils ///////
/**
* @since 0.9.28
*/
private static class Inet6Addr {
private final Inet6Address addr;
private final boolean isDyn, isDep, isTemp;
public Inet6Addr(Inet6Address a, int flags) {
addr = a;
isDyn = (flags & FLAG_PERMANENT) == 0;
isDep = (flags & FLAG_DEPRECATED) != 0;
isTemp = (flags & FLAG_TEMPORARY) != 0;
}
public Inet6Address getAddress() { return addr; }
public boolean isDynamic() { return isDyn; }
public boolean isDeprecated() { return isDep; }
public boolean isTemporary() { return isTemp; }
}
/**
* Only call if INET6_CACHE_ENABLED.
* Caller must sync on _ifCache.
* @since 0.9.28
*/
private static void refreshCache() {
long now = System.currentTimeMillis();
if (now - _ifCacheTime < INET6_CACHE_EXPIRE)
return;
_ifCache.clear();
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(new FileInputStream(IF_INET6_FILE), "ISO-8859-1"), 4096);
String line = null;
while ( (line = in.readLine()) != null) {
// http://tldp.org/HOWTO/html_single/Linux+IPv6-HOWTO/#PROC-NET
// 00000000000000000000000000000001 01 80 10 80 lo
String[] parts = DataHelper.split(line, " ", 6);
if (parts.length < 5)
continue;
String as = parts[0];
if (as.length() != 32)
continue;
StringBuilder buf = new StringBuilder(40);
int i = 0;
while(true) {
buf.append(as.substring(i, i+4));
i += 4;
if (i >= 32)
break;
buf.append(':');
}
Inet6Address addr;
try {
addr = (Inet6Address) InetAddress.getByName(buf.toString());
} catch (UnknownHostException uhe) {
continue;
}
int flags = FLAG_PERMANENT;
try {
flags = Integer.parseInt(parts[4], 16);
} catch (NumberFormatException nfe) {}
Inet6Addr a = new Inet6Addr(addr, flags);
_ifCache.put(addr, a);
}
} catch (IOException ioe) {
} finally {
if (in != null) try { in.close(); } catch (IOException ioe) {}
}
_ifCacheTime = now;
}
/**
* Is this address dynamic?
* Returns false if unknown.
* @since 0.9.28
*/
public static boolean isDynamic(Inet6Address addr) {
if (!INET6_CACHE_ENABLED)
return false;
Inet6Addr a;
synchronized(_ifCache) {
refreshCache();
a = _ifCache.get(addr);
}
if (a == null)
return false;
return a.isDynamic();
}
/**
* Is this address deprecated?
* Returns false if unknown.
* @since 0.9.28
*/
public static boolean isDeprecated(Inet6Address addr) {
if (!INET6_CACHE_ENABLED)
return false;
Inet6Addr a;
synchronized(_ifCache) {
refreshCache();
a = _ifCache.get(addr);
}
if (a == null)
return false;
return a.isDeprecated();
}
/**
* Is this address temporary?
* Returns false if unknown.
* @since 0.9.28
*/
public static boolean isTemporary(Inet6Address addr) {
if (!INET6_CACHE_ENABLED)
return false;
Inet6Addr a;
synchronized(_ifCache) {
refreshCache();
a = _ifCache.get(addr);
}
if (a == null)
return false;
return a.isTemporary();
}
//////// End IPv6 Cache Utils ///////
/**
* @since 0.9.3
*/
@@ -377,32 +539,66 @@ public abstract class Addresses {
synchronized(_IPAddress) {
_IPAddress.clear();
}
if (_ifCache != null) {
synchronized(_ifCache) {
_ifCache.clear();
_ifCacheTime = 0;
}
}
}
/**
* Print out the local addresses
*/
public static void main(String[] args) {
System.err.println("External IPv4 Addresses:");
System.out.println("External IPv4 Addresses:");
Set<String> a = getAddresses(false, false, false);
for (String s : a)
System.err.println(s);
System.err.println("\nExternal and Local IPv4 Addresses:");
System.out.println(s);
System.out.println("\nExternal and Local IPv4 Addresses:");
a = getAddresses(true, false, false);
for (String s : a)
System.err.println(s);
System.err.println("\nAll External Addresses:");
System.out.println(s);
System.out.println("\nAll External Addresses:");
a = getAddresses(false, false, true);
for (String s : a)
System.err.println(s);
System.err.println("\nAll External and Local Addresses:");
System.out.println(s);
System.out.println("\nAll External and Local Addresses:");
a = getAddresses(true, false, true);
for (String s : a)
System.err.println(s);
System.err.println("\nAll addresses:");
System.out.println(s);
System.out.println("\nAll addresses:");
a = getAddresses(true, true, true);
for (String s : a)
System.err.println(s);
System.err.println("\nIs connected? " + isConnected());
System.out.println(s);
System.out.println("\nIPv6 address flags:");
for (String s : a) {
if (!s.contains(":"))
continue;
StringBuilder buf = new StringBuilder(64);
buf.append(s);
Inet6Address addr;
try {
addr = (Inet6Address) InetAddress.getByName(buf.toString());
if (addr.isSiteLocalAddress())
buf.append(" host");
else if (addr.isLinkLocalAddress())
buf.append(" link");
else if (addr.isAnyLocalAddress())
buf.append(" wildcard");
else if (addr.isLoopbackAddress())
buf.append(" loopback");
else
buf.append(" global");
if (isTemporary(addr))
buf.append(" temporary");
if (isDeprecated(addr))
buf.append(" deprecated");
if (isDynamic(addr))
buf.append(" dynamic");
} catch (UnknownHostException uhe) {}
System.out.println(buf.toString());
}
System.out.println("\nIs connected? " + isConnected());
}
}

View File

@@ -22,6 +22,7 @@ public class CommandLine {
"freenet.support.CPUInformation.CPUID",
"net.i2p.CoreVersion",
"net.i2p.client.naming.BlockfileNamingService",
"net.i2p.crypto.CertUtil",
"net.i2p.crypto.CryptoCheck",
"net.i2p.crypto.SU3File",
"net.i2p.crypto.TrustedUpdate",

View File

@@ -29,6 +29,7 @@ abstract class LogWriter implements Runnable {
protected volatile boolean _write;
private LogRecord _last;
private long _firstTimestamp;
// ms
private volatile long _flushInterval = FLUSH_INTERVAL;
@@ -95,7 +96,7 @@ abstract class LogWriter implements Runnable {
Queue<LogRecord> records = _manager.getQueue();
if (records == null) return;
if (!records.isEmpty()) {
if (_last != null && _last.getDate() < _manager.getContext().clock().now() - 30*60*1000)
if (_last != null && _firstTimestamp < _manager.getContext().clock().now() - 30*60*1000)
_last = null;
LogRecord rec;
int dupCount = 0;
@@ -108,6 +109,7 @@ abstract class LogWriter implements Runnable {
dupCount = 0;
}
writeRecord(rec);
_firstTimestamp = rec.getDate();
}
_last = rec;
}

View File

@@ -34,8 +34,7 @@ public abstract class SystemVersion {
private static final boolean _isOpenJDK;
private static final boolean _is64;
private static final boolean _hasWrapper = System.getProperty("wrapper.version") != null;
private static final boolean _isLinuxService = !_isWin && !_isMac &&
DAEMON_USER.equals(System.getProperty("user.name"));
private static final boolean _isLinuxService;
private static final boolean _oneDotSix;
private static final boolean _oneDotSeven;
@@ -63,6 +62,8 @@ public abstract class SystemVersion {
vendor.startsWith("Free Software Foundation"); // gij
String runtime = System.getProperty("java.runtime.name");
_isOpenJDK = runtime != null && runtime.contains("OpenJDK");
_isLinuxService = !_isWin && !_isMac && !_isAndroid &&
DAEMON_USER.equals(System.getProperty("user.name"));
int sdk = 0;
if (_isAndroid) {

View File

@@ -1,3 +1,69 @@
2016-11-16 zzz
* Console: Remove dead home page links (ticket #1882)
* Profiles: Pull same-IP detection into a utility class
* Router: Add methods to verify and track members of our family
2016-11-15 zzz
* Certs: Add Let's Encrypt ISRG Root X1 cert
2016-11-14 zzz
* Logs: Fix output of dup message after 30 minutes
2016-11-13 zzz
* Console: Add initial news to bottom of news page (ticket #1153)
* i2psnark: Periodically DHT nodes (ticket #1328)
* UPnP:
- Prevent exception on bad HTTP header (ticket #1480)
- Prevent NPE on socket creation fail (tickets #728, #1681)
2016-11-12 zzz
* Console:
- Fix inadvertent config save when clicking sidebar
buttons on /configstats
- Add IPv6 firewalled setting on /confignet
* I2CP: Reduce error level on session closed while signing LS (ticket #1606)
* JRobin: Move DeallocationHelper logging from wrapper log to router log
* Profiles: Periodically save, delete old ones after saving (ticket #1328)
* Susimail:
- Add logout button to more pages (ticket #1374)
- Fix nonce error on login after logout
- Fix internal error after cancel button on settings form when not logged in
2016-11-11 zzz
* Build: Truncate history.txt bundled in installers
2016-11-10 zzz
* Transport: Use NTCP for some outbound connections even before
SSU minimums are met (ticket #1835)
2016-11-09 zzz
* Transport: Add stats for inbound v4/v6 connections (ticket #1854)
* Tunnels: Reduce default VTBM records from 5 to 4
2016-11-08 zzz
* Build: Fix minimum Java version for Windows
* Install: Add max memory option to runplain.sh
* Crypto: Change serial number in selfsigned certs from int to long
* Router: Fix low-memory log messages for non-wrapper (ticket #1795)
* Transport: Improve IPv6 selection logic
2016-11-06 zzz
* Console: Add Java 9 log warning (ticket #1870)
* Security: Consistently log authentication failures for all interfaces
* Util: Consolidate linux service detection code
2016-11-05 zzz
* Build: Add support for using libtomcat8-java package
* Console: Add message to ignore InstanceManager warning (ticket #1818)
* SusiDNS: Fix jsp EL syntax error with EL 3.0 (Tomcat 8) (ticket #1870)
2016-11-04 zzz
* Console: Improve handling and logging of webapps that fail to start
* i2psnark: Add launch-i2psnark.bat (ticket #1871)
* Transports:
- New config i2np.allowLocal, fixes test networks (ticket #1875)
- New configs i2np.udp.minpeers and i2np.udp.minv6peers, for testing (ticket #1876)
2016-10-29 zzz
* Console: Java 9 fixes for classloader (ticket #1870)
@@ -47,7 +113,7 @@
* Console: Fix HTML error on /configservice
* Debian: Update package descriptions, allow Java 9
* i2psnark: Add ids to rows, add to per-torrent show peers link
* SSU: Fix minimum version check for IPv6 peer test (ticket #1861)
* SSU: Fix minimum version check for IPv6 peer test (tickets #1829, #1861)
* 2016-10-17 0.9.27 released

View File

@@ -7,7 +7,7 @@
<customProcName>false</customProcName>
<icon>resources/console.ico</icon>
<jre>
<minVersion>1.6.0</minVersion>
<minVersion>1.7.0</minVersion>
</jre>
<!--
<splash>

View File

@@ -7,7 +7,7 @@
<customProcName>false</customProcName>
<icon>resources/start.ico</icon>
<jre>
<minVersion>1.6.0</minVersion>
<minVersion>1.7.0</minVersion>
<!--
<minHeapSize>64</minHeapSize>
-->

View File

@@ -57,6 +57,8 @@
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.util.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>

View File

@@ -45,6 +45,10 @@
# * hostname (DNS looked up at list readin time, not dynamically, so may not be much use)
# * 44-byte Base64 router hash
# *
# * Acceptable formats (IPV6 only):
# * comment:IPv6 (must replace : with ; e.g. abcd;1234;0;12;;ff)
# * IPv6 (must replace : with ; e.g. abcd;1234;0;12;;ff)
# *
# * No whitespace allowed after the last ':'.
# *
# * For further information and downloads:

View File

@@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----

View File

@@ -3,7 +3,7 @@
# This runs the router by itself, WITHOUT the wrapper.
# This means the router will not restart if it crashes.
# Also, you will be using the default memory size, which is
# probably not enough for i2p.
# probably not enough for i2p, unless you set it below.
# You should really use the i2prouter script instead.
#
@@ -19,6 +19,10 @@ I2PTEMP="%SYSTEM_java_io_tmpdir"
PREFERv4="false"
CP=
# Uncomment to set the maximum memory. The default and the option may vary in different JVMs.
# Check your java documentation to be sure.
#MAXMEMOPT="-Xmx256m"
# Try using the Java binary that I2P was installed with.
# If it's not found, try looking in the system PATH.
JAVA=$(which %JAVA_HOME/bin/java || which java)
@@ -39,7 +43,7 @@ done
if [ $(uname -s) = "Darwin" ]; then
export JAVA_TOOL_OPTIONS="-Djava.awt.headless=true"
fi
JAVAOPTS="-Djava.net.preferIPv4Stack=${PREFERv4} -Djava.library.path=${I2P}:${I2P}/lib -Di2p.dir.base=${I2P} -DloggerFilenameOverride=logs/log-router-@.txt"
JAVAOPTS="${MAXMEMOPT} -Djava.net.preferIPv4Stack=${PREFERv4} -Djava.library.path=${I2P}:${I2P}/lib -Di2p.dir.base=${I2P} -DloggerFilenameOverride=logs/log-router-@.txt"
(
nohup ${JAVA} -cp \"${CP}\" ${JAVAOPTS} net.i2p.router.RouterLaunch > /dev/null 2>&1
) &

View File

@@ -38,6 +38,8 @@
<attribute name="Built-By" value="${build.built-by}" />
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>

View File

@@ -78,6 +78,8 @@
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Main-Class" value="net.i2p.router.CommandLine" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
<attribute name="X-Compile-Source-JDK" value="${javac.version}" />
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
</manifest>
</jar>
</target>

View File

@@ -248,6 +248,10 @@ public class Blocklist {
* hostname (DNS looked up at list readin time, not dynamically, so may not be much use)
* 44-byte Base64 router hash
*
* Acceptable formats (IPV6 only):
* comment:IPv6 (must replace : with ; e.g. abcd;1234;0;12;;ff)
* IPv6 (must replace : with ; e.g. abcd;1234;0;12;;ff)
*
* No whitespace allowed after the last ':'.
*
* For further information and downloads:
@@ -290,10 +294,14 @@ public class Blocklist {
continue;
}
byte[] ip1 = e.ip1;
byte[] ip2 = e.ip2;
store(ip1, ip2, count++);
ipcount += 1 + toInt(ip2) - toInt(ip1); // includes dups, oh well
if (ip1.length == 4) {
byte[] ip2 = e.ip2;
store(ip1, ip2, count++);
ipcount += 1 + toInt(ip2) - toInt(ip1); // includes dups, oh well
} else {
// IPv6
add(ip1);
}
}
} catch (IOException ioe) {
if (_log.shouldLog(Log.ERROR))
@@ -393,25 +401,25 @@ public class Blocklist {
int start2 = -1;
int mask = -1;
String comment = null;
int index = buf.indexOf("#");
int index = buf.indexOf('#');
if (index == 0)
return null; // comment
index = buf.lastIndexOf(":");
index = buf.lastIndexOf(':');
if (index >= 0) {
comment = buf.substring(0, index);
start1 = index + 1;
}
if (end1 - start1 == 44 && buf.substring(start1).indexOf(".") < 0) {
if (end1 - start1 == 44 && buf.substring(start1).indexOf('.') < 0) {
byte b[] = Base64.decode(buf.substring(start1));
if (b != null)
return new Entry(comment, Hash.create(b), null, null);
}
index = buf.indexOf("-", start1);
index = buf.indexOf('-', start1);
if (index >= 0) {
end1 = index;
start2 = index + 1;
} else {
index = buf.indexOf("/", start1);
index = buf.indexOf('/', start1);
if (index >= 0) {
end1 = index;
mask = index + 1;
@@ -420,11 +428,14 @@ public class Blocklist {
if (end1 - start1 <= 0)
return null; // blank
try {
InetAddress pi = InetAddress.getByName(buf.substring(start1, end1));
String sip = buf.substring(start1, end1);
// IPv6
sip = sip.replace(';', ':');
InetAddress pi = InetAddress.getByName(sip);
if (pi == null) return null;
ip1 = pi.getAddress();
if (ip1.length != 4)
throw new UnknownHostException();
//if (ip1.length != 4)
// throw new UnknownHostException();
if (start2 >= 0) {
pi = InetAddress.getByName(buf.substring(start2));
if (pi == null) return null;
@@ -462,16 +473,16 @@ public class Blocklist {
ip2 = ip1;
}
} catch (UnknownHostException uhe) {
if (shouldLog && _log.shouldLog(Log.ERROR))
_log.error("Format error in the blocklist file: " + buf);
if (shouldLog)
_log.logAlways(Log.WARN, "Format error in the blocklist file: " + buf);
return null;
} catch (NumberFormatException nfe) {
if (shouldLog && _log.shouldLog(Log.ERROR))
_log.error("Format error in the blocklist file: " + buf);
if (shouldLog)
_log.logAlways(Log.WARN, "Format error in the blocklist file: " + buf);
return null;
} catch (IndexOutOfBoundsException ioobe) {
if (shouldLog && _log.shouldLog(Log.ERROR))
_log.error("Format error in the blocklist file: " + buf);
if (shouldLog)
_log.logAlways(Log.WARN, "Format error in the blocklist file: " + buf);
return null;
}
return new Entry(comment, null, ip1, ip2);
@@ -743,6 +754,9 @@ public class Blocklist {
return entry;
}
/**
* IPv4 only
*/
private void store(byte ip1[], byte ip2[], int idx) {
_blocklist[idx] = toEntry(ip1, ip2);
}
@@ -1035,10 +1049,16 @@ public class Blocklist {
}
/****
public static void main(String args[]) {
Blocklist b = new Blocklist();
if ( (args != null) && (args.length == 1) )
b.readBlocklistFile(args[0]);
public static void main(String args[]) throws Exception {
Blocklist b = new Blocklist(new Router().getContext());
if (args != null && args.length == 1) {
File f = new File(args[0]);
b.allocate(Collections.singletonList(f));
int count = b.readBlocklistFile(f, 0);
b.merge(count);
Writer w = new java.io.OutputStreamWriter(System.out);
b.renderStatusHTML(w);
}
System.out.println("Saved " + b._blocklistSize + " records");
String tests[] = {"0.0.0.0", "0.0.0.1", "0.0.0.2", "0.0.0.255", "1.0.0.0",
"3.3.3.3", "77.1.2.3", "127.0.0.0", "127.127.127.127", "128.0.0.0",

View File

@@ -23,7 +23,7 @@ public class CommandLine extends net.i2p.util.CommandLine {
"net.i2p.router.tasks.CryptoChecker",
"net.i2p.router.transport.GeoIPv6",
"net.i2p.router.transport.udp.MTU",
//"net.i2p.router.transport.UPnP"
"net.i2p.router.transport.UPnP"
});
protected CommandLine() {}

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 = 6;
public final static long BUILD = 9;
/** for example "-test" */
public final static String EXTRA = "";

View File

@@ -329,14 +329,14 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
pw = props.getProperty("i2cp.password");
}
if (user == null || user.length() == 0 || pw == null || pw.length() == 0) {
_log.error("I2CP auth failed");
_log.logAlways(Log.WARN, "I2CP authentication failed");
_runner.disconnectClient("Authorization required, specify i2cp.username and i2cp.password in options");
_authorized = false;
return false;
}
PasswordManager mgr = new PasswordManager(_context);
if (!mgr.checkHash(PROP_AUTH, user, pw)) {
_log.error("I2CP auth failed user: " + user);
_log.logAlways(Log.WARN, "I2CP authentication failed, user: " + user);
_runner.disconnectClient("Authorization failed, user = " + user);
_authorized = false;
return false;

View File

@@ -10,6 +10,7 @@ import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.security.cert.X509CRL;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -44,6 +45,7 @@ public class FamilyKeyCrypto {
private final Log _log;
private final Map<Hash, String> _verified;
private final Set<Hash> _negativeCache;
private final Set<Hash> _ourFamily;
// following for verification only, otherwise null
private final String _fname;
private final SigningPrivateKey _privkey;
@@ -82,13 +84,15 @@ public class FamilyKeyCrypto {
_fname = _context.getProperty(PROP_FAMILY_NAME);
if (_fname != null) {
if (_fname.contains("/") || _fname.contains("\\") ||
_fname.contains("..") || (new File(_fname)).isAbsolute())
throw new GeneralSecurityException("Illegal family name");
_fname.contains("..") || (new File(_fname)).isAbsolute() ||
_fname.length() <= 0)
throw new GeneralSecurityException("Illegal family name: " + _fname);
}
_privkey = (_fname != null) ? initialize() : null;
_pubkey = (_privkey != null) ? _privkey.toPublic() : null;
_verified = new ConcurrentHashMap<Hash, String>(4);
_negativeCache = new ConcurrentHashSet<Hash>(4);
_ourFamily = (_privkey != null) ? new ConcurrentHashSet<Hash>(4) : Collections.<Hash>emptySet();
}
/**
@@ -144,6 +148,35 @@ public class FamilyKeyCrypto {
return rv;
}
/**
* Do we have a valid family?
* @since 0.9.28
*/
public boolean hasFamily() {
return _pubkey != null;
}
/**
* Get verified members of our family.
* Will not contain ourselves.
*
* @return non-null, not a copy, do not modify
* @since 0.9.28
*/
public Set<Hash> getOurFamily() {
return _ourFamily;
}
/**
* Get our family name.
*
* @return name or null
* @since 0.9.28
*/
public String getOurFamilyName() {
return _fname;
}
/**
* Verify the family signature in a RouterInfo.
* @return true if good sig or if no family specified at all
@@ -152,6 +185,44 @@ public class FamilyKeyCrypto {
String name = ri.getOption(OPT_NAME);
if (name == null)
return true;
return verify(ri, name);
}
/**
* Verify the family in a RouterInfo matches ours and the signature is good.
* Returns false if we don't have a family and sig, or they don't.
* Returns false for ourselves.
*
* @return true if family matches with good sig
* @since 0.9.28
*/
public boolean verifyOurFamily(RouterInfo ri) {
if (_pubkey == null)
return false;
String name = ri.getOption(OPT_NAME);
if (!_fname.equals(name))
return false;
Hash h = ri.getHash();
if (_ourFamily.contains(h))
return true;
if (h.equals(_context.routerHash()))
return false;
boolean rv = verify(ri, name);
if (rv) {
_ourFamily.add(h);
_log.logAlways(Log.INFO, "Found and verified member of our family (" + _fname + "): " + h);
} else {
if (_log.shouldWarn())
_log.warn("Found spoofed member of our family (" + _fname + "): " + h);
}
return rv;
}
/**
* Verify the family in a RouterInfo, name already retrieved
* @since 0.9.28
*/
private boolean verify(RouterInfo ri, String name) {
Hash h = ri.getHash();
String ssig = ri.getOption(OPT_SIG);
if (ssig == null) {

View File

@@ -19,6 +19,7 @@ import net.i2p.router.MessageSelector;
import net.i2p.router.ReplyJob;
import net.i2p.router.RouterContext;
import net.i2p.router.TunnelInfo;
import net.i2p.router.util.MaskedIPSet;
import net.i2p.util.Log;
/**
@@ -39,11 +40,13 @@ class FloodfillVerifyStoreJob extends JobImpl {
private final boolean _isRouterInfo;
private MessageWrapper.WrappedMessage _wrappedMessage;
private final Set<Hash> _ignore;
private final MaskedIPSet _ipSet;
private static final int START_DELAY = 18*1000;
private static final int START_DELAY_RAND = 9*1000;
private static final int VERIFY_TIMEOUT = 20*1000;
private static final int MAX_PEERS_TO_TRY = 4;
private static final int IP_CLOSE_BYTES = 3;
/**
* Delay a few seconds, then start the verify
@@ -60,7 +63,10 @@ class FloodfillVerifyStoreJob extends JobImpl {
_facade = facade;
_ignore = new HashSet<Hash>(MAX_PEERS_TO_TRY);
if (sentTo != null) {
_ipSet = new MaskedIPSet(ctx, sentTo, IP_CLOSE_BYTES);
_ignore.add(_sentTo);
} else {
_ipSet = new MaskedIPSet(4);
}
// wait some time before trying to verify the store
getTiming().setStartAfter(ctx.clock().now() + START_DELAY + ctx.random().nextInt(START_DELAY_RAND));
@@ -188,10 +194,19 @@ class FloodfillVerifyStoreJob extends JobImpl {
break;
Hash peer = peers.get(0);
RouterInfo ri = _facade.lookupRouterInfoLocally(peer);
if (ri != null && StoreJob.supportsCert(ri, keyCert))
return peer;
if (_log.shouldLog(Log.INFO))
_log.info(getJobId() + ": Skipping verify w/ router that doesn't support key certs " + peer);
if (ri != null && StoreJob.supportsCert(ri, keyCert)) {
Set<String> peerIPs = new MaskedIPSet(getContext(), ri, IP_CLOSE_BYTES);
if (!_ipSet.containsAny(peerIPs)) {
_ipSet.addAll(peerIPs);
return peer;
} else {
if (_log.shouldLog(Log.INFO))
_log.info(getJobId() + ": Skipping verify w/ router too close to the store " + peer);
}
} else {
if (_log.shouldLog(Log.INFO))
_log.info(getJobId() + ": Skipping verify w/ router that doesn't support key certs " + peer);
}
_ignore.add(peer);
}
} else {

View File

@@ -17,6 +17,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import net.i2p.data.Hash;
import net.i2p.data.router.RouterInfo;
@@ -43,6 +44,9 @@ class PeerManager {
private final Map<Character, Set<Hash>> _peersByCapability;
/** value strings are lower case */
private final Map<Hash, String> _capabilitiesByPeer;
private final AtomicBoolean _storeLock = new AtomicBoolean();
private volatile long _lastStore;
private static final long REORGANIZE_TIME = 45*1000;
private static final long REORGANIZE_TIME_MEDIUM = 123*1000;
/**
@@ -52,6 +56,8 @@ class PeerManager {
* Rate contained in the profile, as the Rates must be coalesced.
*/
private static final long REORGANIZE_TIME_LONG = 351*1000;
private static final long STORE_TIME = 19*60*60*1000;
private static final long EXPIRE_AGE = 3*24*60*60*1000;
public static final String TRACKED_CAPS = "" +
FloodfillNetworkDatabaseFacade.CAPABILITY_FLOODFILL +
@@ -97,11 +103,14 @@ class PeerManager {
}
/**
* Reorganize the profiles. Also periodically store them,
* and delete very old ones.
*
* This takes too long to run on the SimpleTimer2 queue
* @since 0.9.10
*/
private class ReorgThread extends I2PThread {
private SimpleTimer2.TimedEvent _event;
private final SimpleTimer2.TimedEvent _event;
public ReorgThread(SimpleTimer2.TimedEvent event) {
super("PeerManager Reorg");
@@ -117,6 +126,19 @@ class PeerManager {
_log.log(Log.CRIT, "Error evaluating profiles", t);
}
long orgtime = System.currentTimeMillis() - start;
if (_lastStore == 0) {
_lastStore = start;
} else if (start - _lastStore > STORE_TIME) {
_lastStore = start;
try {
_log.debug("Periodic profile store start");
storeProfiles();
_persistenceHelper.deleteOldProfiles(EXPIRE_AGE);
_log.debug("Periodic profile store end");
} catch (Throwable t) {
_log.log(Log.CRIT, "Error storing profiles", t);
}
}
long uptime = _context.router().getUptime();
long delay;
if (orgtime > 1000 || uptime > 2*60*60*1000)
@@ -130,9 +152,16 @@ class PeerManager {
}
void storeProfiles() {
Set<Hash> peers = selectPeers();
for (Hash peer : peers) {
storeProfile(peer);
// lock in case shutdown bumps into periodic store
if (!_storeLock.compareAndSet(false, true))
return;
try {
Set<Hash> peers = selectPeers();
for (Hash peer : peers) {
storeProfile(peer);
}
} finally {
_storeLock.set(false);
}
}

View File

@@ -24,6 +24,7 @@ import net.i2p.data.router.RouterInfo;
import net.i2p.router.NetworkDatabaseFacade;
import net.i2p.router.RouterContext;
import net.i2p.router.tunnel.pool.TunnelPeerSelector;
import net.i2p.router.util.MaskedIPSet;
import net.i2p.router.util.RandomIterator;
import net.i2p.stat.Rate;
import net.i2p.stat.RateStat;
@@ -1245,7 +1246,7 @@ public class ProfileOrganizer {
*/
private void locked_selectPeers(Map<Hash, PeerProfile> peers, int howMany, Set<Hash> toExclude, Set<Hash> matches, int mask) {
List<Hash> all = new ArrayList<Hash>(peers.keySet());
Set<String> IPSet = new HashSet<String>(8);
MaskedIPSet IPSet = new MaskedIPSet(8);
// use RandomIterator to avoid shuffling the whole thing
for (Iterator<Hash> iter = new RandomIterator<Hash>(all); (matches.size() < howMany) && iter.hasNext(); ) {
Hash peer = iter.next();
@@ -1277,77 +1278,14 @@ public class ProfileOrganizer {
* @param mask is 1-4 (number of bytes to match)
* @param IPMatches all IPs so far, modified by this routine
*/
private boolean notRestricted(Hash peer, Set<String> IPSet, int mask) {
Set<String> peerIPs = maskedIPSet(peer, mask);
if (containsAny(IPSet, peerIPs))
private boolean notRestricted(Hash peer, MaskedIPSet IPSet, int mask) {
Set<String> peerIPs = new MaskedIPSet(_context, peer, mask);
if (IPSet.containsAny(peerIPs))
return false;
IPSet.addAll(peerIPs);
return true;
}
/**
* The Set of IPs for this peer, with a given mask.
* Includes the comm system's record of the IP, and all netDb addresses.
*
* As of 0.9.24, returned set will include netdb family as well.
*
* @return an opaque set of masked IPs for this peer
*/
private Set<String> maskedIPSet(Hash peer, int mask) {
Set<String> rv = new HashSet<String>(4);
byte[] commIP = _context.commSystem().getIP(peer);
if (commIP != null)
rv.add(maskedIP(commIP, mask));
RouterInfo pinfo = _context.netDb().lookupRouterInfoLocally(peer);
if (pinfo == null)
return rv;
Collection<RouterAddress> paddr = pinfo.getAddresses();
for (RouterAddress pa : paddr) {
byte[] pib = pa.getIP();
if (pib == null) continue;
rv.add(maskedIP(pib, mask));
}
String family = pinfo.getOption("family");
if (family != null) {
// TODO should KNDF put a family-verified indicator in the RI,
// after checking the sig, or does it matter?
// What's the threat here of not avoid ding a router
// falsely claiming to be in the family?
// Prefix with something so an IP can't be spoofed
rv.add('x' + family);
}
return rv;
}
/**
* generate an arbitrary unique value for this ip/mask (mask = 1-4)
* If IPv6, force mask = 6.
*/
private static String maskedIP(byte[] ip, int mask) {
final StringBuilder buf = new StringBuilder(1 + (mask*2));
final char delim;
if (ip.length == 16) {
mask = 6;
delim = ':';
} else {
delim = '.';
}
buf.append(delim);
buf.append(Long.toHexString(DataHelper.fromLong(ip, 0, mask)));
return buf.toString();
}
/** does a contain any of the elements in b? */
private static <T> boolean containsAny(Set<T> a, Set<T> b) {
if (a.isEmpty() || b.isEmpty())
return false;
for (T o : b) {
if (a.contains(o))
return true;
}
return false;
}
/**
* @param randomKey used for deterministic random partitioning into subtiers
* @param subTierMode 2-7:

View File

@@ -229,6 +229,26 @@ class ProfilePersistenceHelper {
}
}
/**
* Delete profile files with timestamps older than 'age' ago
* @since 0.9.28
*/
public void deleteOldProfiles(long age) {
long cutoff = System.currentTimeMillis() - age;
List<File> files = selectFiles();
int i = 0;
for (File f : files) {
if (!f.isFile())
continue;
if (f.lastModified() < cutoff) {
i++;
f.delete();
}
}
if (_log.shouldWarn())
_log.warn("Deleted " + i + " old profiles");
}
private boolean isExpired(long lastSentToSuccessfully) {
long timeSince = _context.clock().now() - lastSentToSuccessfully;
return (timeSince > EXPIRE_AGE);

View File

@@ -49,17 +49,23 @@ public class OOMListener implements I2PThread.OOMEventListener {
log.log(Log.CRIT, "Thread ran out of memory, shutting down I2P", oom);
log.log(Log.CRIT, "free mem: " + Runtime.getRuntime().freeMemory() +
" total mem: " + Runtime.getRuntime().totalMemory());
// Can't find any System property or wrapper property that gives
// you the actual config file path, have to guess
String path;
if (SystemVersion.isLinuxService()) {
path = "/etc/i2p";
} else {
path = _context.getBaseDir().toString();
}
if (_context.hasWrapper()) {
// Can't find any System property or wrapper property that gives
// you the actual config file path, have to guess
String path;
if (SystemVersion.isLinuxService()) {
path = "/etc/i2p";
} else {
path = _context.getBaseDir().toString();
}
log.log(Log.CRIT, "To prevent future shutdowns, increase wrapper.java.maxmemory in " +
path + File.separatorChar + "wrapper.config");
} else if (!SystemVersion.isWindows()) {
log.log(Log.CRIT, "To prevent future shutdowns, increase MAXMEMOPT in " +
path + File.separatorChar + "runplain.sh or /usr/bin/i2prouter-nowrapper");
} else {
log.log(Log.CRIT, "To prevent future shutdowns, run the restartable version of I2P, and increase wrapper.java.maxmemory in " +
path + File.separatorChar + "wrapper.config");
}
} catch (OutOfMemoryError oome) {}
try {

View File

@@ -11,6 +11,7 @@ package net.i2p.router.transport;
import java.io.IOException;
import java.io.Writer;
import java.net.InetAddress;
import java.net.Inet6Address;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -165,7 +166,7 @@ public class TransportManager implements TransportEventListener {
// so that NTCP may bind early
int port = udp.getRequestedPort();
if (port > 0)
ntcp.externalAddressReceived(SOURCE_CONFIG, null, port);
ntcp.externalAddressReceived(SOURCE_CONFIG, (byte[]) null, port);
}
}
if (_transports.isEmpty())
@@ -182,15 +183,52 @@ public class TransportManager implements TransportEventListener {
*/
private void initializeAddress(Transport t) {
Set<String> ipset = Addresses.getAddresses(false, true); // non-local, include IPv6
//
// Avoid IPv6 temporary addresses if we have a non-temporary one
//
boolean hasNonTempV6Address = false;
List<InetAddress> addresses = new ArrayList<InetAddress>(4);
List<Inet6Address> tempV6Addresses = new ArrayList<Inet6Address>(4);
for (String ips : ipset) {
try {
InetAddress ia = InetAddress.getByName(ips);
byte[] ip = ia.getAddress();
t.externalAddressReceived(SOURCE_INTERFACE, ip, 0);
InetAddress addr = InetAddress.getByName(ips);
if (ips.contains(":") && (addr instanceof Inet6Address)) {
Inet6Address v6addr = (Inet6Address) addr;
// getAddresses(false, true) will not return deprecated addresses
//if (Addresses.isDeprecated(v6addr)) {
// if (_log.shouldWarn())
// _log.warn("Not binding to deprecated temporary address " + bt);
// continue;
//}
if (Addresses.isTemporary(v6addr)) {
// Save temporary addresses
// we only use these if we don't have a non-temporary adress
tempV6Addresses.add(v6addr);
continue;
}
hasNonTempV6Address = true;
}
addresses.add(addr);
} catch (UnknownHostException e) {
_log.error("UDP failed to bind to local address", e);
}
}
// we only use these if we don't have a non-temporary adress
if (!tempV6Addresses.isEmpty()) {
if (hasNonTempV6Address) {
if (_log.shouldWarn()) {
for (Inet6Address addr : tempV6Addresses) {
_log.warn("Not binding to temporary address " + addr.getHostAddress());
}
}
} else {
addresses.addAll(tempV6Addresses);
}
}
for (InetAddress ia : addresses) {
byte[] ip = ia.getAddress();
t.externalAddressReceived(SOURCE_INTERFACE, ip, 0);
}
}
/**

View File

@@ -25,6 +25,8 @@ public abstract class TransportUtil {
public static final String NTCP_IPV6_CONFIG = "i2np.ntcp.ipv6";
public static final String SSU_IPV6_CONFIG = "i2np.udp.ipv6";
public static final String PROP_IPV4_FIREWALLED = "i2np.ipv4.firewalled";
/** @since 0.9.28 */
public static final String PROP_IPV6_FIREWALLED = "i2np.ipv6.firewalled";
public enum IPv6Config {
/** IPv6 disabled */
@@ -99,12 +101,10 @@ public abstract class TransportUtil {
* This returns true if the force-firewalled setting is configured, false otherwise.
*
* @param transportStyle ignored
* @since 0.9.27
* @since 0.9.27, implemented in 0.9.28
*/
public static boolean isIPv6Firewalled(RouterContext ctx, String transportStyle) {
// TODO
//return ctx.getBooleanProperty(PROP_IPV6_FIREWALLED);
return false;
return ctx.getBooleanProperty(PROP_IPV6_FIREWALLED);
}
/**

View File

@@ -58,6 +58,8 @@ import org.freenetproject.ForwardPortStatus;
*
* some code has been borrowed from Limewire : @see com.limegroup.gnutella.UPnPManager
*
* Public only for command line usage. Not a public API, not for external use.
*
* @see "http://www.upnp.org/"
* @see "http://en.wikipedia.org/wiki/Universal_Plug_and_Play"
* @since 0.7.4
@@ -68,7 +70,7 @@ import org.freenetproject.ForwardPortStatus;
* TODO: Advertise the node like the MDNS plugin does
* TODO: Implement EventListener and react on ip-change
*/
class UPnP extends ControlPoint implements DeviceChangeListener, EventListener {
public class UPnP extends ControlPoint implements DeviceChangeListener, EventListener {
private final Log _log;
private final I2PAppContext _context;

View File

@@ -150,6 +150,8 @@ public class NTCPTransport extends TransportImpl {
//_context.statManager().createRateStat("ntcp.inboundCheckConnection", "", "ntcp", RATES);
_context.statManager().createRateStat("ntcp.inboundEstablished", "", "ntcp", RATES);
_context.statManager().createRateStat("ntcp.inboundEstablishedDuplicate", "", "ntcp", RATES);
_context.statManager().createRateStat("ntcp.inboundIPv4Conn", "Inbound IPv4 NTCP Connection", "ntcp", RATES);
_context.statManager().createRateStat("ntcp.inboundIPv6Conn", "Inbound IPv6 NTCP Connection", "ntcp", RATES);
//_context.statManager().createRateStat("ntcp.infoMessageEnqueued", "", "ntcp", RATES);
//_context.statManager().createRateStat("ntcp.floodInfoMessageEnqueued", "", "ntcp", RATES);
_context.statManager().createRateStat("ntcp.invalidDH", "", "ntcp", RATES);
@@ -213,10 +215,13 @@ public class NTCPTransport extends TransportImpl {
synchronized (_conLock) {
old = _conByIdent.put(peer, con);
}
if (con.isIPv6())
if (con.isIPv6()) {
_lastInboundIPv6 = con.getCreated();
else
_context.statManager().addRateData("ntcp.inboundIPv6Conn", 1);
} else {
_lastInboundIPv4 = con.getCreated();
_context.statManager().addRateData("ntcp.inboundIPv4Conn", 1);
}
return old;
}

View File

@@ -289,6 +289,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
_context.statManager().createRateStat("udp.proactiveReestablish", "How long a session was idle for when we proactively reestablished it", "udp", RATES);
_context.statManager().createRateStat("udp.dropPeerDroplist", "How many peers currently have their packets dropped outright when a new peer is added to the list?", "udp", RATES);
_context.statManager().createRateStat("udp.dropPeerConsecutiveFailures", "How many consecutive failed sends to a peer did we attempt before giving up and reestablishing a new session (lifetime is inactivity perood)", "udp", RATES);
_context.statManager().createRateStat("udp.inboundIPv4Conn", "Inbound IPv4 UDP Connection", "udp", RATES);
_context.statManager().createRateStat("udp.inboundIPv6Conn", "Inbound IPv4 UDP Connection", "udp", RATES);
// following are for PacketBuider
//_context.statManager().createRateStat("udp.packetAuthTime", "How long it takes to encrypt and MAC a packet for sending", "udp", RATES);
//_context.statManager().createRateStat("udp.packetAuthTimeSlow", "How long it takes to encrypt and MAC a packet for sending (when its slow)", "udp", RATES);
@@ -780,6 +782,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
void inboundConnectionReceived(boolean isIPv6) {
if (isIPv6) {
_lastInboundIPv6 = _context.clock().now();
_context.statManager().addRateData("udp.inboundIPv6Conn", 1);
// former workaround for lack of IPv6 peer testing
//if (_currentOurV6Address != null)
// setReachabilityStatus(Status.IPV4_UNKNOWN_IPV6_OK, true);
@@ -788,6 +791,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
// that we are not firewalled.
// use OS clock since its an ordering thing, not a time thing
_lastInboundReceivedOn = System.currentTimeMillis();
_context.statManager().addRateData("udp.inboundIPv4Conn", 1);
}
}
@@ -1765,13 +1769,23 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
// (Otherwise we only talk UDP to those that are firewalled, and we will
// never get any introducers)
int count = _peersByIdent.size();
if (alwaysPreferUDP() || count < _min_peers ||
(_haveIPv6Address && count < _min_v6_peers) ||
(introducersRequired() && _introManager.introducerCount() < MIN_INTRODUCER_POOL))
if (alwaysPreferUDP()) {
return _cachedBid[SLOW_PREFERRED_BID];
else if (preferUDP())
} else if (count < _min_peers ||
(_haveIPv6Address && count < _min_v6_peers) ||
(introducersRequired() && _introManager.introducerCount() < MIN_INTRODUCER_POOL)) {
// Even if we haven't hit our minimums, give NTCP a chance some of the time.
// This may make things work a little faster at startup
// (especially when we have an IPv6 address and the increased minimums),
// and if UDP is completely blocked we'll still have some connectivity.
// TODO After some time, decide that UDP is blocked/broken and return TRANSIENT_FAIL_BID?
if (_context.random().nextInt(4) == 0)
return _cachedBid[SLOWEST_BID];
else
return _cachedBid[SLOW_PREFERRED_BID];
} else if (preferUDP()) {
return _cachedBid[SLOW_BID];
else if (haveCapacity()) {
} else if (haveCapacity()) {
if (addr.getCost() > DEFAULT_COST)
return _cachedBid[SLOWEST_COST_BID];
else

View File

@@ -104,7 +104,6 @@ class BloomFilterIVValidator implements IVValidator {
return;
// Can't find any System property or wrapper property that gives
// you the actual config file path, have to guess
// TODO if !SystemVersion.hasWrapper ...
String path;
if (SystemVersion.isLinuxService()) {
path = "/etc/i2p";
@@ -114,13 +113,21 @@ class BloomFilterIVValidator implements IVValidator {
String msg =
"Configured for " + DataHelper.formatSize(KBps *1024L) +
"Bps share bandwidth but only " +
DataHelper.formatSize(maxMemory) + "B available memory." +
" Recommend increasing wrapper.java.maxmemory in " +
path + File.separatorChar + "wrapper.config" +
// getMaxMemory() returns significantly lower than wrapper config, so add 10%
" to at least " + (recMaxMem * 11 / 10 / (1024*1024)) + " (MB)" +
" if the actual share bandwidth exceeds " +
DataHelper.formatSize(threshKBps * 1024L) + "Bps.";
DataHelper.formatSize(maxMemory) + "B available memory.";
if (_context.hasWrapper()) {
msg += " Recommend increasing wrapper.java.maxmemory in " +
path + File.separatorChar + "wrapper.config";
} else if (!SystemVersion.isWindows()) {
msg += " Recommend increasing MAXMEMOPT in " +
path + File.separatorChar + "runplain.sh or /usr/bin/i2prouter-nowrapper";
} else {
msg += " Recommend running the restartable version of I2P, and increasing wrapper.java.maxmemory in " +
path + File.separatorChar + "wrapper.config";
}
// getMaxMemory() returns significantly lower than wrapper config, so add 10%
msg += " to at least " + (recMaxMem * 11 / 10 / (1024*1024)) + " (MB)" +
" if the actual share bandwidth exceeds " +
DataHelper.formatSize(threshKBps * 1024L) + "Bps.";
System.out.println("WARN: " + msg);
_context.logManager().getLog(BloomFilterIVValidator.class).logAlways(Log.WARN, msg);
}

View File

@@ -25,9 +25,23 @@ import net.i2p.util.VersionComparator;
*/
abstract class BuildRequestor {
private static final List<Integer> ORDER = new ArrayList<Integer>(TunnelBuildMessage.MAX_RECORD_COUNT);
private static final String MIN_VARIABLE_VERSION = "0.7.12";
private static final boolean SEND_VARIABLE = true;
private static final int SHORT_RECORDS = 4;
private static final List<Integer> SHORT_ORDER = new ArrayList<Integer>(SHORT_RECORDS);
/** 5 (~2600 bytes) fits nicely in 3 tunnel messages */
private static final int MEDIUM_RECORDS = 5;
private static final List<Integer> MEDIUM_ORDER = new ArrayList<Integer>(MEDIUM_RECORDS);
static {
for (int i = 0; i < TunnelBuildMessage.MAX_RECORD_COUNT; i++)
for (int i = 0; i < TunnelBuildMessage.MAX_RECORD_COUNT; i++) {
ORDER.add(Integer.valueOf(i));
}
for (int i = 0; i < SHORT_RECORDS; i++) {
SHORT_ORDER.add(Integer.valueOf(i));
}
for (int i = 0; i < MEDIUM_RECORDS; i++) {
MEDIUM_ORDER.add(Integer.valueOf(i));
}
}
private static final int PRIORITY = OutNetMessage.PRIORITY_MY_BUILD_REQUEST;
@@ -223,17 +237,6 @@ abstract class BuildRequestor {
// + "ms and dispatched in " + (System.currentTimeMillis()-beforeDispatch));
return true;
}
private static final String MIN_VARIABLE_VERSION = "0.7.12";
/** change this to true in 0.7.13 if testing goes well */
private static final boolean SEND_VARIABLE = true;
/** 5 (~2600 bytes) fits nicely in 3 tunnel messages */
private static final int SHORT_RECORDS = 5;
private static final List<Integer> SHORT_ORDER = new ArrayList<Integer>(SHORT_RECORDS);
static {
for (int i = 0; i < SHORT_RECORDS; i++)
SHORT_ORDER.add(Integer.valueOf(i));
}
/** @since 0.7.12 */
private static boolean supportsVariable(RouterContext ctx, Hash h) {
@@ -256,7 +259,7 @@ abstract class BuildRequestor {
Log log = ctx.logManager().getLog(BuildRequestor.class);
long replyTunnel = 0;
Hash replyRouter = null;
boolean useVariable = SEND_VARIABLE && cfg.getLength() <= SHORT_RECORDS;
boolean useVariable = SEND_VARIABLE && cfg.getLength() <= MEDIUM_RECORDS;
if (cfg.isInbound()) {
//replyTunnel = 0; // as above
replyRouter = ctx.routerHash();
@@ -295,10 +298,13 @@ abstract class BuildRequestor {
TunnelBuildMessage msg;
List<Integer> order;
if (useVariable) {
msg = new VariableTunnelBuildMessage(ctx, SHORT_RECORDS);
order = new ArrayList<Integer>(SHORT_ORDER);
//if (log.shouldLog(Log.INFO))
// log.info("Using new VTBM");
if (cfg.getLength() <= SHORT_RECORDS) {
msg = new VariableTunnelBuildMessage(ctx, SHORT_RECORDS);
order = new ArrayList<Integer>(SHORT_ORDER);
} else {
msg = new VariableTunnelBuildMessage(ctx, MEDIUM_RECORDS);
order = new ArrayList<Integer>(MEDIUM_ORDER);
}
} else {
msg = new TunnelBuildMessage(ctx);
order = new ArrayList<Integer>(ORDER);

View File

@@ -0,0 +1,106 @@
package net.i2p.router.util;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.data.router.RouterAddress;
import net.i2p.data.router.RouterInfo;
import net.i2p.router.RouterContext;
/**
* Used for detection of routers with matching IPs or family.
* Moved out of ProfileOrganizer for use in netdb also.
*
* @since 0.9.28
*/
public class MaskedIPSet extends HashSet<String> {
public MaskedIPSet() {
super();
}
public MaskedIPSet(int initialCapacity) {
super(initialCapacity);
}
/**
* The Set of IPs for this peer, with a given mask.
* Includes the comm system's record of the IP, and all netDb addresses.
*
* As of 0.9.24, returned set will include netdb family as well.
*
* @param peer non-null
* @param mask is 1-4 (number of bytes to match)
* @return an opaque set of masked IPs for this peer
*/
public MaskedIPSet(RouterContext ctx, Hash peer, int mask) {
this(ctx, ctx.netDb().lookupRouterInfoLocally(peer), mask);
}
/**
* The Set of IPs for this peer, with a given mask.
* Includes the comm system's record of the IP, and all netDb addresses.
*
* As of 0.9.24, returned set will include netdb family as well.
*
* @param pinfo may be null
* @param mask is 1-4 (number of bytes to match)
* @return an opaque set of masked IPs for this peer
*/
public MaskedIPSet(RouterContext ctx, RouterInfo pinfo, int mask) {
super(4);
if (pinfo == null)
return;
byte[] commIP = ctx.commSystem().getIP(pinfo.getHash());
if (commIP != null)
add(maskedIP(commIP, mask));
Collection<RouterAddress> paddr = pinfo.getAddresses();
for (RouterAddress pa : paddr) {
byte[] pib = pa.getIP();
if (pib == null) continue;
add(maskedIP(pib, mask));
}
String family = pinfo.getOption("family");
if (family != null) {
// TODO should KNDF put a family-verified indicator in the RI,
// after checking the sig, or does it matter?
// What's the threat here of not avoid ding a router
// falsely claiming to be in the family?
// Prefix with something so an IP can't be spoofed
add('x' + family);
}
}
/**
* generate an arbitrary unique value for this ip/mask (mask = 1-4)
* If IPv6, force mask = 6.
* @param mask is 1-4 (number of bytes to match)
*/
private static String maskedIP(byte[] ip, int mask) {
final StringBuilder buf = new StringBuilder(1 + (mask*2));
final char delim;
if (ip.length == 16) {
mask = 6;
delim = ':';
} else {
delim = '.';
}
buf.append(delim);
buf.append(Long.toHexString(DataHelper.fromLong(ip, 0, mask)));
return buf.toString();
}
/** does this contain any of the elements in b? */
public boolean containsAny(Set<String> b) {
if (isEmpty() || b.isEmpty())
return false;
for (String s : b) {
if (contains(s))
return true;
}
return false;
}
}

View File

@@ -116,6 +116,9 @@ public class HTTPHeader
public final static String getValue(String data, String name)
{
// I2P #1480 avoid IAE
if (data.length() <= 0)
return "";
/* Thanks for Stephan Mehlhase (2010-10-26) */
StringReader strReader = new StringReader(data);
LineNumberReader lineReader = new LineNumberReader(strReader, Math.min(data.length(), MAX_LENGTH));

View File

@@ -92,6 +92,9 @@ public class HTTPUSocket
{
if (0 < localAddr.length())
return localAddr;
// I2P prevent NPE #1681
if (ssdpUniSock == null)
return "";
return ssdpUniSock.getLocalAddress().getHostAddress();
}