diff --git a/apps/BOB/nbproject/private/private.xml b/apps/BOB/nbproject/private/private.xml index 7d9997b3a..c1f155a78 100644 --- a/apps/BOB/nbproject/private/private.xml +++ b/apps/BOB/nbproject/private/private.xml @@ -1,9 +1,4 @@ - - file:/root/NetBeansProjects/i2p.i2p/apps/BOB/src/net/i2p/BOB/BOB.java - file:/root/NetBeansProjects/i2p.i2p/apps/BOB/src/net/i2p/BOB/DoCMDS.java - file:/root/NetBeansProjects/i2p.i2p/apps/BOB/src/net/i2p/BOB/MUXlisten.java - diff --git a/apps/BOB/src/net/i2p/BOB/BOB.java b/apps/BOB/src/net/i2p/BOB/BOB.java index 1aa432e2e..f08d27c2f 100644 --- a/apps/BOB/src/net/i2p/BOB/BOB.java +++ b/apps/BOB/src/net/i2p/BOB/BOB.java @@ -41,7 +41,6 @@ import net.i2p.client.I2PClient; import net.i2p.client.streaming.RetransmissionTimer; import net.i2p.util.Log; import net.i2p.util.SimpleScheduler; -import net.i2p.util.SimpleStore; import net.i2p.util.SimpleTimer2; /** diff --git a/apps/BOB/src/net/i2p/BOB/DoCMDS.java b/apps/BOB/src/net/i2p/BOB/DoCMDS.java index cc92e66ca..9019ef85b 100644 --- a/apps/BOB/src/net/i2p/BOB/DoCMDS.java +++ b/apps/BOB/src/net/i2p/BOB/DoCMDS.java @@ -47,7 +47,7 @@ public class DoCMDS implements Runnable { // FIX ME // I need a better way to do versioning, but this will do for now. - public static final String BMAJ = "00", BMIN = "00", BREV = "06", BEXT = ""; + public static final String BMAJ = "00", BMIN = "00", BREV = "07", BEXT = ""; public static final String BOBversion = BMAJ + "." + BMIN + "." + BREV + BEXT; private Socket server; private Properties props; diff --git a/apps/BOB/src/net/i2p/BOB/I2PtoTCP.java b/apps/BOB/src/net/i2p/BOB/I2PtoTCP.java index 91ac05589..5df1f3e0e 100644 --- a/apps/BOB/src/net/i2p/BOB/I2PtoTCP.java +++ b/apps/BOB/src/net/i2p/BOB/I2PtoTCP.java @@ -52,12 +52,12 @@ public class I2PtoTCP implements Runnable { this.database = database; } - private void rlock() throws Exception { + private void rlock() { database.getReadLock(); info.getReadLock(); } - private void runlock() throws Exception { + private void runlock() { database.releaseReadLock(); info.releaseReadLock(); } diff --git a/apps/BOB/src/net/i2p/BOB/MUXlisten.java b/apps/BOB/src/net/i2p/BOB/MUXlisten.java index 2f22abbeb..d13b8217b 100644 --- a/apps/BOB/src/net/i2p/BOB/MUXlisten.java +++ b/apps/BOB/src/net/i2p/BOB/MUXlisten.java @@ -43,7 +43,7 @@ import net.i2p.util.Log; */ public class MUXlisten implements Runnable { - private NamedDB database, info; + private NamedDB database, info; private Log _log; private I2PSocketManager socketManager; private ByteArrayInputStream prikey; @@ -269,27 +269,27 @@ public class MUXlisten implements Runnable { // Wait around till all threads are collected. if (tg != null) { String boner = tg.getName(); - System.out.println("BOB: MUXlisten: Starting thread collection for: " + boner); + // System.out.println("BOB: MUXlisten: Starting thread collection for: " + boner); _log.warn("BOB: MUXlisten: Starting thread collection for: " + boner); // tg.interrupt(); // give my stuff a small smack again. if (tg.activeCount() + tg.activeGroupCount() != 0) { - visit(tg, 0, boner); + // visit(tg, 0, boner); int foo = tg.activeCount() + tg.activeGroupCount(); // hopefully no longer needed! - int bar = foo; - System.out.println("BOB: MUXlisten: Waiting on threads for " + boner); - System.out.println("\nBOB: MUXlisten: ThreadGroup dump BEGIN " + boner); - visit(tg, 0, boner); - System.out.println("BOB: MUXlisten: ThreadGroup dump END " + boner + "\n"); + // int bar = foo; + // System.out.println("BOB: MUXlisten: Waiting on threads for " + boner); + // System.out.println("\nBOB: MUXlisten: ThreadGroup dump BEGIN " + boner); + // visit(tg, 0, boner); + // System.out.println("BOB: MUXlisten: ThreadGroup dump END " + boner + "\n"); // Happily spin forever :-( while (foo != 0) { foo = tg.activeCount() + tg.activeGroupCount(); - if (foo != bar && foo != 0) { - System.out.println("\nBOB: MUXlisten: ThreadGroup dump BEGIN " + boner); - visit(tg, 0, boner); - System.out.println("BOB: MUXlisten: ThreadGroup dump END " + boner + "\n"); - } - bar = foo; + // if (foo != bar && foo != 0) { + // System.out.println("\nBOB: MUXlisten: ThreadGroup dump BEGIN " + boner); + // visit(tg, 0, boner); + // System.out.println("BOB: MUXlisten: ThreadGroup dump END " + boner + "\n"); + // } + // bar = foo; try { Thread.sleep(100); //sleep for 100 ms (One tenth second) } catch (InterruptedException ex) { @@ -297,7 +297,7 @@ public class MUXlisten implements Runnable { } } } - System.out.println("BOB: MUXlisten: Threads went away. Success: " + boner); + // System.out.println("BOB: MUXlisten: Threads went away. Success: " + boner); _log.warn("BOB: MUXlisten: Threads went away. Success: " + boner); tg.destroy(); // Zap reference to the ThreadGroup so the JVM can GC it. @@ -357,41 +357,4 @@ public class MUXlisten implements Runnable { } } - /* - private static void nuke(ThreadGroup group, int level) { - // Get threads in `group' - int numThreads = group.activeCount(); - Thread[] threads = new Thread[numThreads * 2]; - numThreads = group.enumerate(threads, false); - // Enumerate each thread in `group' and stop it. - for (int i = 0; i < numThreads; i++) { - // Get thread - Thread thread = threads[i]; - try { - if (thread.isAlive()) { - thread.stop(); - } - } catch (SecurityException se) { - //nop - } - } - - // Get thread subgroups of `group' - int numGroups = group.activeGroupCount(); - ThreadGroup[] groups = new ThreadGroup[numGroups * 2]; - numGroups = group.enumerate(groups, false); - - // Recursively visit each subgroup - for (int i = 0; i < numGroups; i++) { - nuke(groups[i], level + 1); - } - try { - group.destroy(); - } catch (IllegalThreadStateException IE) { - //nop - } catch (SecurityException se) { - //nop - } - } - */ } diff --git a/apps/BOB/src/net/i2p/BOB/TCPlistener.java b/apps/BOB/src/net/i2p/BOB/TCPlistener.java index 8f559c09f..9155cb82b 100644 --- a/apps/BOB/src/net/i2p/BOB/TCPlistener.java +++ b/apps/BOB/src/net/i2p/BOB/TCPlistener.java @@ -42,7 +42,6 @@ public class TCPlistener implements Runnable { private NamedDB info, database; private Log _log; - private int tgwatch; public I2PSocketManager socketManager; public I2PServerSocket serverSocket; private ServerSocket listener; @@ -60,7 +59,6 @@ public class TCPlistener implements Runnable { this._log = _log; this.socketManager = S; this.listener = listener; - tgwatch = 1; } private void rlock() throws Exception { @@ -84,28 +82,6 @@ public class TCPlistener implements Runnable { try { die: { - try { - rlock(); - } catch (Exception e) { - break die; - } - try { - if (info.exists("OUTPORT")) { - tgwatch = 2; - } - } catch (Exception e) { - try { - runlock(); - } catch (Exception e2) { - break die; - } - break die; - } - try { - runlock(); - } catch (Exception e) { - break die; - } try { Socket server = new Socket(); listener.setSoTimeout(50); // We don't block, we cycle and check. @@ -134,7 +110,7 @@ public class TCPlistener implements Runnable { if (g) { conn++; // toss the connection to a new thread. - TCPtoI2P conn_c = new TCPtoI2P(socketManager, server); + TCPtoI2P conn_c = new TCPtoI2P(socketManager, server, info, database); Thread t = new Thread(conn_c, Thread.currentThread().getName() + " TCPtoI2P " + conn); t.start(); g = false; diff --git a/apps/BOB/src/net/i2p/BOB/TCPtoI2P.java b/apps/BOB/src/net/i2p/BOB/TCPtoI2P.java index 117c2b103..2073e0e69 100644 --- a/apps/BOB/src/net/i2p/BOB/TCPtoI2P.java +++ b/apps/BOB/src/net/i2p/BOB/TCPtoI2P.java @@ -33,6 +33,7 @@ import java.net.Socket; import net.i2p.I2PException; import net.i2p.client.streaming.I2PSocket; import net.i2p.client.streaming.I2PSocketManager; +import net.i2p.data.DataFormatException; import net.i2p.data.Destination; import net.i2p.i2ptunnel.I2PTunnel; @@ -49,15 +50,29 @@ public class TCPtoI2P implements Runnable { private Socket sock; private I2PSocketManager socketManager; + /** + * Constructor + * @param i2p + * @param socket + * param info + * param database + */ + TCPtoI2P(I2PSocketManager i2p, Socket socket , NamedDB info, NamedDB database) { + this.sock = socket; + this.info = info; + this.database = database; + this.socketManager = i2p; + } + /** * This is a more forgiving readline, * it works on unbuffered streams * * @param in * @return line of text as a String - * @throws Exception + * @throws IOException */ - private static String lnRead(InputStream in) throws Exception { + private static String lnRead(InputStream in) throws IOException { String S; int b; char c; @@ -80,20 +95,6 @@ public class TCPtoI2P implements Runnable { return S; } - /** - * Constructor - * @param i2p - * @param socket - * param info - * param database - */ - TCPtoI2P(I2PSocketManager i2p, Socket socket /*, NamedDB info, NamedDB database */) { - this.sock = socket; - // this.info = info; - // this.database = database; - this.socketManager = i2p; - } - /** * Print an error message to out * @@ -103,19 +104,22 @@ public class TCPtoI2P implements Runnable { */ private void Emsg(String e, OutputStream out) throws IOException { // Debugging System.out.println("ERROR TCPtoI2P: " + e); - out.write("ERROR".concat(e).getBytes()); - out.write(13); // cr + out.write("ERROR ".concat(e).getBytes()); + out.write(13); + out.write(10); out.flush(); } - private void rlock() throws Exception { +// private void rlock() throws Exception { + private void rlock() { database.getReadLock(); info.getReadLock(); } - private void runlock() throws Exception { - database.releaseReadLock(); +// private void runlock() throws Exception { + private void runlock() { info.releaseReadLock(); + database.releaseReadLock(); } /** @@ -135,56 +139,64 @@ public class TCPtoI2P implements Runnable { in = sock.getInputStream(); out = sock.getOutputStream(); - try { - line = lnRead(in); - input = line.toLowerCase(); - Destination dest = null; - - if (input.endsWith(".i2p")) { - dest = I2PTunnel.destFromName(input); - line = dest.toBase64(); - } - dest = new Destination(); - dest.fromBase64(line); - - try { - // get a client socket - I2P = socketManager.connect(dest); - I2P.setReadTimeout(0); // temp bugfix, this *SHOULD* be the default - // make readers/writers - Iin = I2P.getInputStream(); - Iout = I2P.getOutputStream(); - // setup to cross the streams - TCPio conn_c = new TCPio(in, Iout /*, info, database */); // app -> I2P - TCPio conn_a = new TCPio(Iin, out /*, info, database */); // I2P -> app - t = new Thread(conn_c, Thread.currentThread().getName() + " TCPioA"); - q = new Thread(conn_a, Thread.currentThread().getName() + " TCPioB"); - // Fire! - t.start(); - q.start(); - boolean spin = true; - while (t.isAlive() && q.isAlive()) { // AND is used here to kill off the other thread - Thread.sleep(10); //sleep for 10 ms - rlock(); - spin = info.get("RUNNING").equals(Boolean.TRUE); - runlock(); - } - } catch (I2PException e) { - Emsg("ERROR " + e.toString(), out); - } catch (ConnectException e) { - Emsg("ERROR " + e.toString(), out); - } catch (NoRouteToHostException e) { - Emsg("ERROR " + e.toString(), out); - } catch (InterruptedIOException e) { - // We're breaking away. - } - - } catch (Exception e) { - Emsg("ERROR " + e.toString(), out); + line = lnRead(in); + input = line.toLowerCase(); + Destination dest = null; + if (input.endsWith(".i2p")) { + dest = I2PTunnel.destFromName(input); + line = dest.toBase64(); + } + dest = new Destination(); + dest.fromBase64(line); + + try { + // get a client socket + I2P = socketManager.connect(dest); + I2P.setReadTimeout(0); // temp bugfix, this *SHOULD* be the default + // make readers/writers + Iin = I2P.getInputStream(); + Iout = I2P.getOutputStream(); + // setup to cross the streams + TCPio conn_c = new TCPio(in, Iout /*, info, database */); // app -> I2P + TCPio conn_a = new TCPio(Iin, out /*, info, database */); // I2P -> app + t = new Thread(conn_c, Thread.currentThread().getName() + " TCPioA"); + q = new Thread(conn_a, Thread.currentThread().getName() + " TCPioB"); + // Fire! + t.start(); + q.start(); + boolean spin = true; + while (t.isAlive() && q.isAlive()) { // AND is used here to kill off the other thread + Thread.sleep(10); //sleep for 10 ms + rlock(); + spin = info.get("RUNNING").equals(Boolean.TRUE); + runlock(); + } + } catch (I2PException e) { + Emsg(e.toString(), out); + } catch (ConnectException e) { + Emsg(e.toString(), out); + } catch (NoRouteToHostException e) { + Emsg(e.toString(), out); + } + + } catch (InterruptedIOException e) { + // We're breaking away. + } catch (InterruptedException e) { + // ditto + } catch (IOException e) { + try { + Emsg(e.toString(), out); + } catch (IOException ex) { + // ditto + } + } catch (DataFormatException e) { + try { + Emsg(e.toString(), out); + } catch (IOException ex) { + // ditto } - } catch (Exception e) { - // bail on anything else } + } finally { try { t.interrupt(); diff --git a/core/java/src/net/i2p/CoreVersion.java b/core/java/src/net/i2p/CoreVersion.java index 6b3f02efa..972b87966 100644 --- a/core/java/src/net/i2p/CoreVersion.java +++ b/core/java/src/net/i2p/CoreVersion.java @@ -15,7 +15,7 @@ package net.i2p; */ public class CoreVersion { public final static String ID = "$Revision: 1.72 $ $Date: 2008-08-24 12:00:00 $"; - public final static String VERSION = "0.7.3"; + public final static String VERSION = "0.7.4"; public static void main(String args[]) { System.out.println("I2P Core version: " + VERSION); diff --git a/history.txt b/history.txt index 184c2500c..28b3be69d 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,111 @@ +2009-06-17 zzz + * PeerSelector: + - Limit exploratory tunnels to connected peers when over + half the connection limit (was 80%) + - Have the high capacity tier fall back to a new connected tier + before moving on to the not failing tier + so that tunnel build success doesn't collapse and drive + connections to the limit + * PeerTestJob: + - Limit to connected peers + +2009-06-12 zzz + * Console: + - Move the console css from default.css in the .war to docs/themes/console/console.css, + and support console themes in the main console with routerconsole.theme=foo + - Remove unused NoticeHelper + + * Installer: + Upgrade to izpack 4.3.0 and add a short script to fix Vista install problems. + (previous izpack was 3.7.2 from 2005-04-22) + + izpack 4.3.0 from : + http://dist.codehaus.org/izpack/releases/4.3.0/IzPack-install-4.3.0.jar + SHA1 f06da6b26ac2c68fed64ab38980352989b8d8841 + (no signatures or sha1sums found on website, and the jar is unsigned) + License: Apache 2.0 + + upack izpack: + java -jar IzPack-install-4.3.0.jar + or + java -jar IzPack-install-4.3.0.jar -console + + get the standalone-compiler.jar from the installation lib/ directory: + SHA1 6d2b4a5657bfb864a333b1c4b1c0f8223aa57d80 + (no signatures or sha1sums found on website, and the jar is unsigned) + + This fixes the bug with the install windows centered in all the + workspaces, not the current workspace. And who knows what other + bugs in the last 4 years. + + To fix Vista (and presumably Windows 7) permissiom problems, + add a run-privileged flag for those, and run the new fixperms.bat + which calls icacls to add the privileges to the install directory. + + Add support for 6 more language packs found in the new release. + Change from ISO3 codes to native language names. + + Disable creation of the i2p.tar.bz2 file in build.xml + (distributed as i2pheadless-0.7.x.tar.bz2), as izpack 4.3.0 now + supports headless installation with java -jar i2pinstall.exe -console. + Update INSTALL.txt and INSTALL-headless.txt accordingly. + + - Add install and temp path substitution to wrapper.config and + i2prouter on install + + - Change the wrapper.config classpath to one line: lib/*.jar + This means we lose control of classpath load order, so move the windows installer + jars copy.jar, delete.jar, and exec.jar to a new installer/ directory so + these jars won't be in the classpath or potentially conflict, since + copy.jar and delete.jar include FileUtil.class, and we don't want to have + to remember to add them to the updater if we ever change FileUtil.class. + Delete the installer/ directory in postinstall.sh since it is windows-only. + + * Watchdog: Only try to dump threads if there is a wrapper + and we aren't on windows + +* 2009-06-12 0.7.4 released + +2009-06-12 Complication + * Update versions, package release + +2009-06-09 zzz + * NTCP: Fix startup race NPE (thanks postman!) + +2009-06-08 sponge + * Last commit for this cycle. All debugging except for WARN removed. + I can use the visit command to debug now anyway. + +2009-06-08 sponge + * Removed BOB debugging as-per zzz + +2009-06-08 sponge + * Fixed NPE and some other goofups in BOB. + * BOB bump version + +2009-06-07 zzz + * Build file: + - Add updaterWithJettyFixesAndGeoIP, use it in pkg for one release + - Cleanups + * Console: + - netdb.jsp cleanup + - tunnels.jsp cleanup + * ExploratoryPeerSelector: + - Limit to connected peers when near connection limit + * Timestamper: + - Use locale country if geoip unavailable + * Transport: + - Lower min NTCP idle time to 3m (was 5m) + - Increase SSU conn limit by 33% + * UPnP: Fix deprecation warning + * Watchdog: + - Defang him again + +2009-06-06 sponge + * Added BOB's license to licenses + * Janitorial javadoc fixes *sigh* + * bump to -13 + 2009-06-05 sponge * Merge and bump to -12 @@ -10,8 +118,15 @@ time out. What should happen is the streaming lib should cause an IO error to the pending read or write. +2009-06-05 zzz + * Build file: + - Add license info for launch4j includes + * Console: + - 16x11 transparent flags for ch and np, thanks anonim! + 2009-06-04 zzz * Console: + - Update geoip file to June 3 version - Hide some controls if no wrapper on configservice.jsp * I2PTunnel: - Fix bug where delayed-open and close-on-idle tunnels would diff --git a/initialNews.xml b/initialNews.xml index a07ac5b6e..0a2c5b12b 100644 --- a/initialNews.xml +++ b/initialNews.xml @@ -1,5 +1,5 @@ - - +

Congratulations on getting I2P installed!

    diff --git a/installer/install.xml b/installer/install.xml index 1141b17ba..377b47dec 100644 --- a/installer/install.xml +++ b/installer/install.xml @@ -4,7 +4,7 @@ i2p - 0.7.3 + 0.7.4 diff --git a/licenses/COPYING-BOB.txt b/licenses/COPYING-BOB.txt new file mode 100644 index 000000000..116db5958 --- /dev/null +++ b/licenses/COPYING-BOB.txt @@ -0,0 +1,21 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) sponge + Planet Earth + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. + +See... + + http://sam.zoy.org/wtfpl/ + and + http://en.wikipedia.org/wiki/WTFPL + +...for any additional details and license questions. diff --git a/news.xml b/news.xml index 6b51926b5..e03588a6e 100644 --- a/news.xml +++ b/news.xml @@ -1,5 +1,5 @@ - - +

    • -2009-05-16: 0.7.3 Released +2009-06-12: 0.7.4 Released

    -I2P version 0.7.3 contains several buxfixes and improvements, -includes a lot of maintenance work and new versions of -both the SAM and BOB application gateway protocols. +I2P version 0.7.4 introduces notable new features +like GeoIP capability and UPnP support. While the former +can become a basis for geographically aware tunnel-building, +the latter should immediately enable more routers to accept +inbound TCP connections, helping distribute workload more evenly.

    -A patch to I2P's internal web server Jetty is included -to correct SusiDNS behaviour on Windows. The way I2P nodes -volunteer to participate in the Network Database is changed -to avoid too many doing this simultaneously, and creation -of new participating tunnels is now throttled before messages -in existing tunnels start to get dropped. +Inbound NTCP is now enabled automaticaly if the router +does not appear firewalled, and default bandwidth limits +for new installations are increased.

    -Multiple improvements to the Router Console and other components -are included, I2PSnark can handle bigger torrents and more files, -while work continues on the experimental desktop interface. -Updating is recommended. +In addition, multiple bugfixes and updates are included, +addressing issues with the NTCP transport, BOB protocol, +connection limiting, behaviour of new I2PTunnel options +and the SusiDNS user interface. Improvements to the Router Console +are likewise included. Updating is recommended.

    diff --git a/router/java/src/net/i2p/router/CommSystemFacade.java b/router/java/src/net/i2p/router/CommSystemFacade.java index 4fe9147ac..c26d9efbf 100644 --- a/router/java/src/net/i2p/router/CommSystemFacade.java +++ b/router/java/src/net/i2p/router/CommSystemFacade.java @@ -36,6 +36,7 @@ public abstract class CommSystemFacade implements Service { public int countActiveSendPeers() { return 0; } public boolean haveInboundCapacity() { return true; } public boolean haveOutboundCapacity() { return true; } + public boolean haveHighOutboundCapacity() { return true; } public List getMostRecentErrorMessages() { return Collections.EMPTY_LIST; } /** diff --git a/router/java/src/net/i2p/router/RouterThrottleImpl.java b/router/java/src/net/i2p/router/RouterThrottleImpl.java index 214753db2..4b3f683ea 100644 --- a/router/java/src/net/i2p/router/RouterThrottleImpl.java +++ b/router/java/src/net/i2p/router/RouterThrottleImpl.java @@ -101,7 +101,7 @@ class RouterThrottleImpl implements RouterThrottle { // reject here if lag too high??? RateStat rs = _context.statManager().getRate("transport.sendProcessingTime"); - Rate r = null; + Rate r = rs.getRate(60*1000); //Reject tunnels if the time to process messages and send them is too large. Too much time implies congestion. if(r != null) { diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 360707e4c..bd644cee5 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,9 +18,9 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 12; + public final static long BUILD = 2; /** for example "-test" */ - public final static String EXTRA = "-rc"; + public final static String EXTRA = ""; public final static String FULL_VERSION = VERSION + "-" + BUILD + EXTRA; public static void main(String args[]) { System.out.println("I2P Router version: " + FULL_VERSION); diff --git a/router/java/src/net/i2p/router/peermanager/PeerManager.java b/router/java/src/net/i2p/router/peermanager/PeerManager.java index 7086f1cfc..9dc3a859b 100644 --- a/router/java/src/net/i2p/router/peermanager/PeerManager.java +++ b/router/java/src/net/i2p/router/peermanager/PeerManager.java @@ -116,7 +116,14 @@ class PeerManager { case PeerSelectionCriteria.PURPOSE_TEST: // for now, the peers we test will be the reliable ones //_organizer.selectWellIntegratedPeers(criteria.getMinimumRequired(), exclude, curVals); - _organizer.selectNotFailingPeers(criteria.getMinimumRequired(), exclude, peers); + + // The PeerTestJob does only run every 5 minutes, but + // this was helping drive us to connection limits, let's leave the exploration + // to the ExploratoryPeerSelector, which will restrict to connected peers + // when we get close to the limit. So let's stick with connected peers here. + // Todo: what's the point of the PeerTestJob anyway? + //_organizer.selectNotFailingPeers(criteria.getMinimumRequired(), exclude, peers); + _organizer.selectActiveNotFailingPeers(criteria.getMinimumRequired(), exclude, peers); break; case PeerSelectionCriteria.PURPOSE_TUNNEL: // pull all of the fast ones, regardless of how many we diff --git a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java index 9d9a8b746..b0de2092d 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java +++ b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java @@ -316,8 +316,8 @@ public class ProfileOrganizer { } finally { releaseReadLock(); } if (matches.size() < howMany) { if (_log.shouldLog(Log.INFO)) - _log.info("selectHighCap("+howMany+"), not enough fast (" + matches.size() + ") going on to notFailing"); - selectNotFailingPeers(howMany, exclude, matches, mask); + _log.info("selectHighCap("+howMany+"), not enough highcap (" + matches.size() + ") going on to ANFP2"); + selectActiveNotFailingPeers2(howMany, exclude, matches, mask); } else { if (_log.shouldLog(Log.INFO)) _log.info("selectHighCap("+howMany+"), found enough highCap (" + matches.size() + ")"); @@ -375,6 +375,7 @@ public class ProfileOrganizer { selectAllNotFailingPeers(howMany, exclude, matches, onlyNotFailing, mask); return; } + /** * Return a set of Hashes for peers that are both not failing and we're actively * talking with. @@ -403,6 +404,39 @@ public class ProfileOrganizer { } } + /** + * Return a set of Hashes for peers that are both not failing and we're actively + * talking with. + * + * We use commSystem().isEstablished(), not profile.getIsActive(), as the + * NTCP idle time is now shorter than the 5 minute getIsActive() threshold, + * and we're using this to try and limit connections. + * + * This DOES cascade further to non-connected peers. + */ + private void selectActiveNotFailingPeers2(int howMany, Set exclude, Set matches, int mask) { + if (matches.size() < howMany) { + Map activePeers = new HashMap(); + getReadLock(); + try { + for (Iterator> iter = _notFailingPeers.entrySet().iterator(); iter.hasNext(); ) { + Map.Entry e = iter.next(); + if (_context.commSystem().isEstablished(e.getKey())) + activePeers.put(e.getKey(), e.getValue()); + } + locked_selectPeers(activePeers, howMany, exclude, matches, mask); + } finally { releaseReadLock(); } + } + if (matches.size() < howMany) { + if (_log.shouldLog(Log.INFO)) + _log.info("selectANFP2("+howMany+"), not enough ANFP (" + matches.size() + ") going on to notFailing"); + selectNotFailingPeers(howMany, exclude, matches, mask); + } else { + if (_log.shouldLog(Log.INFO)) + _log.info("selectANFP2("+howMany+"), found enough ANFP (" + matches.size() + ")"); + } + } + /** * Return a set of Hashes for peers that are not failing. * @@ -520,8 +554,8 @@ public class ProfileOrganizer { } } } - if (_log.shouldLog(Log.INFO)) - _log.info("Unreachable: " + l); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Unreachable: " + l); return l; } diff --git a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java index 04d4f8d23..03d3071bb 100644 --- a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java +++ b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java @@ -73,6 +73,8 @@ public class CommSystemFacadeImpl extends CommSystemFacade { public boolean haveInboundCapacity() { return (_manager == null ? false : _manager.haveInboundCapacity()); } @Override public boolean haveOutboundCapacity() { return (_manager == null ? false : _manager.haveOutboundCapacity()); } + @Override + public boolean haveHighOutboundCapacity() { return (_manager == null ? false : _manager.haveHighOutboundCapacity()); } /** * Framed average clock skew of connected peers in seconds, or null if we cannot answer. diff --git a/router/java/src/net/i2p/router/transport/Transport.java b/router/java/src/net/i2p/router/transport/Transport.java index fc5c32153..d0ec7267b 100644 --- a/router/java/src/net/i2p/router/transport/Transport.java +++ b/router/java/src/net/i2p/router/transport/Transport.java @@ -47,6 +47,7 @@ public interface Transport { public int countActivePeers(); public int countActiveSendPeers(); public boolean haveCapacity(); + public boolean haveHighCapacity(); public Vector getClockSkews(); public List getMostRecentErrorMessages(); diff --git a/router/java/src/net/i2p/router/transport/TransportManager.java b/router/java/src/net/i2p/router/transport/TransportManager.java index 9afdaf333..c61ed14f8 100644 --- a/router/java/src/net/i2p/router/transport/TransportManager.java +++ b/router/java/src/net/i2p/router/transport/TransportManager.java @@ -215,6 +215,20 @@ public class TransportManager implements TransportEventListener { return false; } + /** + * Are all transports well below their outbound connection limit + * Use for throttling in the router. + */ + public boolean haveHighOutboundCapacity() { + if (_transports.size() <= 0) + return false; + for (int i = 0; i < _transports.size(); i++) { + if (!((Transport)_transports.get(i)).haveHighCapacity()) + return false; + } + return true; + } + /** * Is at least one transport below its inbound connection limit + some margin * Use for throttling in the router. diff --git a/router/java/src/net/i2p/router/transport/UPnP.java b/router/java/src/net/i2p/router/transport/UPnP.java index b8572f726..bf967db4e 100644 --- a/router/java/src/net/i2p/router/transport/UPnP.java +++ b/router/java/src/net/i2p/router/transport/UPnP.java @@ -47,9 +47,11 @@ import org.freenetproject.ForwardPortStatus; * * some code has been borrowed from Limewire : @see com.limegroup.gnutella.UPnPManager * - * @see http://www.upnp.org/ - * @see http://en.wikipedia.org/wiki/Universal_Plug_and_Play - * + * @see "http://www.upnp.org/" + * @see "http://en.wikipedia.org/wiki/Universal_Plug_and_Play" + */ + +/* * TODO: Support multiple IGDs ? * TODO: Advertise the node like the MDNS plugin does * TODO: Implement EventListener and react on ip-change diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPSendFinisher.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPSendFinisher.java index 8d19c6249..207db4c3c 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPSendFinisher.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPSendFinisher.java @@ -42,7 +42,8 @@ public class NTCPSendFinisher { } public void stop() { - _executor.shutdownNow(); + if (_executor != null) + _executor.shutdownNow(); } public void add(OutNetMessage msg) { diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java index 75564fb9e..9f6b8e7ca 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java @@ -326,6 +326,10 @@ public class NTCPTransport extends TransportImpl { return countActivePeers() < getMaxConnections() * 4 / 5; } + public boolean haveHighCapacity() { + return countActivePeers() < getMaxConnections() / 2; + } + /** queue up afterSend call, which can take some time w/ jobs, etc */ void sendComplete(OutNetMessage msg) { _finisher.add(msg); } diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java index e1e816d1a..b42efbfae 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -386,8 +386,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority * Todo: * - Much better tracking of troublemakers * - Disable if we have good local address or UPnP - * - * @param ip publicly routable IPv4 only + * + * @param from Hash of inbound destination + * @param ourIP publicly routable IPv4 only * @param ourPort >= 1024 */ void externalAddressReceived(Hash from, byte ourIP[], int ourPort) { @@ -1381,6 +1382,12 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority } } + public boolean haveHighCapacity() { + synchronized (_peersByIdent) { + return _peersByIdent.size() < getMaxConnections() / 2; + } + } + /** * Return our peer clock skews on this transport. * Vector composed of Long, each element representing a peer skew in seconds. diff --git a/router/java/src/net/i2p/router/tunnel/pool/ExploratoryPeerSelector.java b/router/java/src/net/i2p/router/tunnel/pool/ExploratoryPeerSelector.java index b324990de..8971b8ba3 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/ExploratoryPeerSelector.java +++ b/router/java/src/net/i2p/router/tunnel/pool/ExploratoryPeerSelector.java @@ -47,7 +47,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector { // if (exploreHighCap) ctx.profileOrganizer().selectHighCapacityPeers(length, exclude, matches); - else if (ctx.commSystem().haveOutboundCapacity()) + else if (ctx.commSystem().haveHighOutboundCapacity()) ctx.profileOrganizer().selectNotFailingPeers(length, exclude, matches, false); else // use only connected peers so we don't make more connections ctx.profileOrganizer().selectActiveNotFailingPeers(length, exclude, matches); diff --git a/router/java/src/org/xmlpull/v1/XmlPullParser.java b/router/java/src/org/xmlpull/v1/XmlPullParser.java index 24a34d2de..076732a24 100644 --- a/router/java/src/org/xmlpull/v1/XmlPullParser.java +++ b/router/java/src/org/xmlpull/v1/XmlPullParser.java @@ -815,7 +815,7 @@ public interface XmlPullParser { * Namespaces in XML * specification to "http://www.w3.org/XML/1998/namespace". * - * @param zero based index of attribute + * @param index zero based index of attribute * @return attribute namespace, * empty string ("") is returned if namesapces processing is not enabled or * namespaces processing is enabled but attribute has no namespace (it has no prefix). @@ -828,7 +828,7 @@ public interface XmlPullParser { * Throws an IndexOutOfBoundsException if the index is out of range * or current event type is not START_TAG. * - * @param zero based index of attribute + * @param index zero based index of attribute * @return attribute name (null is never returned) */ String getAttributeName (int index); @@ -840,7 +840,7 @@ public interface XmlPullParser { * Throws an IndexOutOfBoundsException if the index is out of range * or current event type is not START_TAG. * - * @param zero based index of attribute + * @param index zero based index of attribute * @return attribute prefix or null if namespaces processing is not enabled. */ String getAttributePrefix(int index); @@ -849,7 +849,7 @@ public interface XmlPullParser { * Returns the type of the specified attribute * If parser is non-validating it MUST return CDATA. * - * @param zero based index of attribute + * @param index zero based index of attribute * @return attribute type (null is never returned) */ String getAttributeType(int index); @@ -859,7 +859,7 @@ public interface XmlPullParser { * If parser is non-validating it MUST always return false. * This information is part of XML infoset: * - * @param zero based index of attribute + * @param index zero based index of attribute * @return false if attribute was in input */ boolean isAttributeDefault(int index); @@ -876,7 +876,7 @@ public interface XmlPullParser { * * @see #defineEntityReplacementText * - * @param zero based index of attribute + * @param index zero based index of attribute * @return value of attribute (null is never returned) */ String getAttributeValue(int index);