|
|
|
@ -28,7 +28,10 @@ import java.io.IOException;
|
|
|
|
|
import java.net.InetAddress;
|
|
|
|
|
import java.net.ServerSocket;
|
|
|
|
|
import java.util.Properties;
|
|
|
|
|
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.I2PSocketManager;
|
|
|
|
|
import net.i2p.client.streaming.I2PSocketManagerFactory;
|
|
|
|
|
import net.i2p.util.Log;
|
|
|
|
@ -73,9 +76,9 @@ public class MUXlisten implements Runnable {
|
|
|
|
|
this.database.getReadLock();
|
|
|
|
|
this.info.getReadLock();
|
|
|
|
|
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.
|
|
|
|
|
Properties R = (Properties)info.get("PROPERTIES");
|
|
|
|
|
Properties R = (Properties) info.get("PROPERTIES");
|
|
|
|
|
Properties Q = new Properties();
|
|
|
|
|
Lifted.copyProperties(R, Q);
|
|
|
|
|
this.database.releaseReadLock();
|
|
|
|
@ -85,7 +88,7 @@ public class MUXlisten implements Runnable {
|
|
|
|
|
this.info.getReadLock();
|
|
|
|
|
this.go_out = info.exists("OUTPORT");
|
|
|
|
|
this.come_in = info.exists("INPORT");
|
|
|
|
|
if(this.come_in) {
|
|
|
|
|
if (this.come_in) {
|
|
|
|
|
port = Integer.parseInt(info.get("INPORT").toString());
|
|
|
|
|
host = InetAddress.getByName(info.get("INHOST").toString());
|
|
|
|
|
}
|
|
|
|
@ -93,7 +96,7 @@ public class MUXlisten implements Runnable {
|
|
|
|
|
this.info.releaseReadLock();
|
|
|
|
|
|
|
|
|
|
socketManager = I2PSocketManagerFactory.createManager(prikey, Q);
|
|
|
|
|
if(this.come_in) {
|
|
|
|
|
if (this.come_in) {
|
|
|
|
|
this.listener = new ServerSocket(port, backlog, host);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -130,40 +133,44 @@ public class MUXlisten implements Runnable {
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public void run() {
|
|
|
|
|
|
|
|
|
|
I2PServerSocket SS = null;
|
|
|
|
|
try {
|
|
|
|
|
wlock();
|
|
|
|
|
try {
|
|
|
|
|
info.add("RUNNING", new Boolean(true));
|
|
|
|
|
info.add("STARTING", new Boolean(false));
|
|
|
|
|
} catch(Exception e) {
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
wunlock();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
} catch(Exception e) {
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
wunlock();
|
|
|
|
|
} catch(Exception e) {
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 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
|
|
|
|
|
|
|
|
|
|
if(go_out) {
|
|
|
|
|
if (go_out) {
|
|
|
|
|
// 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);
|
|
|
|
|
t.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(come_in) {
|
|
|
|
|
if (come_in) {
|
|
|
|
|
// TCP -> I2P
|
|
|
|
|
TCPlistener conn = new TCPlistener(listener, socketManager, info, database, _log);
|
|
|
|
|
Thread q = new Thread(tg, conn, "BOBTCPlistener" + N);
|
|
|
|
@ -171,26 +178,26 @@ die: {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boolean spin = true;
|
|
|
|
|
while(spin) {
|
|
|
|
|
while (spin) {
|
|
|
|
|
try {
|
|
|
|
|
Thread.sleep(200); //sleep for 200 ms (Two thenths second)
|
|
|
|
|
} catch(InterruptedException e) {
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
// nop
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
rlock();
|
|
|
|
|
try {
|
|
|
|
|
spin = info.get("STOPPING").equals(Boolean.FALSE);
|
|
|
|
|
} catch(Exception e) {
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
runlock();
|
|
|
|
|
break die;
|
|
|
|
|
}
|
|
|
|
|
} catch(Exception e) {
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
break die;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
runlock();
|
|
|
|
|
} catch(Exception e) {
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
break die;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -199,80 +206,62 @@ die: {
|
|
|
|
|
wlock();
|
|
|
|
|
try {
|
|
|
|
|
info.add("RUNNING", new Boolean(false));
|
|
|
|
|
} catch(Exception e) {
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
wunlock();
|
|
|
|
|
break die;
|
|
|
|
|
}
|
|
|
|
|
} catch(Exception e) {
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
break die;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
wunlock();
|
|
|
|
|
} catch(Exception e) {
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
break die;
|
|
|
|
|
}
|
|
|
|
|
} // die
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
Thread.sleep(500); //sleep for 500 ms (One half second)
|
|
|
|
|
} catch(InterruptedException ex) {
|
|
|
|
|
// nop
|
|
|
|
|
}
|
|
|
|
|
// try {
|
|
|
|
|
// Thread.sleep(500); //sleep for 500 ms (One half second)
|
|
|
|
|
// } catch (InterruptedException ex) {
|
|
|
|
|
// // 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(); // unwedge any blocking threads.
|
|
|
|
|
while(tg.activeCount() + tg.activeGroupCount() != 0) {
|
|
|
|
|
if (tg.activeCount() + tg.activeGroupCount() != 0) {
|
|
|
|
|
while (tg.activeCount() + tg.activeGroupCount() != 0) {
|
|
|
|
|
tg.interrupt(); // unwedge any blocking threads.
|
|
|
|
|
try {
|
|
|
|
|
Thread.sleep(100); //sleep for 100 ms (One tenth second)
|
|
|
|
|
} catch(InterruptedException ex) {
|
|
|
|
|
// nop
|
|
|
|
|
} catch (InterruptedException ex) {
|
|
|
|
|
// NOP
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
tg.destroy();
|
|
|
|
|
// Zap reference to the ThreadGroup so the JVM can GC it.
|
|
|
|
|
tg = null;
|
|
|
|
|
} catch(Exception e) {
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
// System.out.println("MUXlisten: Caught an exception" + e);
|
|
|
|
|
break quit;
|
|
|
|
|
}
|
|
|
|
|
} // quit
|
|
|
|
|
// 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: 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, 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.
|
|
|
|
|
if(tg != null) {
|
|
|
|
|
if(tg.activeCount() + tg.activeGroupCount() != 0) {
|
|
|
|
|
tg.interrupt(); // unwedge any blocking threads.
|
|
|
|
|
while(tg.activeCount() + tg.activeGroupCount() != 0) {
|
|
|
|
|
if (tg != null) {
|
|
|
|
|
if (tg.activeCount() + tg.activeGroupCount() != 0) {
|
|
|
|
|
tg.interrupt(); // unwedge any blocking threads.
|
|
|
|
|
while (tg.activeCount() + tg.activeGroupCount() != 0) {
|
|
|
|
|
try {
|
|
|
|
|
Thread.sleep(100); //sleep for 100 ms (One tenth second)
|
|
|
|
|
} catch(InterruptedException ex) {
|
|
|
|
|
} catch (InterruptedException ex) {
|
|
|
|
|
// nop
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -282,18 +271,49 @@ die: {
|
|
|
|
|
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.
|
|
|
|
|
if(this.come_in) {
|
|
|
|
|
if (this.come_in) {
|
|
|
|
|
try {
|
|
|
|
|
listener.close();
|
|
|
|
|
} catch(IOException e) {
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
socketManager.destroySocketManager();
|
|
|
|
|
} catch(Exception e) {
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
// 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();
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|