diff --git a/apps/i2psnark/java/build.xml b/apps/i2psnark/java/build.xml index 02eee0aabc36ef863fdd4fd561ac646824761dd4..9689fda06823a17019d39cd05c3488b19a433d70 100644 --- a/apps/i2psnark/java/build.xml +++ b/apps/i2psnark/java/build.xml @@ -18,7 +18,6 @@ <!-- Depend on classes instead of jars where available --> <classpath> <pathelement location="../../../core/java/build/obj" /> - <pathelement location="../../../router/java/build/obj" /> <pathelement location="../../ministreaming/java/build/obj" /> <pathelement location="../../jetty/jettylib/org.mortbay.jetty.jar" /> <pathelement location="../../jetty/jettylib/javax.servlet.jar" /> @@ -32,7 +31,7 @@ srcdir="./src" debug="true" deprecation="on" source="1.5" target="1.5" destdir="./build/obj" - classpath="../../../core/java/build/i2p.jar:../../../router/java/build/router.jar:../../jetty/jettylib/org.mortbay.jetty.jar:../../jetty/jettylib/javax.servlet.jar:../../ministreaming/java/build/mstreaming.jar" /> + classpath="../../../core/java/build/i2p.jar:../../jetty/jettylib/org.mortbay.jetty.jar:../../jetty/jettylib/javax.servlet.jar:../../ministreaming/java/build/mstreaming.jar" /> </target> <target name="jar" depends="builddep, compile"> <jar destfile="./build/i2psnark.jar" basedir="./build/obj" includes="**/*.class" excludes="**/*Servlet.class"> diff --git a/apps/i2psnark/java/src/org/klomp/snark/BWLimits.java b/apps/i2psnark/java/src/org/klomp/snark/BWLimits.java new file mode 100644 index 0000000000000000000000000000000000000000..eb157cb5e4426bb87f5538fbe92fee86175724da --- /dev/null +++ b/apps/i2psnark/java/src/org/klomp/snark/BWLimits.java @@ -0,0 +1,44 @@ +/* + * Released into the public domain + * with no warranty of any kind, either expressed or implied. + */ +package org.klomp.snark; + +import java.util.Arrays; +import java.util.Properties; + +import net.i2p.I2PAppContext; +import net.i2p.client.I2PSessionException; +import net.i2p.client.I2PClient; +import net.i2p.client.I2PSession; +import net.i2p.client.I2PSimpleClient; + +/** + * Connect via I2CP and ask the router the bandwidth limits. + * + * The call is blocking and returns null on failure. + * Timeout is set to 5 seconds in I2PSimpleSession but it should be much faster. + * + * @author zzz + */ +class BWLimits { + + public static int[] getBWLimits(String host, int port) { + int[] rv = null; + try { + I2PClient client = new I2PSimpleClient(); + Properties opts = new Properties(); + opts.put(I2PClient.PROP_TCP_HOST, host); + opts.put(I2PClient.PROP_TCP_PORT, "" + port); + I2PSession session = client.createSession(null, opts); + session.connect(); + rv = session.bandwidthLimits(); + session.destroySession(); + } catch (I2PSessionException ise) {} + return rv; + } + + public static void main(String args[]) { + System.out.println(Arrays.toString(getBWLimits("127.0.0.1", 7654))); + } +} diff --git a/apps/i2psnark/java/src/org/klomp/snark/Snark.java b/apps/i2psnark/java/src/org/klomp/snark/Snark.java index e124955cfc3bc551207bc5291e79f2c25ecdb71e..53c42dfadf30b51dfbd50bfc66e6140480267b99 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Snark.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Snark.java @@ -36,7 +36,6 @@ import java.util.Timer; import java.util.TimerTask; import net.i2p.I2PAppContext; -import net.i2p.router.client.ClientManagerFacadeImpl; import net.i2p.client.streaming.I2PServerSocket; import net.i2p.data.Destination; import net.i2p.util.I2PThread; @@ -261,9 +260,9 @@ public class Snark public Snark(I2PAppContext ctx, Properties opts, String torrent, StorageListener slistener, boolean start, String rootDir) { this(new I2PSnarkUtil(ctx), torrent, null, -1, slistener, null, null, null, null, false, rootDir); - String host = opts.getProperty(ClientManagerFacadeImpl.PROP_CLIENT_HOST); + String host = opts.getProperty("i2cp.hostname"); int port = 0; - String s = opts.getProperty(ClientManagerFacadeImpl.PROP_CLIENT_PORT); + String s = opts.getProperty("i2cp.port"); if (s != null) { try { port = Integer.parseInt(s); diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index 54367af1ac90658eceaaa1dd3a155b2bfef9234f..01a93a58c12fae63ecff4158415105eda292130f 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -18,7 +18,6 @@ import java.util.TreeMap; import net.i2p.I2PAppContext; import net.i2p.data.Base64; import net.i2p.data.DataHelper; -import net.i2p.router.RouterContext; import net.i2p.util.I2PAppThread; import net.i2p.util.Log; @@ -147,22 +146,21 @@ public class SnarkManager implements Snark.CompleteListener { _config.setProperty(PROP_EEP_PORT, "4444"); if (!_config.containsKey(PROP_UPLOADERS_TOTAL)) _config.setProperty(PROP_UPLOADERS_TOTAL, "" + Snark.MAX_TOTAL_UPLOADERS); - if (!_config.containsKey(PROP_UPBW_MAX)) { - try { - if (_context instanceof RouterContext) - _config.setProperty(PROP_UPBW_MAX, "" + (((RouterContext)_context).bandwidthLimiter().getOutboundKBytesPerSecond() / 2)); - else - _config.setProperty(PROP_UPBW_MAX, "" + DEFAULT_MAX_UP_BW); - } catch (NoClassDefFoundError ncdfe) { - _config.setProperty(PROP_UPBW_MAX, "" + DEFAULT_MAX_UP_BW); - } - } if (!_config.containsKey(PROP_DIR)) _config.setProperty(PROP_DIR, "i2psnark"); if (!_config.containsKey(PROP_AUTO_START)) _config.setProperty(PROP_AUTO_START, DEFAULT_AUTO_START); updateConfig(); } + + /** call from DirMonitor since loadConfig() is called before router I2CP is up */ + private void getBWLimit() { + if (!_config.containsKey(PROP_UPBW_MAX)) { + int[] limits = BWLimits.getBWLimits(_util.getI2CPHost(), _util.getI2CPPort()); + if (limits != null && limits[1] > 0) + _util.setMaxUpBW(limits[1]); + } + } private void updateConfig() { String i2cpHost = _config.getProperty(PROP_I2CP_HOST); @@ -619,6 +617,9 @@ public class SnarkManager implements Snark.CompleteListener { _messages.remove(0); } + // here because we need to delay until I2CP is up + // although the user will see the default until then + getBWLimit(); while (true) { File dir = getDataDir(); _log.debug("Directory Monitor loop over " + dir.getAbsolutePath()); diff --git a/core/java/src/net/i2p/client/I2PSession.java b/core/java/src/net/i2p/client/I2PSession.java index 1776af5c0f91200ccfcfbcbb20ec0101fb8f821e..1998dad55a737a016d558e456ae2f632eff13e6c 100644 --- a/core/java/src/net/i2p/client/I2PSession.java +++ b/core/java/src/net/i2p/client/I2PSession.java @@ -143,6 +143,11 @@ public interface I2PSession { */ public Destination lookupDest(Hash h) throws I2PSessionException; + /** + * Get the current bandwidth limits + */ + public int[] bandwidthLimits() throws I2PSessionException; + /** See I2PSessionMuxedImpl for details */ public void addSessionListener(I2PSessionListener lsnr, int proto, int port); /** See I2PSessionMuxedImpl for details */ diff --git a/core/java/src/net/i2p/client/I2PSessionImpl.java b/core/java/src/net/i2p/client/I2PSessionImpl.java index 0e13f2c56308c82a587081bec7cc0b7e23e178b7..5b7603fdd605be34d10c3f3628fb1270175f6774 100644 --- a/core/java/src/net/i2p/client/I2PSessionImpl.java +++ b/core/java/src/net/i2p/client/I2PSessionImpl.java @@ -656,6 +656,10 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa return null; } + public int[] bandwidthLimits() throws I2PSessionException { + return null; + } + protected void updateActivity() { _lastActivity = _context.clock().now(); if (_isReduced) { diff --git a/core/java/src/net/i2p/client/I2PSimpleSession.java b/core/java/src/net/i2p/client/I2PSimpleSession.java index ae588e05f1b4e11a2fe6f59fe06415fbd3f6be0b..b417bd7f7abcf9b19af31ab16b2abab70ac75296 100644 --- a/core/java/src/net/i2p/client/I2PSimpleSession.java +++ b/core/java/src/net/i2p/client/I2PSimpleSession.java @@ -130,7 +130,7 @@ class I2PSimpleSession extends I2PSessionImpl2 { return null; _bwReceivedLock = new Object(); sendMessage(new GetBandwidthLimitsMessage()); - for (int i = 0; i < 5 && !_destReceived; i++) { + for (int i = 0; i < 5 && !_bwReceived; i++) { try { synchronized (_bwReceivedLock) { _bwReceivedLock.wait(1000); diff --git a/router/java/src/net/i2p/router/client/ClientMessageEventListener.java b/router/java/src/net/i2p/router/client/ClientMessageEventListener.java index cf49ebcd480921bb73c46e17783468632bda847d..3b4b1a6bed38fa27ce4434f5691256e96f902ce5 100644 --- a/router/java/src/net/i2p/router/client/ClientMessageEventListener.java +++ b/router/java/src/net/i2p/router/client/ClientMessageEventListener.java @@ -280,15 +280,15 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi } /** - * Divide router limit by 2 for overhead. + * Divide router limit by 1.75 for overhead. * This could someday give a different answer to each client. * But it's not enforced anywhere. */ private void handleGetBWLimits(I2CPMessageReader reader, GetBandwidthLimitsMessage message) { if (_log.shouldLog(Log.INFO)) _log.info("Got BW Limits request"); - int in = _context.bandwidthLimiter().getInboundKBytesPerSecond() / 2; - int out = _context.bandwidthLimiter().getOutboundKBytesPerSecond() / 2; + int in = _context.bandwidthLimiter().getInboundKBytesPerSecond() * 4 / 7; + int out = _context.bandwidthLimiter().getOutboundKBytesPerSecond() * 4 / 7; BandwidthLimitsMessage msg = new BandwidthLimitsMessage(in, out); try { _runner.doSend(msg);