2009-04-08 sponge

* More hopeful fixups to the infamous orpahned tunnel problem. *Sigh*
This commit is contained in:
sponge
2009-04-08 11:55:51 +00:00
parent f9f9aa4498
commit 8f690a8f67
4 changed files with 87 additions and 73 deletions

View File

@ -48,17 +48,18 @@ public class I2Plistener implements Runnable {
/** /**
* Constructor * Constructor
* @param SS
* @param S * @param S
* @param info * @param info
* @param database * @param database
* @param _log * @param _log
*/ */
I2Plistener(I2PSocketManager S, NamedDB info, NamedDB database, Log _log) { I2Plistener(I2PServerSocket SS, I2PSocketManager S, NamedDB info, NamedDB database, Log _log) {
this.database = database; this.database = database;
this.info = info; this.info = info;
this._log = _log; this._log = _log;
this.socketManager = S; this.socketManager = S;
serverSocket = this.socketManager.getServerSocket(); serverSocket = SS;
tgwatch = 1; tgwatch = 1;
} }
@ -72,16 +73,6 @@ public class I2Plistener implements Runnable {
info.releaseReadLock(); info.releaseReadLock();
} }
private void wlock() throws Exception {
database.getWriteLock();
info.getWriteLock();
}
private void wunlock() throws Exception {
info.releaseWriteLock();
database.releaseWriteLock();
}
/** /**
* Simply listen on I2P port, and thread connections * Simply listen on I2P port, and thread connections
* *

View File

@ -28,7 +28,10 @@ import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.util.Properties; import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.i2p.I2PException; import net.i2p.I2PException;
import net.i2p.client.streaming.I2PServerSocket;
import net.i2p.client.streaming.I2PSocketManager; import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.client.streaming.I2PSocketManagerFactory; import net.i2p.client.streaming.I2PSocketManagerFactory;
import net.i2p.util.Log; import net.i2p.util.Log;
@ -73,9 +76,9 @@ public class MUXlisten implements Runnable {
this.database.getReadLock(); this.database.getReadLock();
this.info.getReadLock(); this.info.getReadLock();
N = this.info.get("NICKNAME").toString(); N = this.info.get("NICKNAME").toString();
prikey = new ByteArrayInputStream((byte[])info.get("KEYS")); prikey = new ByteArrayInputStream((byte[]) info.get("KEYS"));
// Make a new copy so that anything else won't muck with our database. // Make a new copy so that anything else won't muck with our database.
Properties R = (Properties)info.get("PROPERTIES"); Properties R = (Properties) info.get("PROPERTIES");
Properties Q = new Properties(); Properties Q = new Properties();
Lifted.copyProperties(R, Q); Lifted.copyProperties(R, Q);
this.database.releaseReadLock(); this.database.releaseReadLock();
@ -85,7 +88,7 @@ public class MUXlisten implements Runnable {
this.info.getReadLock(); this.info.getReadLock();
this.go_out = info.exists("OUTPORT"); this.go_out = info.exists("OUTPORT");
this.come_in = info.exists("INPORT"); this.come_in = info.exists("INPORT");
if(this.come_in) { if (this.come_in) {
port = Integer.parseInt(info.get("INPORT").toString()); port = Integer.parseInt(info.get("INPORT").toString());
host = InetAddress.getByName(info.get("INHOST").toString()); host = InetAddress.getByName(info.get("INHOST").toString());
} }
@ -93,7 +96,7 @@ public class MUXlisten implements Runnable {
this.info.releaseReadLock(); this.info.releaseReadLock();
socketManager = I2PSocketManagerFactory.createManager(prikey, Q); socketManager = I2PSocketManagerFactory.createManager(prikey, Q);
if(this.come_in) { if (this.come_in) {
this.listener = new ServerSocket(port, backlog, host); this.listener = new ServerSocket(port, backlog, host);
} }
@ -130,40 +133,44 @@ public class MUXlisten implements Runnable {
* *
*/ */
public void run() { public void run() {
I2PServerSocket SS = null;
try { try {
wlock(); wlock();
try { try {
info.add("RUNNING", new Boolean(true)); info.add("RUNNING", new Boolean(true));
info.add("STARTING", new Boolean(false)); info.add("STARTING", new Boolean(false));
} catch(Exception e) { } catch (Exception e) {
wunlock(); wunlock();
return; return;
} }
} catch(Exception e) { } catch (Exception e) {
return; return;
} }
try { try {
wunlock(); wunlock();
} catch(Exception e) { } catch (Exception e) {
return; return;
} }
// socketManager.addDisconnectListener(new DisconnectListener());
quit: { quit:
{
try { try {
tg = new ThreadGroup(N); tg = new ThreadGroup(N);
die: { die:
{
// toss the connections to a new threads. // toss the connections to a new threads.
// will wrap with TCP and UDP when UDP works // will wrap with TCP and UDP when UDP works
if(go_out) { if (go_out) {
// I2P -> TCP // I2P -> TCP
I2Plistener conn = new I2Plistener(socketManager, info, database, _log); SS = socketManager.getServerSocket();
I2Plistener conn = new I2Plistener(SS, socketManager, info, database, _log);
Thread t = new Thread(tg, conn, "BOBI2Plistener " + N); Thread t = new Thread(tg, conn, "BOBI2Plistener " + N);
t.start(); t.start();
} }
if(come_in) { if (come_in) {
// TCP -> I2P // TCP -> I2P
TCPlistener conn = new TCPlistener(listener, socketManager, info, database, _log); TCPlistener conn = new TCPlistener(listener, socketManager, info, database, _log);
Thread q = new Thread(tg, conn, "BOBTCPlistener" + N); Thread q = new Thread(tg, conn, "BOBTCPlistener" + N);
@ -171,26 +178,26 @@ die: {
} }
boolean spin = true; boolean spin = true;
while(spin) { while (spin) {
try { try {
Thread.sleep(200); //sleep for 200 ms (Two thenths second) Thread.sleep(200); //sleep for 200 ms (Two thenths second)
} catch(InterruptedException e) { } catch (InterruptedException e) {
// nop // nop
} }
try { try {
rlock(); rlock();
try { try {
spin = info.get("STOPPING").equals(Boolean.FALSE); spin = info.get("STOPPING").equals(Boolean.FALSE);
} catch(Exception e) { } catch (Exception e) {
runlock(); runlock();
break die; break die;
} }
} catch(Exception e) { } catch (Exception e) {
break die; break die;
} }
try { try {
runlock(); runlock();
} catch(Exception e) { } catch (Exception e) {
break die; break die;
} }
} }
@ -199,80 +206,62 @@ die: {
wlock(); wlock();
try { try {
info.add("RUNNING", new Boolean(false)); info.add("RUNNING", new Boolean(false));
} catch(Exception e) { } catch (Exception e) {
wunlock(); wunlock();
break die; break die;
} }
} catch(Exception e) { } catch (Exception e) {
break die; break die;
} }
try { try {
wunlock(); wunlock();
} catch(Exception e) { } catch (Exception e) {
break die; break die;
} }
} // die } // die
try { // try {
Thread.sleep(500); //sleep for 500 ms (One half second) // Thread.sleep(500); //sleep for 500 ms (One half second)
} catch(InterruptedException ex) { // } catch (InterruptedException ex) {
// nop // // nop
} // }
// wait for child threads and thread groups to die // wait for child threads and thread groups to die
// System.out.println("MUXlisten: waiting for children"); // System.out.println("MUXlisten: waiting for children");
if(tg.activeCount() + tg.activeGroupCount() != 0) { if (tg.activeCount() + tg.activeGroupCount() != 0) {
tg.interrupt(); // unwedge any blocking threads. while (tg.activeCount() + tg.activeGroupCount() != 0) {
while(tg.activeCount() + tg.activeGroupCount() != 0) { tg.interrupt(); // unwedge any blocking threads.
try { try {
Thread.sleep(100); //sleep for 100 ms (One tenth second) Thread.sleep(100); //sleep for 100 ms (One tenth second)
} catch(InterruptedException ex) { } catch (InterruptedException ex) {
// nop // NOP
} }
} }
} }
tg.destroy(); tg.destroy();
// Zap reference to the ThreadGroup so the JVM can GC it. // Zap reference to the ThreadGroup so the JVM can GC it.
tg = null; tg = null;
} catch(Exception e) { } catch (Exception e) {
// System.out.println("MUXlisten: Caught an exception" + e); // System.out.println("MUXlisten: Caught an exception" + e);
break quit; break quit;
} }
} // quit } // quit
// This is here to catch when something fucks up REALLY bad. // This is here to catch when something fucks up REALLY bad.
if(tg != null) { if (tg != null) {
System.out.println("BOB: MUXlisten: Something fucked up REALLY bad!"); System.out.println("BOB: MUXlisten: Something fucked up REALLY bad!");
System.out.println("BOB: MUXlisten: Please email the following dump to sponge@mail.i2p"); System.out.println("BOB: MUXlisten: Please email the following dump to sponge@mail.i2p");
WrapperManager.requestThreadDump(); WrapperManager.requestThreadDump();
System.out.println("BOB: MUXlisten: Something fucked up REALLY bad!"); System.out.println("BOB: MUXlisten: Something fucked up REALLY bad!");
System.out.println("BOB: MUXlisten: Please email the above dump to sponge@mail.i2p"); System.out.println("BOB: MUXlisten: Please email the above dump to sponge@mail.i2p");
} }
// zero out everything, just incase.
try {
socketManager.destroySocketManager();
} catch(Exception e) {
// nop
}
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) {
}
// This is here to catch when something fucks up REALLY bad. // This is here to catch when something fucks up REALLY bad.
if(tg != null) { if (tg != null) {
if(tg.activeCount() + tg.activeGroupCount() != 0) { if (tg.activeCount() + tg.activeGroupCount() != 0) {
tg.interrupt(); // unwedge any blocking threads. tg.interrupt(); // unwedge any blocking threads.
while(tg.activeCount() + tg.activeGroupCount() != 0) { while (tg.activeCount() + tg.activeGroupCount() != 0) {
try { try {
Thread.sleep(100); //sleep for 100 ms (One tenth second) Thread.sleep(100); //sleep for 100 ms (One tenth second)
} catch(InterruptedException ex) { } catch (InterruptedException ex) {
// nop // nop
} }
} }
@ -282,18 +271,49 @@ die: {
tg = null; tg = null;
} }
if (SS != null) {
try {
SS.close();
} catch (I2PException ex) {
//Logger.getLogger(MUXlisten.class.getName()).log(Level.SEVERE, null, ex);
}
}
// Lastly try to close things again. // Lastly try to close things again.
if(this.come_in) { if (this.come_in) {
try { try {
listener.close(); listener.close();
} catch(IOException e) { } catch (IOException e) {
} }
} }
try { try {
socketManager.destroySocketManager(); socketManager.destroySocketManager();
} catch(Exception e) { } catch (Exception e) {
// nop // nop
} }
// 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) {
}
} }
// private class DisconnectListener implements I2PSocketManager.DisconnectListener {
//
// public void sessionDisconnected() {
// close();
// }
// }
// public void close() {
// socketManager.destroySocketManager();
// }
} }

View File

@ -1,3 +1,6 @@
2009-04-08 sponge
* More hopeful fixups to the infamous orpahned tunnel problem. *Sigh*
2009-04-08 zzz 2009-04-08 zzz
* IPV6/localhost: * IPV6/localhost:
- Enable IPv6 stack in the JVM, hopefully won't break anything - Enable IPv6 stack in the JVM, hopefully won't break anything

View File

@ -17,7 +17,7 @@ import net.i2p.CoreVersion;
public class RouterVersion { public class RouterVersion {
public final static String ID = "$Revision: 1.548 $ $Date: 2008-06-07 23:00:00 $"; 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 String VERSION = CoreVersion.VERSION;
public final static long BUILD = 13; public final static long BUILD = 14;
public static void main(String args[]) { public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD); System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID); System.out.println("Router ID: " + RouterVersion.ID);