From 8054078b9eba0402a6220e5bb383c85ae8bdf153 Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 23 Apr 2009 20:20:37 +0000 Subject: [PATCH 01/10] -2 --- history.txt | 25 ++++++++++++++++++- .../src/net/i2p/router/RouterVersion.java | 2 +- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/history.txt b/history.txt index 50315edcd..734e1f70f 100644 --- a/history.txt +++ b/history.txt @@ -1,5 +1,28 @@ +2009-04-23 zzz + * Blocklist: cleanup + * eepget: handle -h, --help, bad options, etc. + (http://forum.i2p/viewtopic.php?p=16261#16261) + * Fragmenter: don't re-throw the corrupt fragment IllegalStateException, + to limit the damage - root cause still not found + * i2psnark: (http://forum.i2p/viewtopic.php?t=3317) + - Change file limit to 512 (was 256) + - Change size limit to 10GB (was 5GB) + - Change request size to 16KB (was 32KB) + - Change pipeline to 5 (was 3) + * logs.jsp: Move version info to the top + * Jetty: Fix temp dir name handling on windows, which was + causing susidns not to start + (http://forum.i2p/viewtopic.php?t=3364) + * NTCP: Prevent IllegalStateException + * PeerProfile: + - Replace a hot lock with concurrent RW lock + - Rewrite ugly IP Restriction code + - Also use transport IP in restriction code + * RouterConsole: Make summary bar a refreshing iframe + * Transport: Start the previously unused CleanupUnreachable + 2009-04-21 sponge - * Code janator work, basic corrections involving @Override, and + * Code janitor work, basic corrections involving @Override, and appling final where it is important. Also fixed some equals methods and commented places that need fixing. diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 1d4797d6f..a727710d6 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -17,7 +17,7 @@ import net.i2p.CoreVersion; public class RouterVersion { public final static String ID = "$Revision: 1.548 $ $Date: 2008-06-07 23:00:00 $"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 1; + public final static long BUILD = 2; public static void main(String args[]) { System.out.println("I2P Router version: " + VERSION + "-" + BUILD); System.out.println("Router ID: " + RouterVersion.ID); From f331dad72de65609d04fcb0cf1428a2d9818bdda Mon Sep 17 00:00:00 2001 From: sponge Date: Sat, 25 Apr 2009 00:02:38 +0000 Subject: [PATCH 02/10] 2009-04-25 sponge * I2PSessionMuxedImpl atomic fixes * BOB fixes. This should be the final bug wack. Good Luck to everybody! --- apps/BOB/src/net/i2p/BOB/DoCMDS.java | 10 ++-- apps/BOB/src/net/i2p/BOB/MUXlisten.java | 45 ++++++++++++++-- .../net/i2p/client/I2PSessionMuxedImpl.java | 54 ++++++++++++------- history.txt | 4 ++ .../src/net/i2p/router/RouterVersion.java | 2 +- 5 files changed, 86 insertions(+), 29 deletions(-) diff --git a/apps/BOB/src/net/i2p/BOB/DoCMDS.java b/apps/BOB/src/net/i2p/BOB/DoCMDS.java index 16da28ce9..1a2d2a19a 100644 --- a/apps/BOB/src/net/i2p/BOB/DoCMDS.java +++ b/apps/BOB/src/net/i2p/BOB/DoCMDS.java @@ -1263,11 +1263,11 @@ public class DoCMDS implements Runnable { tunnel = new MUXlisten(database, nickinfo, _log); Thread t = new Thread(tunnel); t.start(); - try { - Thread.sleep(1000 * 10); // Slow down the startup. - } catch(InterruptedException ie) { - // ignore it - } + // try { + // Thread.sleep(1000 * 10); // Slow down the startup. + // } catch(InterruptedException ie) { + // // ignore it + // } out.println("OK tunnel starting"); } catch (I2PException e) { out.println("ERROR starting tunnel: " + e); diff --git a/apps/BOB/src/net/i2p/BOB/MUXlisten.java b/apps/BOB/src/net/i2p/BOB/MUXlisten.java index dc30c5445..cf65a0b12 100644 --- a/apps/BOB/src/net/i2p/BOB/MUXlisten.java +++ b/apps/BOB/src/net/i2p/BOB/MUXlisten.java @@ -133,7 +133,7 @@ public class MUXlisten implements Runnable { */ public void run() { I2PServerSocket SS = null; - int ticks = 1200; // Allow 120 seconds, no more. + int ticks = 100; // Allow 10 seconds, no more. try { wlock(); try { @@ -267,7 +267,6 @@ die: // System.out.println("MUXlisten: waiting for children"); if (tg.activeCount() + tg.activeGroupCount() != 0) { while ((tg.activeCount() + tg.activeGroupCount() != 0) && ticks != 0) { - tg.interrupt(); // unwedge any blocking threads. ticks--; try { Thread.sleep(100); //sleep for 100 ms (One tenth second) @@ -308,7 +307,7 @@ die: } catch (Exception e) { // nop } - ticks = 600; // 60 seconds + ticks = 100; // 10 seconds if (tg.activeCount() + tg.activeGroupCount() != 0) { while ((tg.activeCount() + tg.activeGroupCount() != 0) && ticks != 0) { tg.interrupt(); // unwedge any blocking threads. @@ -325,10 +324,14 @@ die: // Zap reference to the ThreadGroup so the JVM can GC it. tg = null; } else { - System.out.println("BOB: MUXlisten: Can't kill threads. Please send the following dump to sponge@mail.i2p"); + System.out.println("BOB: MUXlisten: Forcibly killing threads."); System.out.println("\n\nBOB: MUXlisten: ThreadGroup dump BEGIN"); visit(tg, 0); System.out.println("BOB: MUXlisten: ThreadGroup dump END\n\n"); + nuke(tg,0); + tg.destroy(); + // Zap reference to the ThreadGroup so the JVM can GC it. + tg = null; } } @@ -354,7 +357,6 @@ die: wunlock(); } catch (Exception e) { } - } @@ -402,4 +404,37 @@ die: visit(groups[i], level + 1); } } + 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/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java b/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java index a3e5e57a7..a906dbcf8 100644 --- a/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java +++ b/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java @@ -4,18 +4,16 @@ package net.i2p.client; * public domain */ -import java.io.IOException; import java.io.InputStream; import java.util.concurrent.LinkedBlockingQueue; -import java.util.HashSet; import java.util.Properties; import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; import net.i2p.I2PAppContext; import net.i2p.data.DataHelper; import net.i2p.data.Destination; import net.i2p.data.SessionKey; -import net.i2p.data.SessionTag; import net.i2p.data.i2cp.MessagePayloadMessage; import net.i2p.util.Log; import net.i2p.util.SimpleScheduler; @@ -97,6 +95,7 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 implements I2PSession { * 255 disallowed * @param port 1-65535 or PORT_ANY for all */ + @Override public void addSessionListener(I2PSessionListener lsnr, int proto, int port) { _demultiplexer.addListener(lsnr, proto, port); } @@ -107,11 +106,13 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 implements I2PSession { * @param proto 1-254 or 0 for all; 255 disallowed * @param port 1-65535 or 0 for all */ + @Override public void addMuxedSessionListener(I2PSessionMuxedListener l, int proto, int port) { _demultiplexer.addMuxedListener(l, proto, port); } /** removes the specified listener (only) */ + @Override public void removeListener(int proto, int port) { _demultiplexer.removeListener(proto, port); } @@ -149,6 +150,7 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 implements I2PSession { * @param fromPort 1-65535 or 0 for unset * @param toPort 1-65535 or 0 for unset */ + @Override public boolean sendMessage(Destination dest, byte[] payload, int offset, int size, SessionKey keyUsed, Set tagsSent, long expires, int proto, int fromPort, int toPort) @@ -198,24 +200,36 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 implements I2PSession { protected class MuxedAvailabilityNotifier extends AvailabilityNotifier { private LinkedBlockingQueue _msgs; - private boolean _alive; + private AtomicBoolean _alive = new AtomicBoolean(false); private static final int POISON_SIZE = -99999; public MuxedAvailabilityNotifier() { _msgs = new LinkedBlockingQueue(); } - - public void stopNotifying() { - _msgs.clear(); - if (_alive) { - _alive = false; - try { - _msgs.put(new MsgData(0, POISON_SIZE, 0, 0, 0)); - } catch (InterruptedException ie) {} + + @Override + public void stopNotifying() { + boolean again = true; + _msgs.clear(); + // Thread.yield(); + if (_alive.get()) { + // System.out.println("I2PSessionMuxedImpl.stopNotifying()"); + while(again) { + _msgs.clear(); + try { + _msgs.put(new MsgData(0, POISON_SIZE, 0, 0, 0)); + again = false; + // System.out.println("I2PSessionMuxedImpl.stopNotifying() success."); + } catch (InterruptedException ie) { + continue; + } + } } + _alive.set(false); } /** unused */ + @Override public void available(long msgId, int size) { throw new IllegalArgumentException("no"); } public void available(long msgId, int size, int proto, int fromPort, int toPort) { @@ -224,20 +238,24 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 implements I2PSession { } catch (InterruptedException ie) {} } + @Override public void run() { - _alive = true; - while (true) { - MsgData msg; + MsgData msg; + _alive.set(true); + while (_alive.get()) { try { msg = _msgs.take(); } catch (InterruptedException ie) { + System.out.println("I2PSessionMuxedImpl.run() InterruptedException " + String.valueOf(_msgs.size()) + " Messages, Alive " + _alive.toString()); continue; } - if (msg.size == POISON_SIZE) + if (msg.size == POISON_SIZE) { + // System.out.println("I2PSessionMuxedImpl.run() POISONED"); break; + } try { - _demultiplexer.messageAvailable(I2PSessionMuxedImpl.this, msg.id, - msg.size, msg.proto, msg.fromPort, msg.toPort); + _demultiplexer.messageAvailable(I2PSessionMuxedImpl.this, + msg.id, msg.size, msg.proto, msg.fromPort, msg.toPort); } catch (Exception e) { _log.error("Error notifying app of message availability"); } diff --git a/history.txt b/history.txt index 734e1f70f..29c4157ed 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,7 @@ +2009-04-25 sponge + * I2PSessionMuxedImpl atomic fixes + * BOB fixes. This should be the final bug wack. Good Luck to everybody! + 2009-04-23 zzz * Blocklist: cleanup * eepget: handle -h, --help, bad options, etc. diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index a727710d6..a34e9238c 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -17,7 +17,7 @@ import net.i2p.CoreVersion; public class RouterVersion { public final static String ID = "$Revision: 1.548 $ $Date: 2008-06-07 23:00:00 $"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 2; + public final static long BUILD = 3; public static void main(String args[]) { System.out.println("I2P Router version: " + VERSION + "-" + BUILD); System.out.println("Router ID: " + RouterVersion.ID); From 542e0f2ed30a40170e9bbf11a44e2abcc1669299 Mon Sep 17 00:00:00 2001 From: zzz Date: Mon, 27 Apr 2009 15:02:05 +0000 Subject: [PATCH 03/10] -4 --- history.txt | 18 ++++++++++++++++++ .../java/src/net/i2p/router/RouterVersion.java | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index 29c4157ed..0972cc484 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,21 @@ +2009-04-27 zzz + * Build files: + - New updaterWithJettyFixes target, build it for pkg + - Pass compiler args down from top build.xml + * GarlicMessageBuilder: Reduce bundled tags to 40 (was 100) + * i2psnark: Add Postman2 tracker + * I2PTunnel: Allow spaces in dest and proxy lists + * NetDb: + - Adjust RouterInfo expiration down to control memory usage + - Display LeaseSets and RouterInfos on separate console pages + * NTCP: + - Correct the meanings of the i2np.ntcp.autoip and i2np.ntcp.autoport + advanced config. If you have one of these set but not the other, you + will have to adjust your configuration on config.jsp. + * RouterConsole: iframe tweaks + * StatisticsManager: Cleanup + * Streaming: Don't let jrandom yell so loud + 2009-04-25 sponge * I2PSessionMuxedImpl atomic fixes * BOB fixes. This should be the final bug wack. Good Luck to everybody! diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index a34e9238c..5f58c2cdd 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -17,7 +17,7 @@ import net.i2p.CoreVersion; public class RouterVersion { public final static String ID = "$Revision: 1.548 $ $Date: 2008-06-07 23:00:00 $"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 3; + public final static long BUILD = 4; public static void main(String args[]) { System.out.println("I2P Router version: " + VERSION + "-" + BUILD); System.out.println("Router ID: " + RouterVersion.ID); From c1d7562331f13cce1c8d4151426efa86ade1060e Mon Sep 17 00:00:00 2001 From: sponge Date: Mon, 27 Apr 2009 17:09:47 +0000 Subject: [PATCH 04/10] 2009-04-27 sponge * more BOB fixes, complete with warnings when things go wrong, and success messages when things turn around and go right. Terminates early so that applications wait no more than 10 seconds or so. * Reversed a few earlier patches that caused some odd behavior. * Changed some core println()'s to debugging messages. --- apps/BOB/src/net/i2p/BOB/I2Plistener.java | 42 +---- apps/BOB/src/net/i2p/BOB/I2PtoTCP.java | 1 - apps/BOB/src/net/i2p/BOB/MUXlisten.java | 173 +++++++++++------- apps/BOB/src/net/i2p/BOB/TCPio.java | 13 -- apps/BOB/src/net/i2p/BOB/TCPlistener.java | 67 +------ apps/BOB/src/net/i2p/BOB/TCPtoI2P.java | 7 +- .../client/streaming/ConnectionHandler.java | 4 +- .../net/i2p/client/streaming/PacketLocal.java | 2 +- .../src/net/i2p/client/I2PSessionImpl.java | 6 +- .../net/i2p/client/I2PSessionMuxedImpl.java | 2 +- history.txt | 7 + .../src/net/i2p/router/RouterVersion.java | 2 +- 12 files changed, 124 insertions(+), 202 deletions(-) diff --git a/apps/BOB/src/net/i2p/BOB/I2Plistener.java b/apps/BOB/src/net/i2p/BOB/I2Plistener.java index a8115893d..3bb94e0b3 100644 --- a/apps/BOB/src/net/i2p/BOB/I2Plistener.java +++ b/apps/BOB/src/net/i2p/BOB/I2Plistener.java @@ -82,18 +82,6 @@ public class I2Plistener implements Runnable { die: { serverSocket.setSoTimeout(50); -// try { -// if (info.exists("INPORT")) { -// tgwatch = 2; -// } -// } catch (Exception e) { -// try { -// runlock(); -// } catch (Exception e2) { -// break die; -// } -// break die; -// } boolean spin = true; while (spin) { @@ -129,40 +117,12 @@ die: { t.start(); } - } catch (I2PException e) { + } catch (Exception e) { // System.out.println("Exception " + e); } } } // System.out.println("I2Plistener: Close"); - - - // Previous level does this cleanup now. - // - // try { - // serverSocket.close(); - // } catch (I2PException e) { - // nop - //} - // need to kill off the socket manager too. - // I2PSession session = socketManager.getSession(); - // if (session != null) { - // System.out.println("I2Plistener: destroySession"); - // try { - // session.destroySession(); - // } catch (I2PSessionException ex) { - // nop - // } - //} - // System.out.println("I2Plistener: Waiting for children"); - // while (Thread.activeCount() > tgwatch) { // wait for all threads in our threadgroup to finish - // try { - // Thread.sleep(100); //sleep for 100 ms (One tenth second) - // } catch (Exception e) { - // nop - // } - //} - // System.out.println("I2Plistener: Done."); } } diff --git a/apps/BOB/src/net/i2p/BOB/I2PtoTCP.java b/apps/BOB/src/net/i2p/BOB/I2PtoTCP.java index 0984823b6..ad5e2701b 100644 --- a/apps/BOB/src/net/i2p/BOB/I2PtoTCP.java +++ b/apps/BOB/src/net/i2p/BOB/I2PtoTCP.java @@ -23,7 +23,6 @@ */ package net.i2p.BOB; -import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; diff --git a/apps/BOB/src/net/i2p/BOB/MUXlisten.java b/apps/BOB/src/net/i2p/BOB/MUXlisten.java index cf65a0b12..2c7a64924 100644 --- a/apps/BOB/src/net/i2p/BOB/MUXlisten.java +++ b/apps/BOB/src/net/i2p/BOB/MUXlisten.java @@ -152,11 +152,11 @@ public class MUXlisten implements Runnable { } // socketManager.addDisconnectListener(new DisconnectListener()); -quit: + quit: { try { tg = new ThreadGroup(N); -die: + die: { // toss the connections to a new threads. // will wrap with TCP and UDP when UDP works @@ -255,7 +255,7 @@ die: try { session.destroySession(); } catch (I2PSessionException ex) { - // nop + // nop } } try { @@ -266,6 +266,7 @@ die: // Wait for child threads and thread groups to die // System.out.println("MUXlisten: waiting for children"); if (tg.activeCount() + tg.activeGroupCount() != 0) { + tg.interrupt(); // give my stuff a small smack. while ((tg.activeCount() + tg.activeGroupCount() != 0) && ticks != 0) { ticks--; try { @@ -287,62 +288,6 @@ die: } } // quit - // This is here to catch when something fucks up REALLY bad. - if (tg != null) { - if (SS != null) { - try { - SS.close(); - } catch (I2PException ex) { - //Logger.getLogger(MUXlisten.class.getName()).log(Level.SEVERE, null, ex); - } - } - if (this.come_in) { - try { - listener.close(); - } catch (IOException e) { - } - } - try { - socketManager.destroySocketManager(); - } catch (Exception e) { - // nop - } - ticks = 100; // 10 seconds - if (tg.activeCount() + tg.activeGroupCount() != 0) { - while ((tg.activeCount() + tg.activeGroupCount() != 0) && ticks != 0) { - tg.interrupt(); // unwedge any blocking threads. - ticks--; - try { - Thread.sleep(100); //sleep for 100 ms (One tenth second) - } catch (InterruptedException ex) { - // nop - } - } - } - if (tg.activeCount() + tg.activeGroupCount() == 0) { - tg.destroy(); - // Zap reference to the ThreadGroup so the JVM can GC it. - tg = null; - } else { - System.out.println("BOB: MUXlisten: Forcibly killing threads."); - System.out.println("\n\nBOB: MUXlisten: ThreadGroup dump BEGIN"); - visit(tg, 0); - System.out.println("BOB: MUXlisten: ThreadGroup dump END\n\n"); - nuke(tg,0); - tg.destroy(); - // Zap reference to the ThreadGroup so the JVM can GC it. - tg = null; - } - } - - // This is here to catch when something fucks up REALLY bad. -// if (tg != null) { -// System.out.println("BOB: MUXlisten: Something fucked up REALLY bad!"); -// System.out.println("BOB: MUXlisten: Please email the following dump to sponge@mail.i2p"); -// WrapperManager.requestThreadDump(); -// System.out.println("BOB: MUXlisten: Something fucked up REALLY bad!"); -// System.out.println("BOB: MUXlisten: Please email the above dump to sponge@mail.i2p"); -// } // zero out everything. try { wlock(); @@ -357,11 +302,102 @@ die: wunlock(); } catch (Exception e) { } + + // This is here to catch when something fucks up REALLY bad, like those annoying stuck threads! + if (tg != null) { + tg.interrupt(); // give my stuff a small smack again. + if (SS != null) { + try { + SS.close(); + } catch (I2PException ex) { + //Logger.getLogger(MUXlisten.class.getName()).log(Level.SEVERE, null, ex); + } + } + if (this.come_in) { + try { + listener.close(); + } catch (IOException e) { + } + } + I2PSession session = socketManager.getSession(); + if (session != null) { + // System.out.println("I2Plistener: destroySession"); + try { + session.destroySession(); + } catch (I2PSessionException ex) { + // nop + } + } + try { + socketManager.destroySocketManager(); + } catch (Exception e) { + // nop + } + // ticks = 100; // 10 seconds + if (tg.activeCount() + tg.activeGroupCount() != 0) { + int foo = tg.activeCount() + tg.activeGroupCount(); + int bar = foo; + String boner = tg.getName(); + System.out.println("BOB: MUXlisten: Waiting on threads for " + boner); + System.out.println("\n\nBOB: MUXlisten: ThreadGroup dump BEGIN " + boner); + visit(tg, 0, boner); + System.out.println("BOB: MUXlisten: ThreadGroup dump END " + boner + "\n\n"); + // Happily spin forever :-( + while ((tg.activeCount() + tg.activeGroupCount() != 0)) { + foo = tg.activeCount() + tg.activeGroupCount(); + if (foo != bar) { + System.out.println("\n\nBOB: MUXlisten: ThreadGroup dump BEGIN " + boner); + visit(tg, 0, boner); + System.out.println("BOB: MUXlisten: ThreadGroup dump END " + boner + "\n\n"); + } + bar = foo; + try { + session = socketManager.getSession(); + if (session != null) { + // System.out.println("I2Plistener: destroySession"); + try { + session.destroySession(); + } catch (I2PSessionException ex) { + // nop + } + } + try { + socketManager.destroySocketManager(); + } catch (Exception e) { + // nop + } + } catch (Exception e) { + // nop + } + // tg.interrupt(); // unwedge any blocking threads. + // ticks--; + try { + Thread.sleep(100); //sleep for 100 ms (One tenth second) + } catch (InterruptedException ex) { + // nop + } + } + System.out.println("BOB: MUXlisten: Threads went away. Success: " + boner); + } +// if (tg.activeCount() + tg.activeGroupCount() == 0) { + tg.destroy(); + // Zap reference to the ThreadGroup so the JVM can GC it. + tg = null; +// } else { +// System.out.println("BOB: MUXlisten: Forcibly killing threads."); +// System.out.println("\n\nBOB: MUXlisten: ThreadGroup dump BEGIN"); +// visit(tg, 0); +// System.out.println("BOB: MUXlisten: ThreadGroup dump END\n\n"); +// nuke(tg,0); +// tg.destroy(); +// // Zap reference to the ThreadGroup so the JVM can GC it. +// tg = null; +// } + } } // Debugging... - /** * Find the root thread group and print them all. * @@ -373,7 +409,7 @@ die: } // Visit each thread group - visit(root, 0); + visit(root, 0, root.getName()); } /** @@ -381,7 +417,7 @@ die: * @param group ThreadGroup to visit * @param level Current level */ - private static void visit(ThreadGroup group, int level) { + private static void visit(ThreadGroup group, int level, String tn) { // Get threads in `group' int numThreads = group.activeCount(); Thread[] threads = new Thread[numThreads * 2]; @@ -391,7 +427,7 @@ die: for (int i = 0; i < numThreads; i++) { // Get thread Thread thread = threads[i]; - System.out.println("BOB: MUXlisten: " + indent + thread.toString()); + System.out.println("BOB: MUXlisten: " + tn + ": " + indent + thread.toString()); } // Get thread subgroups of `group' @@ -401,9 +437,10 @@ die: // Recursively visit each subgroup for (int i = 0; i < numGroups; i++) { - visit(groups[i], level + 1); + visit(groups[i], level + 1, groups[i].getName()); } } + private static void nuke(ThreadGroup group, int level) { // Get threads in `group' int numThreads = group.activeCount(); @@ -414,8 +451,10 @@ die: // Get thread Thread thread = threads[i]; try { - if(thread.isAlive()) thread.stop(); - } catch(SecurityException se) { + if (thread.isAlive()) { + thread.stop(); + } + } catch (SecurityException se) { //nop } } @@ -433,7 +472,7 @@ die: group.destroy(); } catch (IllegalThreadStateException IE) { //nop - } catch(SecurityException se) { + } catch (SecurityException se) { //nop } } diff --git a/apps/BOB/src/net/i2p/BOB/TCPio.java b/apps/BOB/src/net/i2p/BOB/TCPio.java index d4b353c54..d92a5cef0 100644 --- a/apps/BOB/src/net/i2p/BOB/TCPio.java +++ b/apps/BOB/src/net/i2p/BOB/TCPio.java @@ -87,23 +87,13 @@ public class TCPio implements Runnable { boolean spin = true; try { while(spin) { - // database.getReadLock(); - // info.getReadLock(); - // spin = info.get("RUNNING").equals(Boolean.TRUE); - // info.releaseReadLock(); - // database.releaseReadLock(); b = Ain.read(a, 0, 1); - // System.out.println(info.get("NICKNAME").toString() + " " + b); if(b > 0) { Aout.write(a, 0, b); } else if(b == 0) { Thread.yield(); // this should act like a mini sleep. if(Ain.available() == 0) { -// try { - // Thread.yield(); Thread.sleep(10); -// } catch(InterruptedException ex) { -// } } } else { /* according to the specs: @@ -119,19 +109,16 @@ public class TCPio implements Runnable { return; } } - // System.out.println("TCPio: RUNNING = false"); } catch(Exception e) { // Eject!!! Eject!!! //System.out.println("TCPio: Caught an exception " + e); try { Ain.close(); } catch (IOException ex) { -// Logger.getLogger(TCPio.class.getName()).log(Level.SEVERE, null, ex); } try { Aout.close(); } catch (IOException ex) { -// Logger.getLogger(TCPio.class.getName()).log(Level.SEVERE, null, ex); } return; } diff --git a/apps/BOB/src/net/i2p/BOB/TCPlistener.java b/apps/BOB/src/net/i2p/BOB/TCPlistener.java index 78155eb78..4ce888090 100644 --- a/apps/BOB/src/net/i2p/BOB/TCPlistener.java +++ b/apps/BOB/src/net/i2p/BOB/TCPlistener.java @@ -73,16 +73,6 @@ public class TCPlistener implements Runnable { info.releaseReadLock(); } - private void wlock() throws Exception { - database.getWriteLock(); - info.getWriteLock(); - } - - private void wunlock() throws Exception { - info.releaseWriteLock(); - database.releaseWriteLock(); - } - /** * Simply listen on TCP port, and thread connections * @@ -116,7 +106,7 @@ die: { } try { Socket server = new Socket(); - listener.setSoTimeout(50); // Half of the expected time from MUXlisten + listener.setSoTimeout(50); // We don't block, we cycle and check. while (spin) { try { rlock(); @@ -141,73 +131,20 @@ die: { } if (g) { // toss the connection to a new thread. - TCPtoI2P conn_c = new TCPtoI2P(socketManager, server /* , info, database */); + TCPtoI2P conn_c = new TCPtoI2P(socketManager, server); Thread t = new Thread(conn_c, "BOBTCPtoI2P"); t.start(); g = false; } } - //System.out.println("TCPlistener: destroySession"); listener.close(); } catch (IOException ioe) { try { listener.close(); } catch (IOException e) { } - // Fatal failure, cause a stop event - try { - rlock(); - try { - spin = info.get("RUNNING").equals(Boolean.TRUE); - } catch (Exception e) { - runlock(); - break die; - } - } catch (Exception e) { - break die; - } - if (spin) { - try { - wlock(); - try { - info.add("STOPPING", new Boolean(true)); - info.add("RUNNING", new Boolean(false)); - } catch (Exception e) { - wunlock(); - break die; - } - } catch (Exception e) { - break die; - } - try { - wunlock(); - } catch (Exception e) { - break die; - } - } } } - // Previous level does this cleanup now. - // - // need to kill off the socket manager too. - // I2PSession session = socketManager.getSession(); - // if (session != null) { - // try { - // session.destroySession(); - // } catch (I2PSessionException ex) { - // nop - // } - //} - //System.out.println("TCPlistener: Waiting for children"); - //while (Thread.activeCount() > tgwatch) { // wait for all threads in our threadgroup to finish - // try { - // Thread.sleep(100); //sleep for 100 ms (One tenth second) - // } catch (Exception e) { - // // nop - // } - //} //System.out.println("TCPlistener: Done."); } } - - diff --git a/apps/BOB/src/net/i2p/BOB/TCPtoI2P.java b/apps/BOB/src/net/i2p/BOB/TCPtoI2P.java index c376e16fe..5fefae017 100644 --- a/apps/BOB/src/net/i2p/BOB/TCPtoI2P.java +++ b/apps/BOB/src/net/i2p/BOB/TCPtoI2P.java @@ -151,13 +151,8 @@ public class TCPtoI2P implements Runnable { t.start(); q.start(); while(t.isAlive() && q.isAlive()) { // AND is used here to kill off the other thread -// try { Thread.sleep(10); //sleep for 10 ms -// } catch(InterruptedException e) { - // nop -// } } - // System.out.println("TCPtoI2P: Going away..."); } catch(I2PException e) { Emsg("ERROR " + e.toString(), out); @@ -166,7 +161,7 @@ public class TCPtoI2P implements Runnable { } catch(NoRouteToHostException e) { Emsg("ERROR " + e.toString(), out); } catch(InterruptedIOException e) { - Emsg("ERROR " + e.toString(), out); + // We're breaking away. } } catch(Exception e) { diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java index 2d198ad66..f4b00c1b5 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java @@ -2,8 +2,6 @@ package net.i2p.client.streaming; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import java.util.ArrayList; -import java.util.List; import net.i2p.I2PAppContext; import net.i2p.util.Log; @@ -126,7 +124,7 @@ class ConnectionHandler { if (timeoutMs <= 0) { try { syn = _synQueue.take(); // waits forever - } catch (InterruptedException ie) { break;} + } catch (InterruptedException ie) { } // { break;} } else { long remaining = expiration - _context.clock().now(); // (dont think this applies anymore for LinkedBlockingQueue) diff --git a/apps/streaming/java/src/net/i2p/client/streaming/PacketLocal.java b/apps/streaming/java/src/net/i2p/client/streaming/PacketLocal.java index 197b92754..827be5b04 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/PacketLocal.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/PacketLocal.java @@ -213,7 +213,7 @@ public class PacketLocal extends Packet implements MessageOutputStream.WriteStat timeRemaining = 10*1000; wait(timeRemaining); } - } catch (InterruptedException ie) { break; } + } catch (InterruptedException ie) { }//{ break; } } if (!writeSuccessful()) releasePayload(); diff --git a/core/java/src/net/i2p/client/I2PSessionImpl.java b/core/java/src/net/i2p/client/I2PSessionImpl.java index 9e42eef5f..a5d8ed94d 100644 --- a/core/java/src/net/i2p/client/I2PSessionImpl.java +++ b/core/java/src/net/i2p/client/I2PSessionImpl.java @@ -16,7 +16,6 @@ import java.net.Socket; import java.net.UnknownHostException; import java.util.concurrent.ConcurrentHashMap; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -90,7 +89,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa protected I2PAppContext _context; /** monitor for waiting until a lease set has been granted */ - private Object _leaseSetWait = new Object(); + private final Object _leaseSetWait = new Object(); /** whether the session connection has already been closed (or not yet opened) */ protected boolean _closed; @@ -101,7 +100,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa /** have we received the current date from the router yet? */ private boolean _dateReceived; /** lock that we wait upon, that the SetDateMessageHandler notifies */ - private Object _dateReceivedLock = new Object(); + private final Object _dateReceivedLock = new Object(); /** * thread that we tell when new messages are available who then tells us @@ -253,6 +252,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa try { if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "connect begin to " + _hostname + ":" + _portNum); _socket = new Socket(_hostname, _portNum); + // _socket.setSoTimeout(1000000); // Uhmmm we could really-really use a real timeout, and handle it. _out = _socket.getOutputStream(); synchronized (_out) { _out.write(I2PClient.PROTOCOL_BYTE); diff --git a/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java b/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java index a906dbcf8..eda48e754 100644 --- a/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java +++ b/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java @@ -246,7 +246,7 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 implements I2PSession { try { msg = _msgs.take(); } catch (InterruptedException ie) { - System.out.println("I2PSessionMuxedImpl.run() InterruptedException " + String.valueOf(_msgs.size()) + " Messages, Alive " + _alive.toString()); + _log.debug("I2PSessionMuxedImpl.run() InterruptedException " + String.valueOf(_msgs.size()) + " Messages, Alive " + _alive.toString()); continue; } if (msg.size == POISON_SIZE) { diff --git a/history.txt b/history.txt index 0972cc484..cfc2af853 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,10 @@ +2009-04-27 sponge + * more BOB fixes, complete with warnings when things go wrong, and + success messages when things turn around and go right. Terminates + early so that applications wait no more than 10 seconds or so. + * Reversed a few earlier patches that caused some odd behavior. + * Changed some core println()'s to debugging messages. + 2009-04-27 zzz * Build files: - New updaterWithJettyFixes target, build it for pkg diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 5f58c2cdd..5203f2360 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -17,7 +17,7 @@ import net.i2p.CoreVersion; public class RouterVersion { public final static String ID = "$Revision: 1.548 $ $Date: 2008-06-07 23:00:00 $"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 4; + public final static long BUILD = 5; public static void main(String args[]) { System.out.println("I2P Router version: " + VERSION + "-" + BUILD); System.out.println("Router ID: " + RouterVersion.ID); From a0c4e79c8a4ab512bf8162ebcf67461a10edd581 Mon Sep 17 00:00:00 2001 From: zzz Date: Tue, 28 Apr 2009 14:13:05 +0000 Subject: [PATCH 05/10] allow an extra part appended to the router version --- .../java/src/net/i2p/router/web/SummaryHelper.java | 2 +- router/java/src/net/i2p/router/Router.java | 3 +-- router/java/src/net/i2p/router/RouterVersion.java | 8 ++++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java index a275e2a61..8663d35fe 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java @@ -48,7 +48,7 @@ public class SummaryHelper extends HelperBase { * */ public String getVersion() { - return RouterVersion.VERSION + "-" + RouterVersion.BUILD; + return RouterVersion.FULL_VERSION; } /** * Retrieve a pretty printed uptime count (ala 4d or 7h or 39m) diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index c9a95dd55..2c9a1319e 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -999,8 +999,7 @@ public class Router { } public static void main(String args[]) { - System.out.println("Starting I2P " + RouterVersion.VERSION + "-" + RouterVersion.BUILD); - System.out.println(RouterVersion.ID); + System.out.println("Starting I2P " + RouterVersion.FULL_VERSION); installUpdates(); verifyWrapperConfig(); Router r = new Router(); diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 5203f2360..46331081d 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -15,11 +15,15 @@ import net.i2p.CoreVersion; * */ public class RouterVersion { - public final static String ID = "$Revision: 1.548 $ $Date: 2008-06-07 23:00:00 $"; + /** deprecated */ + public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; public final static long BUILD = 5; + /** for example "-test" */ + 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: " + VERSION + "-" + BUILD); + System.out.println("I2P Router version: " + FULL_VERSION); System.out.println("Router ID: " + RouterVersion.ID); System.out.println("I2P Core version: " + CoreVersion.VERSION); System.out.println("Core ID: " + CoreVersion.ID); From 7688df6fe5e8cb18b7b876a5a1c8ac1c4967bd86 Mon Sep 17 00:00:00 2001 From: zzz Date: Fri, 1 May 2009 13:03:59 +0000 Subject: [PATCH 06/10] -6 --- history.txt | 20 +++++++++++++++++++ .../src/net/i2p/router/RouterVersion.java | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/history.txt b/history.txt index cfc2af853..8aebfdd1a 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,23 @@ +2009-05-01 zzz + * Build files: + - Fix up susidns build file so it will work with gcj + - Add consoleDocs target + * Client: Fix race NPE (thanks sponge) + * Console: fix ERR-UDP Disabled and Inbound TCP host/port not set + * I2CP: Fix race NPE + * I2PTunnel: + - Try to fix locking to prevent duplicate destinations when using + the new option new-dest-on-resume. Still not right for shared clients + but should be better for non-shared. + * Router console: + - Add jbigi and cpu info to logs.jsp + * Session key manager: + - Log before a hang maybe + * URL Launcher: + - Launcher on linux was stopping after trying opera, whether it succeeded or failed. + Now it keeps going to try firefox, etc. as designed. + - Extend default delay from 5s to 15s so it will reliably start + 2009-04-27 sponge * more BOB fixes, complete with warnings when things go wrong, and success messages when things turn around and go right. Terminates diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 46331081d..0ac10c058 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 5; + public final static long BUILD = 6; /** for example "-test" */ public final static String EXTRA = ""; public final static String FULL_VERSION = VERSION + "-" + BUILD + EXTRA; From 6dc5d0f8d7e8366f910eed0612c76b8ab96fd535 Mon Sep 17 00:00:00 2001 From: zzz Date: Fri, 1 May 2009 13:20:19 +0000 Subject: [PATCH 07/10] add postman2 --- hosts.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/hosts.txt b/hosts.txt index 95ca28af6..b015d95c6 100644 --- a/hosts.txt +++ b/hosts.txt @@ -313,3 +313,4 @@ tracker.mastertracker.i2p=VzXD~stRKbL3MOmeTn1iaCQ0CFyTmuFHiKYyo0Rd~dFPZFCYH-22rT codevoid.i2p=tV-4GJjgYIoCDTTJ91nfDbhSnT8B2o3v-TUfHtiAAjJJdroCAEDbmJWFPUQJEEispvrjNe~fP7VAYkk9fAhSrmdBLtEGB3NUESdiZEPsDtKJBdxijPGb1erZF2Z6eYHoK-t5g7MWWTsgLz~4xn211Jpfa-T4pqL2tcjsa7ixsaMpHF8NXFrITdyxSJRPz8OnHYgDR~ULFyzroi255MpiSUBzGcUZEiQSFLHLhjT5D5tP~gfJirFnfgOHvzWBK9L7y91qY~gYvM2eDcxMxq4Ac1gw0JeahkzAk3j6Spco3LHW3bJvELopf1QmLFu3nfPaegH1Hejt9AhXEH~FV-~M9F1BePipcIYlm7nKyre3aVPLYDZSCvkUx~8nnD3HEpMijD8fdfqSFPU7aZQe19a7rZJUbX~a4M3rBDO-C4uAid6Uznb1tLu2XR1GVVITGHaLwmumImXjlU~1nEnluBQB6iBQPZ9xJccArlYgWSooR9gpyN93PwTPsPe5cPkxCFuxAAAA echelon.i2p=w6zK9m4fqSfvJck9EGIR1wRIbWsEQ2DkjZ-VI57ESFqLqbTIA1cD5nOfSSbpELqPyhjifdrNiBNAsSdyil3C0a2B7CGtwUcTS2dCG0tKf2nAbvpsbcCK17nI4Xbu5KqZU0y3hJ~l7rcJqQBR0nfV5cU30ZDrpQV6VL875cihGlnmwLFq6qSzNcEb88Nw6wFG~FIgB2PJ6A3jJyuTnLrdiMvwqgD6nSyeOylOgBCsNxXh8-drrhASjladfNrwjlGRCZTiQ~H92HIyOwiabDiG3TUugMaFWs87yuXnZ~ni9jgjoAMFo8xV8Od2BiRgCxkZoMU07FhgUjew9qtXNa04wkexf3gx77nVPhqE0GHqCuwHwmBVf92RdYEys76u~akaOMq5UhayDpCBCaHiYLkKDNqmh47tfMCwxf6z8VIcR4zv25QfJDIWPs~RA~9U7m4raytiAs5PvYZBn4B3SqOL8XdkL9sDT54sQXbsYCJr3olu6ieMtNWlmos0uohYXNUyAAAA crstrack.i2p=b4G9sCdtfvccMAXh~SaZrPqVQNyGQbhbYMbw6supq2XGzbjU4NcOmjFI0vxQ8w1L05twmkOvg5QERcX6Mi8NQrWnR0stLExu2LucUXg1aYjnggxIR8TIOGygZVIMV3STKH4UQXD--wz0BUrqaLxPhrm2Eh9Hwc8TdB6Na4ShQUq5Xm8D4elzNUVdpM~RtChEyJWuQvoGAHY3ppX-EJJLkiSr1t77neS4Lc-KofMVmgI9a2tSSpNAagBiNI6Ak9L1T0F9uxeDfEG9bBSQPNMOSUbAoEcNxtt7xOW~cNOAyMyGydwPMnrQ5kIYPY8Pd3XudEko970vE0D6gO19yoBMJpKx6Dh50DGgybLQ9CpRaynh2zPULTHxm8rneOGRcQo8D3mE7FQ92m54~SvfjXjD2TwAVGI~ae~n9HDxt8uxOecAAvjjJ3TD4XM63Q9TmB38RmGNzNLDBQMEmJFpqQU8YeuhnS54IVdUoVQFqui5SfDeLXlSkh4vYoMU66pvBfWbAAAA +tracker2.postman.i2p=lnQ6yoBTxQuQU8EQ1FlF395ITIQF-HGJxUeFvzETLFnoczNjQvKDbtSB7aHhn853zjVXrJBgwlB9sO57KakBDaJ50lUZgVPhjlI19TgJ-CxyHhHSCeKx5JzURdEW-ucdONMynr-b2zwhsx8VQCJwCEkARvt21YkOyQDaB9IdV8aTAmP~PUJQxRwceaTMn96FcVenwdXqleE16fI8CVFOV18jbJKrhTOYpTtcZKV4l1wNYBDwKgwPx5c0kcrRzFyw5~bjuAKO~GJ5dR7BQsL7AwBoQUS4k1lwoYrG1kOIBeDD3XF8BWb6K3GOOoyjc1umYKpur3G~FxBuqtHAsDRICkEbKUqJ9mPYQlTSujhNxiRIW-oLwMtvayCFci99oX8MvazPS7~97x0Gsm-onEK1Td9nBdmq30OqDxpRtXBimbzkLbR1IKObbg9HvrKs3L-kSyGwTUmHG9rSQSoZEvFMA-S0EXO~o4g21q1oikmxPMhkeVwQ22VHB0-LZJfmLr4SAAAA From 7e3bda9d4d9a37c81fdcee7202ea7d908c89ca16 Mon Sep 17 00:00:00 2001 From: sponge Date: Sun, 3 May 2009 16:02:07 +0000 Subject: [PATCH 08/10] 2009-05-03 sponge * More hopeful fixes for BOB. * Added new Robert ID to snark --- apps/BOB/src/net/i2p/BOB/MUXlisten.java | 66 +++++-------------- .../org/klomp/snark/web/I2PSnarkServlet.java | 2 + history.txt | 4 ++ .../src/net/i2p/router/RouterVersion.java | 2 +- 4 files changed, 24 insertions(+), 50 deletions(-) diff --git a/apps/BOB/src/net/i2p/BOB/MUXlisten.java b/apps/BOB/src/net/i2p/BOB/MUXlisten.java index 2c7a64924..776dbf28a 100644 --- a/apps/BOB/src/net/i2p/BOB/MUXlisten.java +++ b/apps/BOB/src/net/i2p/BOB/MUXlisten.java @@ -265,23 +265,23 @@ public class MUXlisten implements Runnable { } // Wait for child threads and thread groups to die // System.out.println("MUXlisten: waiting for children"); - if (tg.activeCount() + tg.activeGroupCount() != 0) { - tg.interrupt(); // give my stuff a small smack. - while ((tg.activeCount() + tg.activeGroupCount() != 0) && ticks != 0) { - ticks--; - try { - Thread.sleep(100); //sleep for 100 ms (One tenth second) - } catch (InterruptedException ex) { - break quit; - } - } - if (tg.activeCount() + tg.activeGroupCount() != 0) { - break quit; // Uh-oh. - } - } - tg.destroy(); + // if (tg.activeCount() + tg.activeGroupCount() != 0) { + // tg.interrupt(); // give my stuff a small smack. + // while ((tg.activeCount() + tg.activeGroupCount() != 0) && ticks != 0) { + // ticks--; + // try { + // Thread.sleep(100); //sleep for 100 ms (One tenth second) + // } catch (InterruptedException ex) { + // break quit; + // } + // } + // if (tg.activeCount() + tg.activeGroupCount() != 0) { + // break quit; // Uh-oh. + // } + //} + //tg.destroy(); // Zap reference to the ThreadGroup so the JVM can GC it. - tg = null; + //tg = null; } catch (Exception e) { // System.out.println("MUXlisten: Caught an exception" + e); break quit; @@ -305,7 +305,7 @@ public class MUXlisten implements Runnable { // This is here to catch when something fucks up REALLY bad, like those annoying stuck threads! if (tg != null) { - tg.interrupt(); // give my stuff a small smack again. + // tg.interrupt(); // give my stuff a small smack again. if (SS != null) { try { SS.close(); @@ -319,21 +319,11 @@ public class MUXlisten implements Runnable { } catch (IOException e) { } } - I2PSession session = socketManager.getSession(); - if (session != null) { - // System.out.println("I2Plistener: destroySession"); - try { - session.destroySession(); - } catch (I2PSessionException ex) { - // nop - } - } try { socketManager.destroySocketManager(); } catch (Exception e) { // nop } - // ticks = 100; // 10 seconds if (tg.activeCount() + tg.activeGroupCount() != 0) { int foo = tg.activeCount() + tg.activeGroupCount(); int bar = foo; @@ -352,15 +342,6 @@ public class MUXlisten implements Runnable { } bar = foo; try { - session = socketManager.getSession(); - if (session != null) { - // System.out.println("I2Plistener: destroySession"); - try { - session.destroySession(); - } catch (I2PSessionException ex) { - // nop - } - } try { socketManager.destroySocketManager(); } catch (Exception e) { @@ -369,8 +350,6 @@ public class MUXlisten implements Runnable { } catch (Exception e) { // nop } - // tg.interrupt(); // unwedge any blocking threads. - // ticks--; try { Thread.sleep(100); //sleep for 100 ms (One tenth second) } catch (InterruptedException ex) { @@ -379,20 +358,9 @@ public class MUXlisten implements Runnable { } System.out.println("BOB: MUXlisten: Threads went away. Success: " + boner); } -// if (tg.activeCount() + tg.activeGroupCount() == 0) { tg.destroy(); // Zap reference to the ThreadGroup so the JVM can GC it. tg = null; -// } else { -// System.out.println("BOB: MUXlisten: Forcibly killing threads."); -// System.out.println("\n\nBOB: MUXlisten: ThreadGroup dump BEGIN"); -// visit(tg, 0); -// System.out.println("BOB: MUXlisten: ThreadGroup dump END\n\n"); -// nuke(tg,0); -// tg.destroy(); -// // Zap reference to the ThreadGroup so the JVM can GC it. -// tg = null; -// } } } diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index 515594219..3923484a8 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -587,6 +587,8 @@ public class I2PSnarkServlet extends HttpServlet { client = "I2PSnarkXL"; else if ("ZV".equals(ch.substring(2,4))) client = "Robert"; + else if ("VUZP".equals(ch)) + client = "Robert"; else client = "Unknown (" + ch + ')'; out.write("" + client + "  " + peer.toString().substring(5, 9) + ""); diff --git a/history.txt b/history.txt index 8aebfdd1a..102aef632 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,7 @@ +2009-05-03 sponge + * More hopeful fixes for BOB. + * Added new Robert ID to snark + 2009-05-01 zzz * Build files: - Fix up susidns build file so it will work with gcj diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 0ac10c058..4ab27b06c 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 6; + public final static long BUILD = 7; /** for example "-test" */ public final static String EXTRA = ""; public final static String FULL_VERSION = VERSION + "-" + BUILD + EXTRA; From eba6ca5430393e0ae623b96f1f28a28af395cab9 Mon Sep 17 00:00:00 2001 From: sponge Date: Wed, 6 May 2009 05:34:33 +0000 Subject: [PATCH 09/10] 2009-05-06 sponge * Hopefully the last fixes for BOB. * Fixes to prevent race in client-side I2CP and Notifier. --- apps/BOB/src/net/i2p/BOB/I2Plistener.java | 80 +++-- apps/BOB/src/net/i2p/BOB/I2PtoTCP.java | 161 +++++---- apps/BOB/src/net/i2p/BOB/MUXlisten.java | 329 ++++++++---------- apps/BOB/src/net/i2p/BOB/TCPlistener.java | 115 +++--- apps/BOB/src/net/i2p/BOB/TCPtoI2P.java | 146 ++++---- .../net/i2p/client/I2PSessionMuxedImpl.java | 10 +- .../net/i2p/data/i2cp/I2CPMessageReader.java | 4 +- history.txt | 4 + .../src/net/i2p/router/RouterVersion.java | 2 +- 9 files changed, 430 insertions(+), 421 deletions(-) diff --git a/apps/BOB/src/net/i2p/BOB/I2Plistener.java b/apps/BOB/src/net/i2p/BOB/I2Plistener.java index 3bb94e0b3..caaadc76d 100644 --- a/apps/BOB/src/net/i2p/BOB/I2Plistener.java +++ b/apps/BOB/src/net/i2p/BOB/I2Plistener.java @@ -25,6 +25,8 @@ package net.i2p.BOB; import java.net.ConnectException; import java.net.SocketTimeoutException; +import java.util.logging.Level; +import java.util.logging.Logger; import net.i2p.I2PException; import net.i2p.client.streaming.I2PServerSocket; import net.i2p.client.streaming.I2PSocket; @@ -78,51 +80,59 @@ public class I2Plistener implements Runnable { public void run() { boolean g = false; I2PSocket sessSocket = null; + int conn = 0; + try { + die: + { -die: { + serverSocket.setSoTimeout(50); + boolean spin = true; + while (spin) { - serverSocket.setSoTimeout(50); - boolean spin = true; - while (spin) { - - try { - rlock(); - } catch (Exception e) { - break die; - } - try { - spin = info.get("RUNNING").equals(Boolean.TRUE); - } catch (Exception e) { try { - runlock(); - } catch (Exception e2) { + rlock(); + } catch (Exception e) { break die; } - break die; - } - try { try { - sessSocket = serverSocket.accept(); - g = true; - } catch (ConnectException ce) { - g = false; - } catch (SocketTimeoutException ste) { - g = false; - } - if (g) { - g = false; - // toss the connection to a new thread. - I2PtoTCP conn_c = new I2PtoTCP(sessSocket, info, database); - Thread t = new Thread(conn_c, "BOBI2PtoTCP"); - t.start(); + spin = info.get("RUNNING").equals(Boolean.TRUE); + } catch (Exception e) { + try { + runlock(); + } catch (Exception e2) { + break die; + } + break die; } + try { + try { + sessSocket = serverSocket.accept(); + g = true; + } catch (ConnectException ce) { + g = false; + } catch (SocketTimeoutException ste) { + g = false; + } + if (g) { + g = false; + conn++; + // toss the connection to a new thread. + I2PtoTCP conn_c = new I2PtoTCP(sessSocket, info, database); + Thread t = new Thread(conn_c, Thread.currentThread().getName() + " I2PtoTCP " + conn); + t.start(); + } - } catch (Exception e) { - // System.out.println("Exception " + e); + } catch (Exception e) { + // System.out.println("Exception " + e); + } } } - } + } finally { + try { + serverSocket.close(); + } catch (I2PException ex) { + } // System.out.println("I2Plistener: Close"); - // System.out.println("I2Plistener: Done."); + } } } diff --git a/apps/BOB/src/net/i2p/BOB/I2PtoTCP.java b/apps/BOB/src/net/i2p/BOB/I2PtoTCP.java index ad5e2701b..73e936c61 100644 --- a/apps/BOB/src/net/i2p/BOB/I2PtoTCP.java +++ b/apps/BOB/src/net/i2p/BOB/I2PtoTCP.java @@ -70,90 +70,99 @@ public class I2PtoTCP implements Runnable { String host; int port; boolean tell; -die: { - try { + InputStream in = null; + OutputStream out = null; + InputStream Iin = null; + OutputStream Iout = null; + try { + die: + { try { - rlock(); - } catch(Exception e) { - break die; - } - try { - host = info.get("OUTHOST").toString(); - port = Integer.parseInt(info.get("OUTPORT").toString()); - tell = info.get("QUIET").equals(Boolean.FALSE); - } catch(Exception e) { - runlock(); - break die; - } - try { - runlock(); - } catch(Exception e) { - break die; - } - sock = new Socket(host, port); - // make readers/writers - InputStream in = sock.getInputStream(); - OutputStream out = sock.getOutputStream(); - InputStream Iin = I2P.getInputStream(); - OutputStream Iout = I2P.getOutputStream(); - I2P.setReadTimeout(0); // temp bugfix, this *SHOULD* be the default - - if(tell) { - // tell who is connecting - out.write(I2P.getPeerDestination().toBase64().getBytes()); - out.write(10); // nl - out.flush(); // not really needed, but... - } - // 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 - Thread t = new Thread(conn_c, "TCPioA"); - Thread q = new Thread(conn_a, "TCPioB"); - // Fire! - t.start(); - q.start(); - while(t.isAlive() && q.isAlive()) { // AND is used here to kill off the other thread try { - Thread.sleep(10); //sleep for 10 ms - } catch(InterruptedException e) { + rlock(); + } catch (Exception e) { + break die; + } + try { + host = info.get("OUTHOST").toString(); + port = Integer.parseInt(info.get("OUTPORT").toString()); + tell = info.get("QUIET").equals(Boolean.FALSE); + } catch (Exception e) { + runlock(); + break die; + } + try { + runlock(); + } catch (Exception e) { + break die; + } + sock = new Socket(host, port); + // make readers/writers + in = sock.getInputStream(); + out = sock.getOutputStream(); + Iin = I2P.getInputStream(); + Iout = I2P.getOutputStream(); + I2P.setReadTimeout(0); // temp bugfix, this *SHOULD* be the default + + if (tell) { + // tell who is connecting + out.write(I2P.getPeerDestination().toBase64().getBytes()); + out.write(10); // nl + out.flush(); // not really needed, but... + } + // 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 + Thread t = new Thread(conn_c, Thread.currentThread().getName() + " TCPioA"); + Thread q = new Thread(conn_a, Thread.currentThread().getName() + " TCPioB"); + // Fire! + t.start(); + q.start(); + while (t.isAlive() && q.isAlive()) { // AND is used here to kill off the other thread try { - in.close(); - } catch(Exception ex) { - } - try { - out.close(); - } catch(Exception ex) { - } - try { - Iin.close(); - } catch(Exception ex) { - } - try { - Iout.close(); - } catch(Exception ex) { + Thread.sleep(10); //sleep for 10 ms + } catch (InterruptedException e) { + break die; } } - } // System.out.println("I2PtoTCP: Going away..."); - } catch(Exception e) { - // System.out.println("I2PtoTCP: Owch! damn!"); - break die; + } catch (Exception e) { + // System.out.println("I2PtoTCP: Owch! damn!"); + break die; + } + } // die + } finally { + try { + in.close(); + } catch (Exception ex) { + } + try { + out.close(); + } catch (Exception ex) { + } + try { + Iin.close(); + } catch (Exception ex) { + } + try { + Iout.close(); + } catch (Exception ex) { + } + try { + // System.out.println("I2PtoTCP: Close I2P"); + I2P.close(); + } catch (Exception e) { + tell = false; + } + //System.out.println("I2PtoTCP: Closed I2P"); + try { + // System.out.println("I2PtoTCP: Close sock"); + sock.close(); + } catch (Exception e) { + tell = false; } - } // die - try { - // System.out.println("I2PtoTCP: Close I2P"); - I2P.close(); - } catch(Exception e) { - tell = false; - } - //System.out.println("I2PtoTCP: Closed I2P"); - try { - // System.out.println("I2PtoTCP: Close sock"); - sock.close(); - } catch(Exception e) { - tell = false; - } // System.out.println("I2PtoTCP: Done"); + } } } diff --git a/apps/BOB/src/net/i2p/BOB/MUXlisten.java b/apps/BOB/src/net/i2p/BOB/MUXlisten.java index 776dbf28a..91028e7cb 100644 --- a/apps/BOB/src/net/i2p/BOB/MUXlisten.java +++ b/apps/BOB/src/net/i2p/BOB/MUXlisten.java @@ -29,8 +29,6 @@ import java.net.InetAddress; import java.net.ServerSocket; import java.util.Properties; import net.i2p.I2PException; -import net.i2p.client.I2PSession; -import net.i2p.client.I2PSessionException; import net.i2p.client.streaming.I2PServerSocket; import net.i2p.client.streaming.I2PSocketManager; import net.i2p.client.streaming.I2PSocketManagerFactory; @@ -50,7 +48,7 @@ public class MUXlisten implements Runnable { private ByteArrayInputStream prikey; private ThreadGroup tg; private String N; - private ServerSocket listener; + private ServerSocket listener = null; private int backlog = 50; // should this be more? less? boolean go_out; boolean come_in; @@ -133,187 +131,162 @@ public class MUXlisten implements Runnable { */ public void run() { I2PServerSocket SS = null; - int ticks = 100; // Allow 10 seconds, no more. + Thread t = null; + Thread q = null; try { - wlock(); try { - info.add("RUNNING", new Boolean(true)); + wlock(); + try { + info.add("RUNNING", new Boolean(true)); + } catch (Exception e) { + wunlock(); + return; + } + } catch (Exception e) { + return; + } + try { + wunlock(); } catch (Exception e) { - wunlock(); return; } - } catch (Exception e) { - return; - } - try { - wunlock(); - } catch (Exception e) { - return; - } // socketManager.addDisconnectListener(new DisconnectListener()); - quit: - { - try { - tg = new ThreadGroup(N); - die: - { - // toss the connections to a new threads. - // will wrap with TCP and UDP when UDP works + quit: + { + try { + tg = new ThreadGroup(N); + die: + { + // toss the connections to a new threads. + // will wrap with TCP and UDP when UDP works - if (go_out) { - // I2P -> TCP - SS = socketManager.getServerSocket(); - I2Plistener conn = new I2Plistener(SS, socketManager, info, database, _log); - Thread t = new Thread(tg, conn, "BOBI2Plistener " + N); - t.start(); - } - - if (come_in) { - // TCP -> I2P - TCPlistener conn = new TCPlistener(listener, socketManager, info, database, _log); - Thread q = new Thread(tg, conn, "BOBTCPlistener" + N); - q.start(); - } - - try { - wlock(); - try { - info.add("STARTING", new Boolean(false)); - } catch (Exception e) { - wunlock(); - break die; + if (go_out) { + // I2P -> TCP + SS = socketManager.getServerSocket(); + I2Plistener conn = new I2Plistener(SS, socketManager, info, database, _log); + t = new Thread(tg, conn, "BOBI2Plistener " + N); + t.start(); } - } catch (Exception e) { - break die; - } - try { - wunlock(); - } catch (Exception e) { - break die; - } - boolean spin = true; - while (spin) { - try { - Thread.sleep(1000); //sleep for 1 second - } catch (InterruptedException e) { - break die; + + if (come_in) { + // TCP -> I2P + TCPlistener conn = new TCPlistener(listener, socketManager, info, database, _log); + q = new Thread(tg, conn, "BOBTCPlistener " + N); + q.start(); } + try { - rlock(); + wlock(); try { - spin = info.get("STOPPING").equals(Boolean.FALSE); + info.add("STARTING", new Boolean(false)); } catch (Exception e) { - runlock(); + wunlock(); break die; } } catch (Exception e) { break die; } try { - runlock(); - } catch (Exception e) { - break die; - } - } - - try { - wlock(); - try { - info.add("RUNNING", new Boolean(false)); - } catch (Exception e) { wunlock(); + } catch (Exception e) { break die; } - } catch (Exception e) { - break die; - } - try { - wunlock(); - } catch (Exception e) { - break die; - } - } // die + boolean spin = true; + while (spin) { + try { + Thread.sleep(1000); //sleep for 1 second + } catch (InterruptedException e) { + break die; + } + try { + rlock(); + try { + spin = info.get("STOPPING").equals(Boolean.FALSE); + } catch (Exception e) { + runlock(); + break die; + } + } catch (Exception e) { + break die; + } + try { + runlock(); + } catch (Exception e) { + break die; + } + } - if (SS != null) { - try { - SS.close(); - } catch (I2PException ex) { - //Logger.getLogger(MUXlisten.class.getName()).log(Level.SEVERE, null, ex); - } - } - if (this.come_in) { - try { - listener.close(); - } catch (IOException e) { - } - } + try { + wlock(); + try { + info.add("RUNNING", new Boolean(false)); + } catch (Exception e) { + wunlock(); + break die; + } + } catch (Exception e) { + break die; + } + try { + wunlock(); + } catch (Exception e) { + break die; + } + } // die - I2PSession session = socketManager.getSession(); - if (session != null) { - // System.out.println("I2Plistener: destroySession"); - try { - session.destroySession(); - } catch (I2PSessionException ex) { - // nop - } - } - try { - socketManager.destroySocketManager(); - } catch (Exception e) { - // nop - } - // Wait for child threads and thread groups to die - // System.out.println("MUXlisten: waiting for children"); - // if (tg.activeCount() + tg.activeGroupCount() != 0) { - // tg.interrupt(); // give my stuff a small smack. - // while ((tg.activeCount() + tg.activeGroupCount() != 0) && ticks != 0) { - // ticks--; - // try { - // Thread.sleep(100); //sleep for 100 ms (One tenth second) - // } catch (InterruptedException ex) { - // break quit; - // } - // } - // if (tg.activeCount() + tg.activeGroupCount() != 0) { - // break quit; // Uh-oh. + // I2PSession session = socketManager.getSession(); + // if (session != null) { + // System.out.println("I2Plistener: destroySession"); + // try { + // session.destroySession(); + // } catch (I2PSessionException ex) { + // nop // } + // } + // try { + // socketManager.destroySocketManager(); + //} catch (Exception e) { + // nop //} - //tg.destroy(); - // Zap reference to the ThreadGroup so the JVM can GC it. - //tg = null; - } catch (Exception e) { - // System.out.println("MUXlisten: Caught an exception" + e); - break quit; - } - } // quit - - // zero out everything. - try { - wlock(); + } catch (Exception e) { + // System.out.println("MUXlisten: Caught an exception" + e); + break quit; + } + } // quit + } finally { + // allow threads above this one to catch the stop signal. try { - info.add("STARTING", new Boolean(false)); - info.add("STOPPING", new Boolean(false)); - info.add("RUNNING", new Boolean(false)); - } catch (Exception e) { - wunlock(); - return; + Thread.sleep(250); + } catch (InterruptedException ex) { + } + // zero out everything. + try { + wlock(); + try { + info.add("STARTING", new Boolean(false)); + info.add("STOPPING", new Boolean(false)); + info.add("RUNNING", new Boolean(false)); + } catch (Exception e) { + wunlock(); + return; + } + wunlock(); + } catch (Exception e) { } - wunlock(); - } catch (Exception e) { - } - // This is here to catch when something fucks up REALLY bad, like those annoying stuck threads! - if (tg != null) { - // tg.interrupt(); // give my stuff a small smack again. + //try { + // Thread.sleep(1000 * 20); // how long?? is this even needed?? + //} catch (InterruptedException ex) { + //} + if (SS != null) { try { SS.close(); } catch (I2PException ex) { - //Logger.getLogger(MUXlisten.class.getName()).log(Level.SEVERE, null, ex); } } - if (this.come_in) { + if (listener != null) { try { listener.close(); } catch (IOException e) { @@ -323,50 +296,46 @@ public class MUXlisten implements Runnable { socketManager.destroySocketManager(); } catch (Exception e) { // nop - } - if (tg.activeCount() + tg.activeGroupCount() != 0) { - int foo = tg.activeCount() + tg.activeGroupCount(); - int bar = foo; + } + // This is here to catch when something fucks up REALLY bad, like those annoying stuck threads! + if (tg != null) { String boner = tg.getName(); - System.out.println("BOB: MUXlisten: Waiting on threads for " + boner); - System.out.println("\n\nBOB: MUXlisten: ThreadGroup dump BEGIN " + boner); - visit(tg, 0, boner); - System.out.println("BOB: MUXlisten: ThreadGroup dump END " + boner + "\n\n"); - // Happily spin forever :-( - while ((tg.activeCount() + tg.activeGroupCount() != 0)) { - foo = tg.activeCount() + tg.activeGroupCount(); - if (foo != bar) { - System.out.println("\n\nBOB: MUXlisten: ThreadGroup dump BEGIN " + boner); - visit(tg, 0, boner); - System.out.println("BOB: MUXlisten: ThreadGroup dump END " + boner + "\n\n"); - } - bar = foo; - try { + // tg.interrupt(); // give my stuff a small smack again. + if (tg.activeCount() + tg.activeGroupCount() != 0) { + int foo = tg.activeCount() + tg.activeGroupCount(); + int bar = foo; + // hopefully no longer needed! + // System.out.println("BOB: MUXlisten: Waiting on threads for " + boner); + // System.out.println("\n\nBOB: MUXlisten: ThreadGroup dump BEGIN " + boner); + // visit(tg, 0, boner); + // System.out.println("BOB: MUXlisten: ThreadGroup dump END " + boner + "\n\n"); + // Happily spin forever :-( + while ((tg.activeCount() + tg.activeGroupCount() != 0)) { + foo = tg.activeCount() + tg.activeGroupCount(); + // if (foo != bar) { + // System.out.println("\n\nBOB: MUXlisten: ThreadGroup dump BEGIN " + boner); + // visit(tg, 0, boner); + // System.out.println("BOB: MUXlisten: ThreadGroup dump END " + boner + "\n\n"); + // } + bar = foo; try { - socketManager.destroySocketManager(); - } catch (Exception e) { + Thread.sleep(100); //sleep for 100 ms (One tenth second) + } catch (InterruptedException ex) { // nop } - } catch (Exception e) { - // nop - } - try { - Thread.sleep(100); //sleep for 100 ms (One tenth second) - } catch (InterruptedException ex) { - // nop } } System.out.println("BOB: MUXlisten: Threads went away. Success: " + boner); + tg.destroy(); + // Zap reference to the ThreadGroup so the JVM can GC it. + tg = null; } - tg.destroy(); - // Zap reference to the ThreadGroup so the JVM can GC it. - tg = null; } } // Debugging... - /** + /** * Find the root thread group and print them all. * */ diff --git a/apps/BOB/src/net/i2p/BOB/TCPlistener.java b/apps/BOB/src/net/i2p/BOB/TCPlistener.java index 4ce888090..0ac67d277 100644 --- a/apps/BOB/src/net/i2p/BOB/TCPlistener.java +++ b/apps/BOB/src/net/i2p/BOB/TCPlistener.java @@ -29,6 +29,8 @@ import java.net.Socket; import java.net.SocketTimeoutException; // import net.i2p.client.I2PSession; // import net.i2p.client.I2PSessionException; +import java.util.logging.Level; +import java.util.logging.Logger; import net.i2p.client.streaming.I2PServerSocket; import net.i2p.client.streaming.I2PSocketManager; import net.i2p.util.Log; @@ -80,71 +82,80 @@ public class TCPlistener implements Runnable { public void run() { boolean g = false; boolean spin = true; - -die: { - try { - rlock(); - } catch (Exception e) { - break die; - } - try { - if (info.exists("OUTPORT")) { - tgwatch = 2; - } - } catch (Exception e) { + int conn = 0; + try { + die: + { try { - runlock(); - } catch (Exception e2) { + rlock(); + } catch (Exception e) { 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. - while (spin) { + try { + if (info.exists("OUTPORT")) { + tgwatch = 2; + } + } catch (Exception e) { try { - rlock(); - } catch (Exception e) { + runlock(); + } catch (Exception e2) { break die; } - try { - spin = info.get("RUNNING").equals(Boolean.TRUE); - } catch (Exception e) { + 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. + while (spin) { try { - runlock(); - } catch (Exception e2) { + rlock(); + } catch (Exception e) { break die; } - break die; + try { + spin = info.get("RUNNING").equals(Boolean.TRUE); + } catch (Exception e) { + try { + runlock(); + } catch (Exception e2) { + break die; + } + break die; + } + try { + server = listener.accept(); + g = true; + } catch (SocketTimeoutException ste) { + g = false; + } + if (g) { + conn++; + // toss the connection to a new thread. + TCPtoI2P conn_c = new TCPtoI2P(socketManager, server); + Thread t = new Thread(conn_c, Thread.currentThread().getName() + " TCPtoI2P " + conn); + t.start(); + g = false; + } } - try { - server = listener.accept(); - g = true; - } catch (SocketTimeoutException ste) { - g = false; - } - if (g) { - // toss the connection to a new thread. - TCPtoI2P conn_c = new TCPtoI2P(socketManager, server); - Thread t = new Thread(conn_c, "BOBTCPtoI2P"); - t.start(); - g = false; - } - } - listener.close(); - } catch (IOException ioe) { - try { listener.close(); - } catch (IOException e) { + } catch (IOException ioe) { + try { + listener.close(); + } catch (IOException e) { + } } } + } finally { + try { + listener.close(); + } catch (IOException ex) { + } + //System.out.println("TCPlistener: " + Thread.currentThread().getName() + "Done."); } - //System.out.println("TCPlistener: Done."); } } diff --git a/apps/BOB/src/net/i2p/BOB/TCPtoI2P.java b/apps/BOB/src/net/i2p/BOB/TCPtoI2P.java index 5fefae017..f3f2c7445 100644 --- a/apps/BOB/src/net/i2p/BOB/TCPtoI2P.java +++ b/apps/BOB/src/net/i2p/BOB/TCPtoI2P.java @@ -64,17 +64,17 @@ public class TCPtoI2P implements Runnable { S = new String(); - while(true) { + while (true) { b = in.read(); - if(b == 13) { + if (b == 13) { //skip CR continue; } - if(b < 20 || b > 126) { + if (b < 20 || b > 126) { // exit on anything not legal break; } - c = (char)(b & 0x7f); // We only really give a fuck about ASCII + c = (char) (b & 0x7f); // We only really give a fuck about ASCII S = new String(S + c); } return S; @@ -118,85 +118,87 @@ public class TCPtoI2P implements Runnable { OutputStream Iout = null; InputStream in = null; OutputStream out = null; - try { - - 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); + in = sock.getInputStream(); + out = sock.getOutputStream(); 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 - Thread t = new Thread(conn_c, "TCPioA"); - Thread q = new Thread(conn_a, "TCPioB"); - // Fire! - t.start(); - q.start(); - while(t.isAlive() && q.isAlive()) { // AND is used here to kill off the other thread + 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 + Thread t = new Thread(conn_c, Thread.currentThread().getName() + " TCPioA"); + Thread q = new Thread(conn_a, Thread.currentThread().getName() + " TCPioB"); + // Fire! + t.start(); + q.start(); + while (t.isAlive() && q.isAlive()) { // AND is used here to kill off the other thread Thread.sleep(10); //sleep for 10 ms + } + + } 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(I2PException e) { + } catch (Exception 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); + } catch (Exception e) { + // bail on anything else + } + } finally { + try { + in.close(); + } catch (Exception e) { + } + try { + out.close(); + } catch (Exception e) { + } + try { + Iin.close(); + } catch (Exception e) { + } + try { + Iout.close(); + } catch (Exception e) { + } + try { + // System.out.println("TCPtoI2P: Close I2P"); + I2P.close(); + } catch (Exception e) { } - } catch(Exception e) { - // bail on anything else - } - try { - in.close(); - } catch(Exception e) { - } - try { - out.close(); - } catch(Exception e) { - } - try { - Iin.close(); - } catch(Exception e) { - } - try { - Iout.close(); - } catch(Exception e) { - } - try { - // System.out.println("TCPtoI2P: Close I2P"); - I2P.close(); - } catch(Exception e) { - } - try { - // System.out.println("TCPtoI2P: Close sock"); - sock.close(); - } catch(Exception e) { + try { + // System.out.println("TCPtoI2P: Close sock"); + sock.close(); + } catch (Exception e) { + } } - // System.out.println("TCPtoI2P: Done."); + // System.out.println("TCPtoI2P: Done."); } } diff --git a/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java b/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java index eda48e754..aeef4e38e 100644 --- a/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java +++ b/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java @@ -202,20 +202,23 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 implements I2PSession { private LinkedBlockingQueue _msgs; private AtomicBoolean _alive = new AtomicBoolean(false); private static final int POISON_SIZE = -99999; - + private AtomicBoolean stopping = new AtomicBoolean(false); + public MuxedAvailabilityNotifier() { _msgs = new LinkedBlockingQueue(); } @Override public void stopNotifying() { + if(stopping.get()) return; + stopping.set(true); boolean again = true; - _msgs.clear(); + // _msgs.clear(); // Thread.yield(); if (_alive.get()) { // System.out.println("I2PSessionMuxedImpl.stopNotifying()"); + _msgs.clear(); while(again) { - _msgs.clear(); try { _msgs.put(new MsgData(0, POISON_SIZE, 0, 0, 0)); again = false; @@ -226,6 +229,7 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 implements I2PSession { } } _alive.set(false); + stopping.set(false); // Do we need this? } /** unused */ diff --git a/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java b/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java index 5c79d94f3..461c4b08a 100644 --- a/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java +++ b/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java @@ -115,8 +115,8 @@ public class I2CPMessageReader { } private class I2CPMessageReaderRunner implements Runnable { - private boolean _doRun; - private boolean _stayAlive; + private volatile boolean _doRun; + private volatile boolean _stayAlive; public I2CPMessageReaderRunner() { _doRun = true; diff --git a/history.txt b/history.txt index 102aef632..042ca5df7 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,7 @@ +2009-05-06 sponge + * Hopefully the last fixes for BOB. + * Fixes to prevent race in client-side I2CP and Notifier. + 2009-05-03 sponge * More hopeful fixes for BOB. * Added new Robert ID to snark diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 4ab27b06c..848b1dc38 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 7; + public final static long BUILD = 8; /** for example "-test" */ public final static String EXTRA = ""; public final static String FULL_VERSION = VERSION + "-" + BUILD + EXTRA; From a516d6474e21bdcd3e515c350ea8a6b858891505 Mon Sep 17 00:00:00 2001 From: mathiasdm Date: Wed, 6 May 2009 16:17:58 +0000 Subject: [PATCH 10/10] * Improvements to popup menu rightclick action * Added general configuration options (still not available by default) * General fixes * Added ant build options (irc says eche|on would like that ;)) --- apps/desktopgui/nbproject/build-impl.xml | 25 +- apps/desktopgui/nbproject/genfiles.properties | 4 +- .../desktopgui/src/desktopgui/GUIVersion.java | 2 +- .../src/gui/GeneralConfiguration.form | 138 ++++--- .../src/gui/GeneralConfiguration.java | 347 +++++++++++------- apps/desktopgui/src/gui/JPopupTrayIcon.java | 29 +- apps/desktopgui/src/gui/LogViewer.form | 1 + apps/desktopgui/src/gui/LogViewer.java | 3 +- apps/desktopgui/src/gui/SpeedSelector3.form | 3 +- apps/desktopgui/src/gui/SpeedSelector3.java | 2 +- apps/desktopgui/src/gui/Version.form | 27 +- apps/desktopgui/src/gui/Version.java | 22 +- .../resources/GeneralConfiguration.properties | 24 +- .../src/gui/resources/LogViewer.properties | 1 + .../gui/resources/SpeedSelector3.properties | 4 +- .../src/gui/resources/Version.properties | 1 + .../src/router/configuration/SpeedHelper.java | 7 + build.xml | 4 + history.txt | 6 + 19 files changed, 404 insertions(+), 246 deletions(-) diff --git a/apps/desktopgui/nbproject/build-impl.xml b/apps/desktopgui/nbproject/build-impl.xml index f8fea458d..039f8788f 100644 --- a/apps/desktopgui/nbproject/build-impl.xml +++ b/apps/desktopgui/nbproject/build-impl.xml @@ -152,7 +152,7 @@ is divided into following sections: - + @@ -218,13 +218,13 @@ is divided into following sections: - + - + @@ -255,6 +255,12 @@ is divided into following sections: + + + + + + @@ -264,7 +270,7 @@ is divided into following sections: - + @@ -311,6 +317,13 @@ is divided into following sections: =================== --> + + + + + + + @@ -331,7 +344,7 @@ is divided into following sections: - + @@ -345,7 +358,7 @@ is divided into following sections: - +