diff --git a/apps/BOB/nbproject/project.properties b/apps/BOB/nbproject/project.properties
index 7a94ff6ddd..9eeffd29f1 100644
--- a/apps/BOB/nbproject/project.properties
+++ b/apps/BOB/nbproject/project.properties
@@ -24,40 +24,24 @@ dist.dir=dist
dist.jar=${dist.dir}/BOB.jar
dist.javadoc.dir=${dist.dir}/javadoc
excludes=
-file.reference.build-javadoc=../../../i2p.i2p/build/javadoc
-file.reference.core.jar=../i2p.i2p/core/dist/core.jar
-file.reference.i2p.jar=../../bob/i2p/i2p.i2p/build/i2p.jar
-file.reference.i2p.jar-1=../../build/i2p.jar
-file.reference.i2p.jar-2=../i2p.i2p/core/java/build/i2p.jar
-file.reference.i2p.jar-3=../../../i2p.i2p/build/i2p.jar
-file.reference.i2ptunnel.jar=../../../i2p.i2p/build/i2ptunnel.jar
-file.reference.java-src=../i2p.i2p/core/java/src/
-file.reference.jbigi.jar=../../bob/i2p/i2p.i2p/build/jbigi.jar
-file.reference.mstreaming.jar=../../bob/i2p/i2p.i2p/build/mstreaming.jar
-file.reference.mstreaming.jar-1=../../build/mstreaming.jar
-file.reference.mstreaming.jar-2=../../../i2p.i2p/build/mstreaming.jar
-file.reference.NetBeansProjects-i2p.i2p=../i2p.i2p/
-file.reference.router.jar=../../build/router.jar
-file.reference.streaming.jar=../../bob/i2p/i2p.i2p/build/streaming.jar
-file.reference.streaming.jar-1=../../../i2p.i2p/build/streaming.jar
-file.reference.wrapper-freebsd=../../installer/lib/wrapper/freebsd/
-file.reference.wrapper-linux=../../installer/lib/wrapper/linux/
-file.reference.wrapper-linux64=../../installer/lib/wrapper/linux64/
-file.reference.wrapper-macosx=../../installer/lib/wrapper/macosx/
-file.reference.wrapper-solaris=../../installer/lib/wrapper/solaris/
-file.reference.wrapper-win32=../../installer/lib/wrapper/win32/
+file.reference.build-javadoc=../../i2p.i2p/build/javadoc
+file.reference.i2p.jar=../../core/java/build/i2p.jar
+file.reference.i2ptunnel.jar=../i2ptunnel/java/build/i2ptunnel.jar
+file.reference.jbigi.jar=../../installer/lib/jbigi/jbigi.jar
+file.reference.mstreaming.jar=../ministreaming/java/build/mstreaming.jar
+file.reference.router.jar=../../router/java/build/router.jar
+file.reference.streaming.jar=../streaming/java/build/streaming.jar
file.reference.wrapper.jar=../../installer/lib/wrapper/linux/wrapper.jar
includes=**
jar.compress=false
javac.classpath=\
- ${file.reference.wrapper.jar}:\
- ${file.reference.streaming.jar-1}:\
- ${file.reference.i2ptunnel.jar}:\
- ${file.reference.i2p.jar-1}:\
${file.reference.router.jar}:\
- ${file.reference.mstreaming.jar-1}:\
- ${file.reference.mstreaming.jar-2}:\
- ${file.reference.i2p.jar-3}
+ ${file.reference.i2ptunnel.jar}:\
+ ${file.reference.mstreaming.jar}:\
+ ${file.reference.streaming.jar}:\
+ ${file.reference.wrapper.jar}:\
+ ${file.reference.i2p.jar}:\
+ ${file.reference.router.jar}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
diff --git a/apps/BOB/src/net/i2p/BOB/BOB.java b/apps/BOB/src/net/i2p/BOB/BOB.java
index 59b46b8d74..830808a549 100644
--- a/apps/BOB/src/net/i2p/BOB/BOB.java
+++ b/apps/BOB/src/net/i2p/BOB/BOB.java
@@ -34,6 +34,9 @@ import java.util.Properties;
import net.i2p.client.I2PClient;
import net.i2p.client.streaming.RetransmissionTimer;
import net.i2p.util.Log;
+import net.i2p.util.SimpleScheduler;
+import net.i2p.util.SimpleTimer2;
+
/**
*
* ################################################################################
@@ -157,12 +160,15 @@ public class BOB {
boolean save = false;
// Set up all defaults to be passed forward to other threads.
// Re-reading the config file in each thread is pretty damn stupid.
- // I2PClient client = I2PClientFactory.createClient();
String configLocation = System.getProperty(PROP_CONFIG_LOCATION, "bob.config");
-
// This is here just to ensure there is no interference with our threadgroups.
RetransmissionTimer Y = RetransmissionTimer.getInstance();
+ SimpleScheduler Y1 = SimpleScheduler.getInstance();
+ SimpleTimer2 Y2 = SimpleTimer2.getInstance();
i = Y.hashCode();
+ i = Y1.hashCode();
+ i = Y2.hashCode();
+
{
try {
FileInputStream fi = new FileInputStream(configLocation);
diff --git a/apps/BOB/src/net/i2p/BOB/DoCMDS.java b/apps/BOB/src/net/i2p/BOB/DoCMDS.java
index 099d69feca..16da28ce9c 100644
--- a/apps/BOB/src/net/i2p/BOB/DoCMDS.java
+++ b/apps/BOB/src/net/i2p/BOB/DoCMDS.java
@@ -46,7 +46,7 @@ public class DoCMDS implements Runnable {
// FIX ME
// I need a better way to do versioning, but this will do for now.
- public static final String BMAJ = "00", BMIN = "00", BREV = "04", BEXT = "";
+ public static final String BMAJ = "00", BMIN = "00", BREV = "05", BEXT = "";
public static final String BOBversion = BMAJ + "." + BMIN + "." + BREV + BEXT;
private Socket server;
private Properties props;
@@ -748,14 +748,12 @@ public class DoCMDS implements Runnable {
nickinfo = (NamedDB) database.get(Arg);
if (!tunnelactive(nickinfo)) {
nickinfo = null;
- ns =
- true;
+ ns = true;
}
} catch (Exception b) {
nickinfo = null;
- ns =
- true;
+ ns = true;
}
try {
@@ -775,10 +773,10 @@ public class DoCMDS implements Runnable {
try {
database.add(Arg, nickinfo);
nickinfo.add(P_NICKNAME, Arg);
- nickinfo.add(P_STARTING, Boolean.FALSE);
- nickinfo.add(P_RUNNING, Boolean.FALSE);
- nickinfo.add(P_STOPPING, Boolean.FALSE);
- nickinfo.add(P_QUIET, Boolean.FALSE);
+ nickinfo.add(P_STARTING, new Boolean(false));
+ nickinfo.add(P_RUNNING, new Boolean(false));
+ nickinfo.add(P_STOPPING, new Boolean(false));
+ nickinfo.add(P_QUIET, new Boolean(false));
nickinfo.add(P_INHOST, "localhost");
nickinfo.add(P_OUTHOST, "localhost");
Properties Q = new Properties();
@@ -1265,13 +1263,17 @@ 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
+ }
out.println("OK tunnel starting");
} catch (I2PException e) {
out.println("ERROR starting tunnel: " + e);
} catch (IOException e) {
out.println("ERROR starting tunnel: " + e);
}
-
}
} catch (Exception ex) {
break die;
@@ -1304,7 +1306,7 @@ public class DoCMDS implements Runnable {
break die;
}
- nickinfo.add(P_STOPPING, Boolean.TRUE);
+ nickinfo.add(P_STOPPING, new Boolean(true));
try {
wunlock();
diff --git a/apps/BOB/src/net/i2p/BOB/I2Plistener.java b/apps/BOB/src/net/i2p/BOB/I2Plistener.java
index c59683270e..a8115893db 100644
--- a/apps/BOB/src/net/i2p/BOB/I2Plistener.java
+++ b/apps/BOB/src/net/i2p/BOB/I2Plistener.java
@@ -26,8 +26,6 @@ package net.i2p.BOB;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
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.I2PSocket;
import net.i2p.client.streaming.I2PSocketManager;
@@ -42,24 +40,35 @@ public class I2Plistener implements Runnable {
private NamedDB info, database;
private Log _log;
- private int tgwatch;
+// private int tgwatch;
public I2PSocketManager socketManager;
public I2PServerSocket serverSocket;
/**
* Constructor
+ * @param SS
* @param S
* @param info
* @param database
* @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.info = info;
this._log = _log;
this.socketManager = S;
- serverSocket = this.socketManager.getServerSocket();
- tgwatch = 1;
+ serverSocket = SS;
+// tgwatch = 1;
+ }
+
+ private void rlock() throws Exception {
+ database.getReadLock();
+ info.getReadLock();
+ }
+
+ private void runlock() throws Exception {
+ database.releaseReadLock();
+ info.releaseReadLock();
}
/**
@@ -70,68 +79,90 @@ public class I2Plistener implements Runnable {
boolean g = false;
I2PSocket sessSocket = null;
- serverSocket.setSoTimeout(50);
- database.getReadLock();
- info.getReadLock();
- if(info.exists("INPORT")) {
- tgwatch = 2;
- }
- info.releaseReadLock();
- database.releaseReadLock();
- boolean spin = true;
- while(spin) {
+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) {
- database.getReadLock();
- info.getReadLock();
- spin = info.get("RUNNING").equals(Boolean.TRUE);
- info.releaseReadLock();
- database.releaseReadLock();
- try {
try {
- sessSocket = serverSocket.accept();
- g = true;
- } catch(ConnectException ce) {
- g = false;
- } catch(SocketTimeoutException ste) {
- g = false;
+ rlock();
+ } catch (Exception e) {
+ break die;
}
- 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();
+ try {
+ 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;
+ // toss the connection to a new thread.
+ I2PtoTCP conn_c = new I2PtoTCP(sessSocket, info, database);
+ Thread t = new Thread(conn_c, "BOBI2PtoTCP");
+ t.start();
+ }
- } catch(I2PException e) {
- // System.out.println("Exception " + e);
+ } catch (I2PException e) {
+ // System.out.println("Exception " + e);
+ }
}
}
// System.out.println("I2Plistener: Close");
- 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.");
+
+ // 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 5d24e19d36..0984823b6e 100644
--- a/apps/BOB/src/net/i2p/BOB/I2PtoTCP.java
+++ b/apps/BOB/src/net/i2p/BOB/I2PtoTCP.java
@@ -23,6 +23,7 @@
*/
package net.i2p.BOB;
+import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
@@ -105,8 +106,8 @@ die: {
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
+ 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!
@@ -116,7 +117,22 @@ die: {
try {
Thread.sleep(10); //sleep for 10 ms
} catch(InterruptedException e) {
- // nop
+ try {
+ in.close();
+ } catch(Exception ex) {
+ }
+ try {
+ out.close();
+ } catch(Exception ex) {
+ }
+ try {
+ Iin.close();
+ } catch(Exception ex) {
+ }
+ try {
+ Iout.close();
+ } catch(Exception ex) {
+ }
}
}
// System.out.println("I2PtoTCP: Going away...");
diff --git a/apps/BOB/src/net/i2p/BOB/MUXlisten.java b/apps/BOB/src/net/i2p/BOB/MUXlisten.java
index 89ab53fe62..dc30c5445d 100644
--- a/apps/BOB/src/net/i2p/BOB/MUXlisten.java
+++ b/apps/BOB/src/net/i2p/BOB/MUXlisten.java
@@ -29,10 +29,12 @@ 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;
import net.i2p.util.Log;
-import org.tanukisoftware.wrapper.WrapperManager;
/**
*
@@ -56,8 +58,8 @@ public class MUXlisten implements Runnable {
/**
* Constructor Will fail if INPORT is occupied.
*
- * @param info
- * @param database
+ * @param info DB entry for this tunnel
+ * @param database master database of tunnels
* @param _log
* @throws net.i2p.I2PException
* @throws java.io.IOException
@@ -73,9 +75,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 +87,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,14 +95,14 @@ 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);
}
// Everything is OK as far as we can tell.
this.database.getWriteLock();
this.info.getWriteLock();
- this.info.add("STARTING", Boolean.TRUE);
+ this.info.add("STARTING", new Boolean(true));
this.info.releaseWriteLock();
this.database.releaseWriteLock();
}
@@ -130,67 +132,87 @@ public class MUXlisten implements Runnable {
*
*/
public void run() {
-
+ I2PServerSocket SS = null;
+ int ticks = 1200; // Allow 120 seconds, no more.
try {
wlock();
try {
- info.add("RUNNING", Boolean.TRUE);
- info.add("STARTING", Boolean.FALSE);
- } catch(Exception e) {
+ info.add("RUNNING", new Boolean(true));
+ } 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);
q.start();
}
- boolean spin = true;
- while(spin) {
+ try {
+ wlock();
try {
- Thread.sleep(200); //sleep for 200 ms (Two thenths second)
- } catch(InterruptedException e) {
- // nop
+ info.add("STARTING", new Boolean(false));
+ } catch (Exception e) {
+ wunlock();
+ break die;
+ }
+ } 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;
}
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;
}
}
@@ -198,102 +220,186 @@ die: {
try {
wlock();
try {
- info.add("RUNNING", Boolean.FALSE);
- } catch(Exception e) {
+ info.add("RUNNING", new Boolean(false));
+ } 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
+ 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 {
- Thread.sleep(500); //sleep for 500 ms (One half second)
- } catch(InterruptedException ex) {
+ socketManager.destroySocketManager();
+ } catch (Exception e) {
// 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");
- 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) && ticks != 0) {
+ tg.interrupt(); // unwedge any blocking threads.
+ ticks--;
try {
Thread.sleep(100); //sleep for 100 ms (One tenth second)
- } catch(InterruptedException ex) {
- // nop
+ } 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;
- } 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) {
- 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", Boolean.FALSE);
- info.add("STOPPING", Boolean.FALSE);
- info.add("RUNNING", Boolean.FALSE);
- } catch(Exception e) {
- wunlock();
- return;
+ if (tg != null) {
+ if (SS != null) {
+ try {
+ SS.close();
+ } catch (I2PException ex) {
+ //Logger.getLogger(MUXlisten.class.getName()).log(Level.SEVERE, null, ex);
+ }
}
- wunlock();
- } catch(Exception e) {
- }
- // This is here to catch when something fucks up REALLY bad.
- if(tg != null) {
- if(tg.activeCount() + tg.activeGroupCount() != 0) {
+ if (this.come_in) {
+ try {
+ listener.close();
+ } catch (IOException e) {
+ }
+ }
+ try {
+ socketManager.destroySocketManager();
+ } catch (Exception e) {
+ // nop
+ }
+ ticks = 600; // 60 seconds
+ if (tg.activeCount() + tg.activeGroupCount() != 0) {
+ while ((tg.activeCount() + tg.activeGroupCount() != 0) && ticks != 0) {
tg.interrupt(); // unwedge any blocking threads.
- while(tg.activeCount() + tg.activeGroupCount() != 0) {
+ ticks--;
try {
Thread.sleep(100); //sleep for 100 ms (One tenth second)
- } catch(InterruptedException ex) {
+ } catch (InterruptedException ex) {
// nop
}
}
}
- tg.destroy();
- // Zap reference to the ThreadGroup so the JVM can GC it.
- tg = null;
- }
-
- // Lastly try to close things again.
- if(this.come_in) {
- try {
- listener.close();
- } catch(IOException e) {
+ 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: Can't kill threads. Please send the following dump to sponge@mail.i2p");
+ System.out.println("\n\nBOB: MUXlisten: ThreadGroup dump BEGIN");
+ visit(tg, 0);
+ System.out.println("BOB: MUXlisten: ThreadGroup dump END\n\n");
}
}
+
+ // 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 {
- socketManager.destroySocketManager();
- } catch(Exception e) {
- // nop
+ 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) {
}
}
+
+
+ // Debugging...
+
+ /**
+ * Find the root thread group and print them all.
+ *
+ */
+ private void visitAllThreads() {
+ ThreadGroup root = Thread.currentThread().getThreadGroup().getParent();
+ while (root.getParent() != null) {
+ root = root.getParent();
+ }
+
+ // Visit each thread group
+ visit(root, 0);
+ }
+
+ /**
+ * Recursively visits all thread groups under `group' and dumps them.
+ * @param group ThreadGroup to visit
+ * @param level Current level
+ */
+ private static void visit(ThreadGroup group, int level) {
+ // Get threads in `group'
+ int numThreads = group.activeCount();
+ Thread[] threads = new Thread[numThreads * 2];
+ numThreads = group.enumerate(threads, false);
+ String indent = "------------------------------------".substring(0, level) + "-> ";
+ // Enumerate each thread in `group' and print it.
+ for (int i = 0; i < numThreads; i++) {
+ // Get thread
+ Thread thread = threads[i];
+ System.out.println("BOB: MUXlisten: " + indent + thread.toString());
+ }
+
+ // 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++) {
+ visit(groups[i], level + 1);
+ }
+ }
}
diff --git a/apps/BOB/src/net/i2p/BOB/Main.java b/apps/BOB/src/net/i2p/BOB/Main.java
index 2d81fb30ed..aa56e83e02 100644
--- a/apps/BOB/src/net/i2p/BOB/Main.java
+++ b/apps/BOB/src/net/i2p/BOB/Main.java
@@ -24,7 +24,8 @@
package net.i2p.BOB;
import net.i2p.client.streaming.RetransmissionTimer;
-
+import net.i2p.util.SimpleScheduler;
+import net.i2p.util.SimpleTimer2;
/**
* Start from command line
*
@@ -39,7 +40,13 @@ public class Main {
public static void main(String[] args) {
// THINK THINK THINK THINK THINK THINK
RetransmissionTimer Y = RetransmissionTimer.getInstance();
+ SimpleScheduler Y1 = SimpleScheduler.getInstance();
+ SimpleTimer2 Y2 = SimpleTimer2.getInstance();
+
BOB.main(args);
+
+ Y2.stop();
+ Y1.stop();
Y.stop();
}
}
diff --git a/apps/BOB/src/net/i2p/BOB/TCPio.java b/apps/BOB/src/net/i2p/BOB/TCPio.java
index c9f4ab64cd..d4b353c549 100644
--- a/apps/BOB/src/net/i2p/BOB/TCPio.java
+++ b/apps/BOB/src/net/i2p/BOB/TCPio.java
@@ -23,6 +23,7 @@
*/
package net.i2p.BOB;
+import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -35,21 +36,21 @@ public class TCPio implements Runnable {
private InputStream Ain;
private OutputStream Aout;
- private NamedDB info, database;
+ // private NamedDB info, database;
/**
* Constructor
*
- * @param Ain
- * @param Aout
- * @param info
- * @param database
+ * @param Ain InputStream
+ * @param Aout OutputStream
+ *
+ * param database
*/
- TCPio(InputStream Ain, OutputStream Aout, NamedDB info, NamedDB database) {
+ TCPio(InputStream Ain, OutputStream Aout /*, NamedDB info , NamedDB database */) {
this.Ain = Ain;
this.Aout = Aout;
- this.info = info;
- this.database = database;
+ // this.info = info;
+ // this.database = database;
}
/**
@@ -86,11 +87,11 @@ 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();
+ // 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) {
@@ -98,11 +99,11 @@ public class TCPio implements Runnable {
} else if(b == 0) {
Thread.yield(); // this should act like a mini sleep.
if(Ain.available() == 0) {
- try {
+// try {
// Thread.yield();
Thread.sleep(10);
- } catch(InterruptedException ex) {
- }
+// } catch(InterruptedException ex) {
+// }
}
} else {
/* according to the specs:
@@ -113,13 +114,25 @@ public class TCPio implements Runnable {
*
*/
// System.out.println("TCPio: End Of Stream");
+ Ain.close();
+ Aout.close();
return;
}
}
// System.out.println("TCPio: RUNNING = false");
} catch(Exception e) {
// Eject!!! Eject!!!
- // System.out.println("TCPio: Caught an exception " + e);
+ //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;
}
// System.out.println("TCPio: Leaving.");
diff --git a/apps/BOB/src/net/i2p/BOB/TCPlistener.java b/apps/BOB/src/net/i2p/BOB/TCPlistener.java
index 30380a55dd..78155eb787 100644
--- a/apps/BOB/src/net/i2p/BOB/TCPlistener.java
+++ b/apps/BOB/src/net/i2p/BOB/TCPlistener.java
@@ -27,8 +27,8 @@ import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
-import net.i2p.client.I2PSession;
-import net.i2p.client.I2PSessionException;
+// 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.util.Log;
@@ -63,6 +63,26 @@ public class TCPlistener implements Runnable {
tgwatch = 1;
}
+ private void rlock() throws Exception {
+ database.getReadLock();
+ info.getReadLock();
+ }
+
+ private void runlock() throws Exception {
+ database.releaseReadLock();
+ 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
*
@@ -70,77 +90,123 @@ public class TCPlistener implements Runnable {
public void run() {
boolean g = false;
boolean spin = true;
- database.getReadLock();
- info.getReadLock();
- if(info.exists("OUTPORT")) {
- tgwatch = 2;
- }
- try {
- Socket server = new Socket();
- listener.setSoTimeout(50); // Half of the expected time from MUXlisten
- info.releaseReadLock();
- database.releaseReadLock();
- while(spin) {
- database.getReadLock();
- info.getReadLock();
- spin = info.get("RUNNING").equals(Boolean.TRUE);
- info.releaseReadLock();
- database.releaseReadLock();
- 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, info, database);
- 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
- database.getReadLock();
- info.getReadLock();
- spin = info.get("RUNNING").equals(Boolean.TRUE);
- info.releaseReadLock();
- database.releaseReadLock();
- if(spin) {
- database.getWriteLock();
- info.getWriteLock();
- info.add("STOPPING", new Boolean(true));
- info.add("RUNNING", new Boolean(false));
- info.releaseWriteLock();
- database.releaseWriteLock();
- }
- }
- // need to kill off the socket manager too.
- I2PSession session = socketManager.getSession();
- if(session != null) {
+die: {
try {
- session.destroySession();
- } catch(I2PSessionException ex) {
- // nop
+ rlock();
+ } catch (Exception e) {
+ break die;
+ }
+ try {
+ if (info.exists("OUTPORT")) {
+ tgwatch = 2;
+ }
+ } catch (Exception e) {
+ try {
+ runlock();
+ } catch (Exception e2) {
+ break die;
+ }
+ break die;
+ }
+ try {
+ runlock();
+ } catch (Exception e) {
+ break die;
+ }
+ try {
+ Socket server = new Socket();
+ listener.setSoTimeout(50); // Half of the expected time from MUXlisten
+ 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) {
+ break die;
+ }
+ break die;
+ }
+ 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 /* , info, database */);
+ 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;
+ }
+ }
}
}
- //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) {
+ // 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: Done.");
+ // }
+ //}
+ //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 df61e78e1b..c376e16fe1 100644
--- a/apps/BOB/src/net/i2p/BOB/TCPtoI2P.java
+++ b/apps/BOB/src/net/i2p/BOB/TCPtoI2P.java
@@ -45,7 +45,7 @@ import net.i2p.i2ptunnel.I2PTunnel;
public class TCPtoI2P implements Runnable {
private I2PSocket I2P;
- private NamedDB info, database;
+ // private NamedDB info, database;
private Socket sock;
private I2PSocketManager socketManager;
@@ -84,13 +84,13 @@ public class TCPtoI2P implements Runnable {
* Constructor
* @param i2p
* @param socket
- * @param info
- * @param database
+ * param info
+ * param database
*/
- TCPtoI2P(I2PSocketManager i2p, Socket socket, NamedDB info, NamedDB database) {
+ TCPtoI2P(I2PSocketManager i2p, Socket socket /*, NamedDB info, NamedDB database */) {
this.sock = socket;
- this.info = info;
- this.database = database;
+ // this.info = info;
+ // this.database = database;
this.socketManager = i2p;
}
@@ -110,14 +110,19 @@ public class TCPtoI2P implements Runnable {
/**
* TCP stream to I2P stream thread starter
+ *
*/
public void run() {
String line, input;
+ InputStream Iin = null;
+ OutputStream Iout = null;
+ InputStream in = null;
+ OutputStream out = null;
try {
- InputStream in = sock.getInputStream();
- OutputStream out = sock.getOutputStream();
+ in = sock.getInputStream();
+ out = sock.getOutputStream();
try {
line = lnRead(in);
input = line.toLowerCase();
@@ -135,22 +140,22 @@ public class TCPtoI2P implements Runnable {
I2P = socketManager.connect(dest);
I2P.setReadTimeout(0); // temp bugfix, this *SHOULD* be the default
// make readers/writers
- InputStream Iin = I2P.getInputStream();
- OutputStream Iout = I2P.getOutputStream();
+ 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
+ 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 {
+// try {
Thread.sleep(10); //sleep for 10 ms
- } catch(InterruptedException e) {
+// } catch(InterruptedException e) {
// nop
- }
+// }
}
// System.out.println("TCPtoI2P: Going away...");
@@ -167,7 +172,24 @@ public class TCPtoI2P implements Runnable {
} catch(Exception e) {
Emsg("ERROR " + e.toString(), out);
}
- } catch(IOException ioe) {
+ } 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");
@@ -181,6 +203,5 @@ public class TCPtoI2P implements Runnable {
} catch(Exception e) {
}
// System.out.println("TCPtoI2P: Done.");
-
}
}
diff --git a/apps/desktopgui/LICENSE b/apps/desktopgui/LICENSE
new file mode 100644
index 0000000000..61febe9011
--- /dev/null
+++ b/apps/desktopgui/LICENSE
@@ -0,0 +1,15 @@
+Desktop GUI: provides a simple GUI for I2P.
+Copyright (C) 2009 Mathias De Maré
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; only version 2 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
\ No newline at end of file
diff --git a/apps/desktopgui/build.xml b/apps/desktopgui/build.xml
new file mode 100644
index 0000000000..77bd6d7785
--- /dev/null
+++ b/apps/desktopgui/build.xml
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+ Builds, tests, and runs the project desktopgui.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/desktopgui/desktopgui/resources/howto/howto.html b/apps/desktopgui/desktopgui/resources/howto/howto.html
new file mode 100644
index 0000000000..ea1b025c7b
--- /dev/null
+++ b/apps/desktopgui/desktopgui/resources/howto/howto.html
@@ -0,0 +1,261 @@
+
+
+ Small Guide to I2P
+
+
+ Small Guide to I2P
+
+ So, what's this all about?
+
+ I2P builds up a new net inside the usual internet, connecting nodes together
+ via encrypted connections.
+ It is a JAVA prgram with its most used part (the encryption of the data) written
+ in handoptimized assembler code.
+ It will use your bandwith, your RAM and your CPU. It will use them all up if you
+ do not limit it.
+ I2P will route unknown traffic through your node, even stuff you dislike.
+ As that data is encrypted, nobody knows whats data went to or drom your node.
+
+
+
+ First, ALWAYS use the latest stable release.
+ Development releases are called "mtn version" and are marked with a -, e.g.
+ 0.6.5-1. Those are usually useable by all but could do harm to your I2P
+ experience.
+ You can get the latest MTN builds from my eepsite echelon.i2p, but always
+ remember: I built them, you need to trust me not to changed the code!
+ After you get the right "i2pupdate.zip" file, put that file into the I2P
+ directory and hit restart on the router console http://127.0.0.1:7657.
+ Do NOT deflate the zip file!
+
+
+
+ I2P is very dynamic - after startup it tries to get known to other I2P routers
+ and measures their speed - you need to wait some 10-120 minutes until your
+ I2P router knows enough other ones to obtain full power of I2P.
+
+
+ Filesharing
+
+
+ I2P is able to do anonymous filesharing.
+ But as there are NO gateways between real net and I2P, you can only share/
+ download torrents from within I2P. Look e.g. postman.i2p or planet.i2p.
+ You CANNOT use azureus, utorrent or any other usual client.
+ You cannot download anonymous torrents from mininova, piratebay or else.
+ You need to use I2P internal torrents and I2P aware programs like
+ I2Psnark (builtin, suitable for 1-20 torrents)
+ I2PRufus (external, python, high CPU load, suitable >20 torrents) http://echelon.i2p/i2prufus
+ I2P-BT (external, python)
+ I2PsnarkXL (mod of I2Psnark made by fwd)
+
+
+
+ There are also gnutella and edonkey clients:
+ i2phex for gnutella (http://echelon.i2p/i2phex)
+ imule for edonkey (http://echelon.i2p/imule)
+
+
+
+ Remember, as I2P uses other routers to route your traffic via 1-6 other PCs,
+ your transferrates in P2P are slower than in usual internet.
+ But you are anonymous, no one can easily (within 2 months-2 years) get your IP!
+ torrents inside of I2P reaches up to 50 kb/sec, usual are 10-20 kb/sec per torrent
+ i2phex reaches up to 20 kb/sec, usually 5-10 kb/sec
+ imule in times reaches 10 kb/sec, usually 5-10 kb/sec
+
+
+
+ In I2PHex and imule you can just tell "share file or directory", in torrent
+ you need to create a .torrent file and upload that (and ONLY that small .torrent)
+ file to the trackers like tracker.postman.i2p/
+
+
+
+ I2P is a smaller net (1000 users) which grows slowly. As of which amount of shared
+ data will slowly rise.
+
+
+
+ I2P is anonymous and it does not censor - there is no administrator.
+ There IS unwanted stuff like kiddyporn, nazism, or else.
+ If you dislike all this, do not use I2P.
+ There is NO way to prohibite this stuff to appear in a anonymous net like I2P.
+ (as that stuff is available shows the anonymity and transfer function of I2P
+ is working well enough)
+ You can delete the destinations in question from your local hosts.txt file (or
+ deface them) which will partly prevent you to reach those bad sies by accident.
+
+
+ Internet (the websites)
+
+
+ Only one outproxy (gateway I2P - webpages in usual Internet) is working.
+ It is NOT official from I2P, I2P does work without.
+ If that outproxy is slow, offline, gone,.. I2P still works on and cannot do
+ anything to change that failure.
+ That outproxy translates usual internet webpages into the I2P net and you can
+ reach them via your Router.
+ The best way for usual webpages is TOR, not that outproxy.
+ Remember: the owner of the outproxy got ALL traffic from all I2P users
+ visiting Internet pages and will risk that into the police!
+
+
+
+ This proxy is false.i2p. In newer I2P routers it is enabled, but not in
+ older ones. Go to http://127.0.0.1:7657/i2ptunnel/index.jsp tunnels page and
+ click on the eepProxy tunnel. Change the entry for the "Outproxies" to false.i2p
+ and save. On the tunnels page, stop the epproxy tunnel and start it again,
+ now your router will use the false.i2p outproxy.
+
+
+
+ No other (known) gateways are setup and running. No one we know will run
+ the gateway for torrent or any other P2P data (and risk his life).
+
+
+ Bandwidth
+
+ http://127.0.0.1:7657/config.jsp
+
+ Setup your bandwith wisely. Know your linespeed!
+
+
+ E.g. most common terms are:
+ 1Mbit = roughly 100 kbyte/sec
+ 10 MBit = roughly 1100 kbyte/sec
+ 512 kbit = roughly 50 kbyte/sec
+ or in germany:
+ 16000er = roughly 1500 kbyte/sec
+ 6000er = roughly 600 kbyte/sec
+ 1000er = roughly 100 kb/sec
+
+
+
+ Set your bandwith limits to 10% under your line speed and burst rate to
+ your line speed.
+ Set the bandwith share percentage to:
+ >80% if lowest bandwith setting is >50k
+ >50% if lowest bandwith setting is >30k
+ >20% if lowest bandwith setting is >16k
+
+
+ There is no shared bandwith under 16k.
+
+
+ Limit your participating tunnels (shared bandwith) on:
+ http://127.0.0.1:7657/configadvanced.jsp
+ with the line:
+ router.maxParticipatingTunnels=500
+
+
+
+ 2000 is for roughly 600 kb/sec - very high value with high CPU load
+ 1000 is for roughly 300 kb/sec
+ 600 is a good value for 150-200kb/sec
+ 300 is roughly 90 kb/sec
+ 150 roughly 50 kb/sec
+ Remember: even failed tunnel requests will result in a part tunnel on the hops in between!
+ Those said, there are far more part tunnels unused than used in the live net under load, which
+ results in slower bandwith per tunnel in the end.
+ It is wise to first limit the bandwith and afterwards the part tunnels, e.g. set some more part
+ tunnels and let I2P reach the bandwith limit instead of the part tunnels limit!
+
+
+ What is shared bandwidth?
+
+
+ I2P transports your date from the client to the server through 1-6 hops
+ (other I2P routers). Each of this hops sees the data from you as "participating
+ tunnel" - which is the shared bandwith of them.
+ With this in mind, I2P needs some amount of this shared bandwith at some
+ amount of routers.
+ Share as much as you are able of - others will thank you!
+
+
+
+ With the "share percentage" set like above, you will obtain enough speed for
+ your own traffic and obtain some participating tunnels (if >16kb/sec) with some
+ noise traffic to hide your traffic in the stream.
+
+
+
+ With release 0.6.5 there is some method to prefer your own traffic ahead
+ of shared traffic which will result in better experience to you!
+
+
+ Addressbook
+
+
+ I2P uses a local addressbook to link short DNS names with the internal used 512bit
+ hashes (which are destination IDs).
+ Those links are saved insside the hosts.txt and userhosts.txt files in the i2p
+ directory.
+ Hosts which are not in those files cannot be reached via the short DNS names
+ and a error message with "jumper links" will appear. Those links will ask
+ some hosts services and forward to the correct site (if the site is known to them).
+ Those hosts services just made a form to add new "hosts" and those results public
+ available.
+ You can subscribe to those hosts service and let your hosts.txt file be updated
+ automatic. Go to http://127.0.0.1:7657/susidns/subscriptions.jsp SusiDNS
+ and enter the hosts services into the textbox (and save afterwards):
+ http://www.i2p2.i2p/hosts.txt
+ http://stats.i2p/cgi-bin/newhosts.txt
+ http://tino.i2p/hosts.txt
+ http://i2host.i2p/cgi-bin/i2hostag
+ You can add one of them, two or all.
+ SusiDNS will now ask those hosts for new entries to the hosts.txt and those
+ will be added to your hosts.txt. The userhosts.txt will ONLY be updated by
+ yourself (the user) and not be published into the net!
+ Remember, names once set could not be changed! If you loose your key (destination
+ ID) to your eepsite, service,..., there is no way to change the linking
+ between the DNS name and the (lost) destination ID automatic! Only manual by each
+ user itself - great topic to discuss of need to renew DNS hostnames.
+ As this subscription will not update old entries, you can "deface" unwanted
+ eepsites with a false key and if you hit the bad name in browser by accident,
+ you will not see the bad stuff!
+
+
+ Out of Memory errors
+
+
+ If your router hits the Out of Memory error - check your logs!
+ Usual point for OOM are to much torrents in i2psnark - i2psnark is a real
+ memory hogg and >10 torrents it requiers hell a lot of memory!
+
+
+
+ Maybe it is possible for you to increase the wrapper memory config.
+ This ONLY works if you start the I2P service restartable with console
+ (on Windows).
+ In I2P directory edit the wrapper.config file and change the values:
+ wrapper.java.maxmemory=256 (or even to 512, IF possible)
+ Afterwards shutdown I2P complete (the service) and restart it.
+
+
+ Blocklists
+
+
+ Sometimes attackers trying to flood the I2P net and try to do some harm.
+ And some folks setting localnet IPs as their internet reachable address.
+ To prevent those bad router to harm the local router, I2P implemented
+ a local blocklist system. It is NOT integrated automatic as it could
+ really harm your I2P experience if setup the wrong way.
+ The way to enable blocklists is:
+ Get the file http://zzz.i2p/files/blocklist.txt and copy this file into the
+ I2P directory.
+ On http://127.0.0.1:7657/configadvanced.jsp set the option
+ router.blocklist.enable=true - click on Apply and restart the router
+ with the restart link left on router console.
+ The blockfile.txt file follows a special order, you´ll get it if you read it.
+ The first entry is the reason to be shown on http://127.0.0.1:7657/profiles.jsp
+ at the bottom in the shitlist section.
+ The second entry is the IP or the dest ID of a router.
+ Right now there are only private subnets in the blocklist AND one chinese router
+ which floods the floodfill DB while restarting every few minutes with a different
+ router ID and far to less bandwith for being a floodfill router.
+
+
+ (By echelon -- echelon.i2p )
+
+
diff --git a/apps/desktopgui/desktopgui/resources/logo/logo.jpg b/apps/desktopgui/desktopgui/resources/logo/logo.jpg
new file mode 100644
index 0000000000..f1b5ccfc87
Binary files /dev/null and b/apps/desktopgui/desktopgui/resources/logo/logo.jpg differ
diff --git a/apps/desktopgui/desktopgui/resources/logo/logo_green.jpg b/apps/desktopgui/desktopgui/resources/logo/logo_green.jpg
new file mode 100644
index 0000000000..9a29b6d1c3
Binary files /dev/null and b/apps/desktopgui/desktopgui/resources/logo/logo_green.jpg differ
diff --git a/apps/desktopgui/desktopgui/resources/logo/logo_orange.jpg b/apps/desktopgui/desktopgui/resources/logo/logo_orange.jpg
new file mode 100644
index 0000000000..137a25e7a0
Binary files /dev/null and b/apps/desktopgui/desktopgui/resources/logo/logo_orange.jpg differ
diff --git a/apps/desktopgui/desktopgui/resources/logo/logo_red.jpg b/apps/desktopgui/desktopgui/resources/logo/logo_red.jpg
new file mode 100644
index 0000000000..1da8983812
Binary files /dev/null and b/apps/desktopgui/desktopgui/resources/logo/logo_red.jpg differ
diff --git a/apps/desktopgui/lib/appframework.jar b/apps/desktopgui/lib/appframework.jar
new file mode 100644
index 0000000000..0b8ff0145f
Binary files /dev/null and b/apps/desktopgui/lib/appframework.jar differ
diff --git a/apps/desktopgui/lib/swing-worker.jar b/apps/desktopgui/lib/swing-worker.jar
new file mode 100644
index 0000000000..bcdd9d9102
Binary files /dev/null and b/apps/desktopgui/lib/swing-worker.jar differ
diff --git a/apps/desktopgui/manifest.mf b/apps/desktopgui/manifest.mf
new file mode 100644
index 0000000000..328e8e5bc3
--- /dev/null
+++ b/apps/desktopgui/manifest.mf
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+X-COMMENT: Main-Class will be added automatically by build
+
diff --git a/apps/desktopgui/nbproject/build-impl.xml b/apps/desktopgui/nbproject/build-impl.xml
new file mode 100644
index 0000000000..f8fea458d1
--- /dev/null
+++ b/apps/desktopgui/nbproject/build-impl.xml
@@ -0,0 +1,629 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must set src.dir
+ Must set test.src.dir
+ Must set build.dir
+ Must set dist.dir
+ Must set build.classes.dir
+ Must set dist.javadoc.dir
+ Must set build.test.classes.dir
+ Must set build.test.results.dir
+ Must set build.classes.excludes
+ Must set dist.jar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ To run this application from the command line without Ant, try:
+
+
+
+
+
+
+ java -cp "${run.classpath.with.dist.jar}" ${main.class}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ To run this application from the command line without Ant, try:
+
+ java -jar "${dist.jar.resolved}"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set debug.class
+
+
+
+
+ Must set fix.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Some tests failed; see details above.
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set test.includes
+
+
+
+ Some tests failed; see details above.
+
+
+
+
+ Must select one file in the IDE or set test.class
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set applet.url
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set applet.url
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/desktopgui/nbproject/genfiles.properties b/apps/desktopgui/nbproject/genfiles.properties
new file mode 100644
index 0000000000..1b326007c7
--- /dev/null
+++ b/apps/desktopgui/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=c4b345cd
+build.xml.script.CRC32=9785bb9a
+build.xml.stylesheet.CRC32=be360661
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=c4b345cd
+nbproject/build-impl.xml.script.CRC32=74d3fda2
+nbproject/build-impl.xml.stylesheet.CRC32=487672f9
diff --git a/apps/desktopgui/nbproject/project.properties b/apps/desktopgui/nbproject/project.properties
new file mode 100644
index 0000000000..b7a05f8ed6
--- /dev/null
+++ b/apps/desktopgui/nbproject/project.properties
@@ -0,0 +1,77 @@
+application.desc=An anonymous communication network.
+application.homepage=http://www.i2p2.de
+application.title=I2P Desktop GUI
+application.vendor=I2P Developers
+build.classes.dir=${build.dir}/classes
+build.classes.excludes=**/*.java,**/*.form
+# This directory is removed when the project is cleaned:
+build.dir=build
+build.generated.dir=${build.dir}/generated
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+debug.classpath=\
+ ${run.classpath}
+debug.test.classpath=\
+ ${run.test.classpath}
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/desktopgui.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+excludes=
+file.reference.appframework.jar=lib/appframework.jar
+file.reference.i2p.jar=../../core/java/build/i2p.jar
+file.reference.router.jar=../../router/java/build/router.jar
+file.reference.swing-worker.jar=lib/swing-worker.jar
+includes=**
+jar.compress=false
+javac.classpath=\
+ ${file.reference.router.jar}:\
+ ${file.reference.appframework.jar}:\
+ ${file.reference.swing-worker.jar}:\
+ ${file.reference.i2p.jar}
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.deprecation=false
+javac.source=1.6
+javac.target=1.6
+javac.test.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}:\
+ ${libs.junit.classpath}:\
+ ${libs.junit_4.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.encoding.used=${javadoc.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+jnlp.codebase.type=local
+jnlp.codebase.url=file:/home/mathias/Documenten/Programmeren/i2p_monotone/repo/i2p.i2p/apps/desktopgui/dist/
+jnlp.enabled=false
+jnlp.offline-allowed=false
+jnlp.signed=false
+main.class=desktopgui.Main
+manifest.file=manifest.mf
+meta.inf.dir=${src.dir}/META-INF
+platform.active=default_platform
+run.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}
+# Space-separated list of JVM arguments used when running the project
+# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
+# or test-sys-prop.name=value to set system properties for unit tests):
+run.jvmargs=
+run.test.classpath=\
+ ${javac.test.classpath}:\
+ ${build.test.classes.dir}
+source.encoding=UTF-8
+src.dir=src
+test.src.dir=test
diff --git a/apps/desktopgui/nbproject/project.xml b/apps/desktopgui/nbproject/project.xml
new file mode 100644
index 0000000000..09409a64cd
--- /dev/null
+++ b/apps/desktopgui/nbproject/project.xml
@@ -0,0 +1,19 @@
+
+
+ org.netbeans.modules.java.j2seproject
+
+
+ desktopgui
+ 1.6.5
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/desktopgui/src/META-INF/services/org.jdesktop.application.Application b/apps/desktopgui/src/META-INF/services/org.jdesktop.application.Application
new file mode 100644
index 0000000000..6cd2ac1fb1
--- /dev/null
+++ b/apps/desktopgui/src/META-INF/services/org.jdesktop.application.Application
@@ -0,0 +1 @@
+desktopgui.Main
\ No newline at end of file
diff --git a/apps/desktopgui/src/desktopgui/Main.java b/apps/desktopgui/src/desktopgui/Main.java
new file mode 100644
index 0000000000..9d9708c8dd
--- /dev/null
+++ b/apps/desktopgui/src/desktopgui/Main.java
@@ -0,0 +1,109 @@
+package desktopgui;
+
+/*
+ * Main.java
+ */
+
+
+
+import gui.Tray;
+import gui.SpeedSelector;
+import java.awt.SystemTray;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+import org.jdesktop.application.Application;
+import org.jdesktop.application.SingleFrameApplication;
+import persistence.PropertyManager;
+
+/**
+ * The main class of the application.
+ */
+public class Main extends SingleFrameApplication {
+
+ /**
+ * At startup create and show the main frame of the application.
+ */
+ @Override protected void startup() {
+ Properties props = PropertyManager.loadProps();
+
+ //First load: present screen with information (to help choose I2P settings)
+ if(props.getProperty(FIRSTLOAD).equals("true")) {
+ props.setProperty(FIRSTLOAD, "false");
+ PropertyManager.saveProps(props);
+ new SpeedSelector(); //Start speed selector GUI
+ }
+
+ if(SystemTray.isSupported()) {
+ tray = new Tray();
+ }
+ else { //Alternative if SystemTray is not supported on the platform
+ }
+ }
+
+ /**
+ * This method is to initialize the specified window by injecting resources.
+ * Windows shown in our application come fully initialized from the GUI
+ * builder, so this additional configuration is not needed.
+ */
+ @Override protected void configureWindow(java.awt.Window root) {
+ }
+
+ /**
+ * A convenient static getter for the application instance.
+ * @return the instance of Main
+ */
+ public static Main getApplication() {
+ return Application.getInstance(Main.class);
+ }
+
+ /**
+ * Main method launching the application.
+ */
+ public static void main(String[] args) {
+ System.setProperty("java.awt.headless", "false"); //Make sure I2P is running in GUI mode for our application
+ try {
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (ClassNotFoundException ex) {
+ Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (InstantiationException ex) {
+ Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (IllegalAccessException ex) {
+ Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (UnsupportedLookAndFeelException ex) {
+ Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ Main main = getApplication();
+ main.launchForeverLoop();
+ main.startup();
+ }
+
+ /**
+ * Avoids the app terminating because no Window is opened anymore.
+ * More info: http://java.sun.com/javase/6/docs/api/java/awt/doc-files/AWTThreadIssues.html#Autoshutdown
+ */
+ public void launchForeverLoop() {
+ Runnable r = new Runnable() {
+ public void run() {
+ try {
+ Object o = new Object();
+ synchronized (o) {
+ o.wait();
+ }
+ } catch (InterruptedException ie) {
+ }
+ }
+ };
+ Thread t = new Thread(r);
+ t.setDaemon(false);
+ t.start();
+ }
+
+ private Tray tray = null;
+ ///Indicates if this is the first time the application loads
+ ///(is only true at the very start of loading the first time!)
+ private static final String FIRSTLOAD = "firstLoad";
+}
diff --git a/apps/desktopgui/src/desktopgui/resources/Main.properties b/apps/desktopgui/src/desktopgui/resources/Main.properties
new file mode 100644
index 0000000000..fb7218ceae
--- /dev/null
+++ b/apps/desktopgui/src/desktopgui/resources/Main.properties
@@ -0,0 +1,11 @@
+# Application global resources
+
+Application.name = desktopgui
+Application.title = I2P Desktop GUI
+Application.version = 0.7.1
+Application.vendor = I2P Developers
+Application.homepage = http://www.i2p2.de
+Application.description = An anonymous communication network.
+Application.vendorId = I2P
+Application.id = desktopgui
+Application.lookAndFeel = system
diff --git a/apps/desktopgui/src/desktopgui/resources/Main_nl_BE.properties b/apps/desktopgui/src/desktopgui/resources/Main_nl_BE.properties
new file mode 100644
index 0000000000..81107aca91
--- /dev/null
+++ b/apps/desktopgui/src/desktopgui/resources/Main_nl_BE.properties
@@ -0,0 +1,11 @@
+# Application global resources
+
+Application.name = desktopgui
+Application.title = I2P Desktop GUI
+Application.version = 0.7.1
+Application.vendor = I2P Ontwikkelaars
+Application.homepage = http://www.i2p2.de
+Application.description = Een anoniem communicatienetwerk.
+Application.vendorId = I2P
+Application.id = desktopgui
+Application.lookAndFeel = system
diff --git a/apps/desktopgui/src/gui/GeneralConfiguration.form b/apps/desktopgui/src/gui/GeneralConfiguration.form
new file mode 100644
index 0000000000..070e201382
--- /dev/null
+++ b/apps/desktopgui/src/gui/GeneralConfiguration.form
@@ -0,0 +1,103 @@
+
+
+
diff --git a/apps/desktopgui/src/gui/GeneralConfiguration.java b/apps/desktopgui/src/gui/GeneralConfiguration.java
new file mode 100644
index 0000000000..b9c7403813
--- /dev/null
+++ b/apps/desktopgui/src/gui/GeneralConfiguration.java
@@ -0,0 +1,106 @@
+/*
+ * GeneralConfiguration.java
+ *
+ * Created on 10 april 2009, 19:04
+ */
+
+package gui;
+
+/**
+ *
+ * @author mathias
+ */
+public class GeneralConfiguration extends javax.swing.JFrame {
+
+ /** Creates new form GeneralConfiguration */
+ public GeneralConfiguration() {
+ initComponents();
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jTabbedPane1 = new javax.swing.JTabbedPane();
+ jPanel1 = new javax.swing.JPanel();
+ jPanel2 = new javax.swing.JPanel();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setName("Form"); // NOI18N
+
+ jTabbedPane1.setName("jTabbedPane1"); // NOI18N
+
+ jPanel1.setName("jPanel1"); // NOI18N
+
+ javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+ jPanel1.setLayout(jPanel1Layout);
+ jPanel1Layout.setHorizontalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 474, Short.MAX_VALUE)
+ );
+ jPanel1Layout.setVerticalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 338, Short.MAX_VALUE)
+ );
+
+ org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(desktopgui.Main.class).getContext().getResourceMap(GeneralConfiguration.class);
+ jTabbedPane1.addTab(resourceMap.getString("jPanel1.TabConstraints.tabTitle"), jPanel1); // NOI18N
+
+ jPanel2.setName("jPanel2"); // NOI18N
+
+ javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
+ jPanel2.setLayout(jPanel2Layout);
+ jPanel2Layout.setHorizontalGroup(
+ jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 474, Short.MAX_VALUE)
+ );
+ jPanel2Layout.setVerticalGroup(
+ jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 338, Short.MAX_VALUE)
+ );
+
+ jTabbedPane1.addTab(resourceMap.getString("jPanel2.TabConstraints.tabTitle"), jPanel2); // NOI18N
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 478, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 369, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
+ );
+
+ pack();
+ }// //GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new GeneralConfiguration().setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JPanel jPanel2;
+ private javax.swing.JTabbedPane jTabbedPane1;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/apps/desktopgui/src/gui/JPopupTrayIcon.java b/apps/desktopgui/src/gui/JPopupTrayIcon.java
new file mode 100644
index 0000000000..83872e4a51
--- /dev/null
+++ b/apps/desktopgui/src/gui/JPopupTrayIcon.java
@@ -0,0 +1,176 @@
+/*
+* Created on Sep 15, 2008 5:51:33 PM
+*/
+
+/*
+ * This class is part of fishfarm project: https://fishfarm.dev.java.net/
+ * It is licensed under the GPL version 2.0 with Classpath Exception.
+ *
+ * Copyright (C) 2008 Michael Bien
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+package gui;
+
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.PopupMenu;
+import java.awt.TrayIcon;
+import java.awt.Window;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JWindow;
+import javax.swing.RootPaneContainer;
+import javax.swing.event.PopupMenuEvent;
+import javax.swing.event.PopupMenuListener;
+
+
+
+/**
+ * JPopupMenu compatible TrayIcon based on Alexander Potochkin's JXTrayIcon
+ * (http://weblogs.java.net/blog/alexfromsun/archive/2008/02/jtrayicon_updat.html)
+ * but uses a JWindow instead of a JDialog to workaround some bugs on linux.
+ *
+ * @author Michael Bien
+ */
+public class JPopupTrayIcon extends TrayIcon {
+
+ private JPopupMenu menu;
+
+ private Window window;
+ private PopupMenuListener popupListener;
+
+ private final static boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().contains("windows");
+
+ public JPopupTrayIcon(Image image) {
+ super(image);
+ init();
+ }
+
+ public JPopupTrayIcon(Image image, String tooltip) {
+ super(image, tooltip);
+ init();
+ }
+
+ public JPopupTrayIcon(Image image, String tooltip, PopupMenu popup) {
+ super(image, tooltip, popup);
+ init();
+ }
+
+ public JPopupTrayIcon(Image image, String tooltip, JPopupMenu popup) {
+ super(image, tooltip);
+ init();
+ setJPopupMenu(popup);
+ }
+
+
+ private final void init() {
+
+
+ popupListener = new PopupMenuListener() {
+
+ @Override
+ public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
+// System.out.println("popupMenuWillBecomeVisible");
+ }
+
+ @Override
+ public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
+// System.out.println("popupMenuWillBecomeInvisible");
+ if(window != null) {
+ window.dispose();
+ window = null;
+ }
+ }
+
+ @Override
+ public void popupMenuCanceled(PopupMenuEvent e) {
+// System.out.println("popupMenuCanceled");
+ if(window != null) {
+ window.dispose();
+ window = null;
+ }
+ }
+ };
+
+ addMouseListener(new MouseAdapter() {
+ @Override
+ public void mousePressed(MouseEvent e) {
+// System.out.println(e.getPoint());
+ showJPopupMenu(e);
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+// System.out.println(e.getPoint());
+ showJPopupMenu(e);
+ }
+ });
+
+ }
+
+ private final void showJPopupMenu(MouseEvent e) {
+ if(e.isPopupTrigger() && menu != null) {
+ if (window == null) {
+
+ if(IS_WINDOWS) {
+ window = new JDialog((Frame)null);
+ ((JDialog)window).setUndecorated(true);
+ }else{
+ window = new JWindow((Frame)null);
+ }
+ window.setAlwaysOnTop(true);
+ Dimension size = menu.getPreferredSize();
+
+ Point centerPoint = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
+ if(e.getY() > centerPoint.getY())
+ window.setLocation(e.getX(), e.getY() - size.height);
+ else
+ window.setLocation(e.getX(), e.getY());
+
+ window.setVisible(true);
+
+ menu.show(((RootPaneContainer)window).getContentPane(), 0, 0);
+
+ // popup works only for focused windows
+ window.toFront();
+
+ }
+ }
+ }
+
+
+ public final JPopupMenu getJPopupMenu() {
+ return menu;
+ }
+
+ public final void setJPopupMenu(JPopupMenu menu) {
+ if (this.menu != null) {
+ this.menu.removePopupMenuListener(popupListener);
+ }
+ this.menu = menu;
+ menu.addPopupMenuListener(popupListener);
+ }
+
+}
diff --git a/apps/desktopgui/src/gui/LogViewer.form b/apps/desktopgui/src/gui/LogViewer.form
new file mode 100644
index 0000000000..b53b410bac
--- /dev/null
+++ b/apps/desktopgui/src/gui/LogViewer.form
@@ -0,0 +1,101 @@
+
+
+
diff --git a/apps/desktopgui/src/gui/LogViewer.java b/apps/desktopgui/src/gui/LogViewer.java
new file mode 100644
index 0000000000..2dad70c1fc
--- /dev/null
+++ b/apps/desktopgui/src/gui/LogViewer.java
@@ -0,0 +1,163 @@
+/*
+ * LogViewer.java
+ *
+ * Created on 10 april 2009, 19:17
+ */
+
+package gui;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.WindowConstants;
+
+/**
+ *
+ * @author mathias
+ */
+public class LogViewer extends javax.swing.JFrame {
+
+ /** Creates new form LogViewer */
+ public LogViewer() {
+ initComponents();
+ readLogText();
+ this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+ this.setVisible(true);
+ }
+
+ private void readLogText() {
+ Thread t = new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ String s = "";
+ File f = new File(LOGLOCATION);
+ if(f.exists()) {
+ try {
+ BufferedReader br = new BufferedReader(new FileReader(f));
+ while(true) {
+ String line = br.readLine();
+ if(line != null)
+ s += JTEXTNEWLINE + line;
+ else
+ break;
+ }
+ }
+ catch(Exception e) {
+ s = "An error has occurred while loading the logfiles:" + JTEXTNEWLINE + e.getMessage();
+ }
+ }
+ logText.setText(s);
+ }
+
+ });
+ t.start();
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ textScroll = new javax.swing.JScrollPane();
+ logText = new javax.swing.JTextArea();
+ explanationText = new javax.swing.JLabel();
+ refreshButton = new javax.swing.JButton();
+ clearButton = new javax.swing.JButton();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setName("Form"); // NOI18N
+
+ textScroll.setName("textScroll"); // NOI18N
+
+ logText.setColumns(20);
+ logText.setRows(5);
+ logText.setName("logText"); // NOI18N
+ textScroll.setViewportView(logText);
+
+ org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(desktopgui.Main.class).getContext().getResourceMap(LogViewer.class);
+ explanationText.setText(resourceMap.getString("explanationText.text")); // NOI18N
+ explanationText.setName("explanationText"); // NOI18N
+
+ refreshButton.setText(resourceMap.getString("refreshButton.text")); // NOI18N
+ refreshButton.setName("refreshButton"); // NOI18N
+ refreshButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ refreshButtonActionPerformed(evt);
+ }
+ });
+
+ clearButton.setText(resourceMap.getString("clearButton.text")); // NOI18N
+ clearButton.setName("clearButton"); // NOI18N
+ clearButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ clearButtonActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addGap(12, 12, 12)
+ .addComponent(explanationText, javax.swing.GroupLayout.PREFERRED_SIZE, 561, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
+ .addComponent(textScroll, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 722, Short.MAX_VALUE)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(refreshButton)
+ .addGap(18, 18, 18)
+ .addComponent(clearButton)
+ .addContainerGap(587, Short.MAX_VALUE))
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(explanationText, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(refreshButton)
+ .addComponent(clearButton))
+ .addGap(14, 14, 14)
+ .addComponent(textScroll, javax.swing.GroupLayout.DEFAULT_SIZE, 330, Short.MAX_VALUE))
+ );
+
+ pack();
+ }// //GEN-END:initComponents
+
+private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearButtonActionPerformed
+ File f = new File(LOGLOCATION);
+ f.delete();
+ try {
+ f.createNewFile();//GEN-LAST:event_clearButtonActionPerformed
+ } catch (IOException ex) {
+ Logger.getLogger(LogViewer.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ readLogText();
+}
+
+private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshButtonActionPerformed
+ readLogText();
+}//GEN-LAST:event_refreshButtonActionPerformed
+
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton clearButton;
+ private javax.swing.JLabel explanationText;
+ private javax.swing.JTextArea logText;
+ private javax.swing.JButton refreshButton;
+ private javax.swing.JScrollPane textScroll;
+ // End of variables declaration//GEN-END:variables
+
+ private static final String LOGLOCATION = "wrapper.log";
+ private static final String JTEXTNEWLINE = "\n";
+}
diff --git a/apps/desktopgui/src/gui/SpeedSelector.form b/apps/desktopgui/src/gui/SpeedSelector.form
new file mode 100644
index 0000000000..79d25ae965
--- /dev/null
+++ b/apps/desktopgui/src/gui/SpeedSelector.form
@@ -0,0 +1,178 @@
+
+
+
diff --git a/apps/desktopgui/src/gui/SpeedSelector.java b/apps/desktopgui/src/gui/SpeedSelector.java
new file mode 100644
index 0000000000..bce18621f2
--- /dev/null
+++ b/apps/desktopgui/src/gui/SpeedSelector.java
@@ -0,0 +1,195 @@
+/*
+ * ProfileSelector.java
+ *
+ * Created on 3 april 2009, 13:57
+ */
+
+package gui;
+
+import java.awt.Dimension;
+import java.awt.Point;
+import java.util.Properties;
+import javax.swing.JComboBox;
+import javax.swing.JTextField;
+import persistence.PropertyManager;
+import util.IntegerVerifier;
+
+/**
+ *
+ * @author mathias
+ */
+public class SpeedSelector extends javax.swing.JFrame {
+
+ /** Creates new form ProfileSelector */
+ public SpeedSelector() {
+ this.props = PropertyManager.getProps();
+ initComponents();
+ initComponentsCustom();
+ initSpeeds(props);
+ this.setVisible(true);
+ this.setLocationRelativeTo(null);
+ this.requestFocus();
+ }
+
+ public SpeedSelector(Point point) {
+ this();
+ this.setLocation(point);
+ }
+
+ public void initComponentsCustom() {
+ ((JTextField)uploadChoice.getEditor().getEditorComponent()).setInputVerifier(new IntegerVerifier());
+ ((JTextField)downloadChoice.getEditor().getEditorComponent()).setInputVerifier(new IntegerVerifier());
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ nextButton = new javax.swing.JButton();
+ uploadLabel = new javax.swing.JLabel();
+ downloadLabel = new javax.swing.JLabel();
+ uploadChoice = new javax.swing.JComboBox();
+ downloadChoice = new javax.swing.JComboBox();
+ speedExplanation = new javax.swing.JLabel();
+ uploadkbps = new javax.swing.JComboBox();
+ downloadkbps = new javax.swing.JComboBox();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(desktopgui.Main.class).getContext().getResourceMap(SpeedSelector.class);
+ setTitle(resourceMap.getString("Form.title")); // NOI18N
+ setMinimumSize(new java.awt.Dimension(610, 330));
+ setName("Form"); // NOI18N
+ setResizable(false);
+ getContentPane().setLayout(null);
+
+ nextButton.setText(resourceMap.getString("nextButton.text")); // NOI18N
+ nextButton.setMaximumSize(new java.awt.Dimension(72, 29));
+ nextButton.setMinimumSize(new java.awt.Dimension(72, 29));
+ nextButton.setName("nextButton"); // NOI18N
+ nextButton.addMouseListener(new java.awt.event.MouseAdapter() {
+ public void mouseClicked(java.awt.event.MouseEvent evt) {
+ nextButtonMouseClicked(evt);
+ }
+ });
+ getContentPane().add(nextButton);
+ nextButton.setBounds(440, 250, 90, 29);
+
+ uploadLabel.setText(resourceMap.getString("uploadLabel.text")); // NOI18N
+ uploadLabel.setName("uploadLabel"); // NOI18N
+ getContentPane().add(uploadLabel);
+ uploadLabel.setBounds(20, 60, 246, 30);
+
+ downloadLabel.setText(resourceMap.getString("downloadLabel.text")); // NOI18N
+ downloadLabel.setName("downloadLabel"); // NOI18N
+ getContentPane().add(downloadLabel);
+ downloadLabel.setBounds(20, 110, 263, 30);
+
+ uploadChoice.setEditable(true);
+ uploadChoice.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "100", "200", "500", "1000", "2000", "4000", "8000", "10000", "20000", "50000", "100000" }));
+ uploadChoice.setSelectedIndex(3);
+ uploadChoice.setName("uploadChoice"); // NOI18N
+ getContentPane().add(uploadChoice);
+ uploadChoice.setBounds(300, 60, 154, 27);
+
+ downloadChoice.setEditable(true);
+ downloadChoice.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "100", "200", "500", "1000", "2000", "4000", "8000", "10000", "20000", "50000", "100000" }));
+ downloadChoice.setSelectedIndex(3);
+ downloadChoice.setName("downloadChoice"); // NOI18N
+ getContentPane().add(downloadChoice);
+ downloadChoice.setBounds(300, 110, 154, 27);
+
+ speedExplanation.setText(resourceMap.getString("speedExplanation.text")); // NOI18N
+ speedExplanation.setName("speedExplanation"); // NOI18N
+ getContentPane().add(speedExplanation);
+ speedExplanation.setBounds(20, 160, 570, 60);
+
+ uploadkbps.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "kbps", "kBps" }));
+ uploadkbps.setName("uploadKbit"); // NOI18N
+ uploadkbps.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ uploadkbpsActionPerformed(evt);
+ }
+ });
+ getContentPane().add(uploadkbps);
+ uploadkbps.setBounds(470, 60, 68, 27);
+
+ downloadkbps.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "kbps", "kBps" }));
+ downloadkbps.setName("downloadKbit"); // NOI18N
+ downloadkbps.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ downloadkbpsActionPerformed(evt);
+ }
+ });
+ getContentPane().add(downloadkbps);
+ downloadkbps.setBounds(470, 110, 68, 27);
+
+ pack();
+ }// //GEN-END:initComponents
+
+private void nextButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_nextButtonMouseClicked
+ if(uploadkbps.getSelectedIndex() == KILOBIT)
+ props.setProperty(SpeedSelectorConstants.MAXUPLOADCAPABLE, uploadChoice.getSelectedItem().toString());
+ else
+ props.setProperty(SpeedSelectorConstants.MAXUPLOADCAPABLE, "" + Integer.parseInt(uploadChoice.getSelectedItem().toString())*8);
+ if(downloadkbps.getSelectedIndex() == KILOBIT)
+ props.setProperty(SpeedSelectorConstants.MAXDOWNLOADCAPABLE, downloadChoice.getSelectedItem().toString());
+ else
+ props.setProperty(SpeedSelectorConstants.MAXDOWNLOADCAPABLE, "" + Integer.parseInt(downloadChoice.getSelectedItem().toString())*8);
+ PropertyManager.saveProps(props);
+ new SpeedSelector2(this.getLocationOnScreen());
+ this.dispose();
+}//GEN-LAST:event_nextButtonMouseClicked
+
+private void uploadkbpsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_uploadkbpsActionPerformed
+ kbpsSwitchPerformed(uploadkbps, uploadChoice);
+}//GEN-LAST:event_uploadkbpsActionPerformed
+
+private void downloadkbpsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_downloadkbpsActionPerformed
+ kbpsSwitchPerformed(downloadkbps, downloadChoice);
+}//GEN-LAST:event_downloadkbpsActionPerformed
+
+private void kbpsSwitchPerformed(JComboBox kbps, JComboBox speed) {
+ int index = kbps.getSelectedIndex();
+ int previous = Integer.parseInt(speed.getSelectedItem().toString());
+ if(index == KILOBIT) {
+ speed.setSelectedItem("" + previous*8);
+ }
+ else {
+ speed.setSelectedItem("" + previous/8);
+ }
+}
+
+private void initSpeeds(Properties props) {
+ String up = props.getProperty(SpeedSelectorConstants.MAXUPLOADCAPABLE);
+ String down = props.getProperty(SpeedSelectorConstants.MAXDOWNLOADCAPABLE);
+
+ if(up == null)
+ props.setProperty(SpeedSelectorConstants.MAXUPLOADCAPABLE, "1000");
+ if(down == null)
+ props.setProperty(SpeedSelectorConstants.MAXDOWNLOADCAPABLE, "1000");
+
+ uploadChoice.setSelectedItem(props.getProperty(SpeedSelectorConstants.MAXUPLOADCAPABLE));
+ downloadChoice.setSelectedItem(props.getProperty(SpeedSelectorConstants.MAXDOWNLOADCAPABLE));
+}
+
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JComboBox downloadChoice;
+ private javax.swing.JLabel downloadLabel;
+ private javax.swing.JComboBox downloadkbps;
+ private javax.swing.JButton nextButton;
+ private javax.swing.JLabel speedExplanation;
+ private javax.swing.JComboBox uploadChoice;
+ private javax.swing.JLabel uploadLabel;
+ private javax.swing.JComboBox uploadkbps;
+ // End of variables declaration//GEN-END:variables
+
+ Properties props;
+ private static final int KILOBIT = 0;
+ private static final int KILOBYTE = 1;
+}
diff --git a/apps/desktopgui/src/gui/SpeedSelector2.form b/apps/desktopgui/src/gui/SpeedSelector2.form
new file mode 100644
index 0000000000..5c305de19b
--- /dev/null
+++ b/apps/desktopgui/src/gui/SpeedSelector2.form
@@ -0,0 +1,117 @@
+
+
+
diff --git a/apps/desktopgui/src/gui/SpeedSelector2.java b/apps/desktopgui/src/gui/SpeedSelector2.java
new file mode 100644
index 0000000000..1177b57258
--- /dev/null
+++ b/apps/desktopgui/src/gui/SpeedSelector2.java
@@ -0,0 +1,160 @@
+/*
+ * ProfileSelector2.java
+ *
+ * Created on 3 april 2009, 14:36
+ */
+
+package gui;
+
+import java.awt.Dimension;
+import java.awt.Point;
+import java.util.Enumeration;
+import java.util.Properties;
+import javax.swing.AbstractButton;
+import persistence.PropertyManager;
+
+/**
+ *
+ * @author mathias
+ */
+public class SpeedSelector2 extends javax.swing.JFrame {
+ Properties props;
+
+ /** Creates new form ProfileSelector2 */
+ public SpeedSelector2(Point point) {
+ this.props = PropertyManager.getProps();
+ initComponents();
+ this.setLocation(point);
+ loadButtonSelection();
+ this.setVisible(true);
+ this.requestFocus();
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ buttonGroup1 = new javax.swing.ButtonGroup();
+ nextButton = new javax.swing.JButton();
+ returnButton = new javax.swing.JButton();
+ questionLabel = new javax.swing.JLabel();
+ browseButton = new javax.swing.JRadioButton();
+ downloadButton = new javax.swing.JRadioButton();
+ jLabel1 = new javax.swing.JLabel();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(desktopgui.Main.class).getContext().getResourceMap(SpeedSelector2.class);
+ setTitle(resourceMap.getString("Form.title")); // NOI18N
+ setMinimumSize(new java.awt.Dimension(610, 330));
+ setName("Form"); // NOI18N
+ setResizable(false);
+ getContentPane().setLayout(null);
+
+ nextButton.setText(resourceMap.getString("nextButton.text")); // NOI18N
+ nextButton.setName("nextButton"); // NOI18N
+ nextButton.addMouseListener(new java.awt.event.MouseAdapter() {
+ public void mouseClicked(java.awt.event.MouseEvent evt) {
+ nextButtonMouseClicked(evt);
+ }
+ });
+ getContentPane().add(nextButton);
+ nextButton.setBounds(440, 250, 90, 29);
+
+ returnButton.setText(resourceMap.getString("returnButton.text")); // NOI18N
+ returnButton.setName("returnButton"); // NOI18N
+ returnButton.addMouseListener(new java.awt.event.MouseAdapter() {
+ public void mouseClicked(java.awt.event.MouseEvent evt) {
+ returnButtonMouseClicked(evt);
+ }
+ });
+ getContentPane().add(returnButton);
+ returnButton.setBounds(336, 250, 90, 29);
+
+ questionLabel.setText(resourceMap.getString("questionLabel.text")); // NOI18N
+ questionLabel.setName("questionLabel"); // NOI18N
+ getContentPane().add(questionLabel);
+ questionLabel.setBounds(30, 40, 265, 17);
+
+ buttonGroup1.add(browseButton);
+ browseButton.setText(resourceMap.getString("browseButton.text")); // NOI18N
+ browseButton.setActionCommand(resourceMap.getString("browseButton.actionCommand")); // NOI18N
+ browseButton.setName("browseButton"); // NOI18N
+ getContentPane().add(browseButton);
+ browseButton.setBounds(40, 120, 520, 40);
+
+ buttonGroup1.add(downloadButton);
+ downloadButton.setText(resourceMap.getString("downloadButton.text")); // NOI18N
+ downloadButton.setActionCommand(resourceMap.getString("downloadButton.actionCommand")); // NOI18N
+ downloadButton.setName("downloadButton"); // NOI18N
+ getContentPane().add(downloadButton);
+ downloadButton.setBounds(40, 70, 499, 40);
+
+ jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N
+ jLabel1.setName("jLabel1"); // NOI18N
+ getContentPane().add(jLabel1);
+ jLabel1.setBounds(30, 170, 530, 70);
+
+ pack();
+ }// //GEN-END:initComponents
+
+private void returnButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_returnButtonMouseClicked
+ saveButtonSelection();
+ PropertyManager.saveProps(props);
+ new SpeedSelector(this.getLocationOnScreen());
+ this.dispose();
+}//GEN-LAST:event_returnButtonMouseClicked
+
+private void nextButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_nextButtonMouseClicked
+ saveButtonSelection();
+ PropertyManager.saveProps(props);
+ new SpeedSelector3(this.getLocationOnScreen(), this.getSize());
+ this.dispose();
+}//GEN-LAST:event_nextButtonMouseClicked
+
+private void loadButtonSelection() {
+
+ Enumeration elements = buttonGroup1.getElements();
+ while(elements.hasMoreElements()) {
+ AbstractButton button = elements.nextElement();
+ if(button == null)
+ continue;
+ if(props.getProperty(SpeedSelectorConstants.USERTYPE) == null)
+ break;
+ String type = button.getActionCommand();
+ if(type.equals(props.getProperty(SpeedSelectorConstants.USERTYPE))) {
+ button.setSelected(true);
+ break;
+ }
+ }
+}
+
+private void saveButtonSelection() {
+ Enumeration elements = buttonGroup1.getElements();
+ while(elements.hasMoreElements()) {
+ AbstractButton button = elements.nextElement();
+ if(button == null)
+ continue;
+ if(button.isSelected()) {
+ String type = button.getActionCommand();
+ props.setProperty(SpeedSelectorConstants.USERTYPE, type);
+ break;
+ }
+ }
+}
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JRadioButton browseButton;
+ private javax.swing.ButtonGroup buttonGroup1;
+ private javax.swing.JRadioButton downloadButton;
+ private javax.swing.JLabel jLabel1;
+ private javax.swing.JButton nextButton;
+ private javax.swing.JLabel questionLabel;
+ private javax.swing.JButton returnButton;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/apps/desktopgui/src/gui/SpeedSelector3.form b/apps/desktopgui/src/gui/SpeedSelector3.form
new file mode 100644
index 0000000000..9c6ef533aa
--- /dev/null
+++ b/apps/desktopgui/src/gui/SpeedSelector3.form
@@ -0,0 +1,337 @@
+
+
+
diff --git a/apps/desktopgui/src/gui/SpeedSelector3.java b/apps/desktopgui/src/gui/SpeedSelector3.java
new file mode 100644
index 0000000000..1f523befda
--- /dev/null
+++ b/apps/desktopgui/src/gui/SpeedSelector3.java
@@ -0,0 +1,439 @@
+/*
+ * ProfileSelector3.java
+ *
+ * Created on 3 april 2009, 15:17
+ */
+
+package gui;
+
+import java.awt.Dimension;
+import java.awt.Point;
+import java.util.Properties;
+import javax.swing.JComboBox;
+import javax.swing.JTextField;
+import persistence.PropertyManager;
+import router.configuration.SpeedHandler;
+import router.configuration.SpeedHelper;
+
+/**
+ *
+ * @author mathias
+ */
+public class SpeedSelector3 extends javax.swing.JFrame {
+ Properties props;
+
+ /** Creates new form ProfileSelector3 */
+ public SpeedSelector3(Point point, Dimension dimension) {
+ this.props = PropertyManager.getProps();
+ initComponents();
+ this.setLocation(point);
+ this.setSize(dimension);
+ initSpeeds();
+ initUsage();
+ this.setVisible(true);
+ this.requestFocus();
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ finishButton = new javax.swing.JButton();
+ previousButton = new javax.swing.JButton();
+ settingsInfo = new javax.swing.JLabel();
+ uploadLabel = new javax.swing.JLabel();
+ downloadLabel = new javax.swing.JLabel();
+ uploadBurstLabel = new javax.swing.JLabel();
+ downloadBurstLabel = new javax.swing.JLabel();
+ uploadUsageLabel = new javax.swing.JLabel();
+ downloadUsageLabel = new javax.swing.JLabel();
+ uploadField = new javax.swing.JTextField();
+ uploadBurstField = new javax.swing.JTextField();
+ downloadField = new javax.swing.JTextField();
+ downloadBurstField = new javax.swing.JTextField();
+ kbpsBurstDownload = new javax.swing.JComboBox();
+ kbpsUpload = new javax.swing.JComboBox();
+ kbpsBurstUpload = new javax.swing.JComboBox();
+ kbpsDownload = new javax.swing.JComboBox();
+ uploadGB = new javax.swing.JLabel();
+ uploadMonth = new javax.swing.JTextField();
+ downloadMonth = new javax.swing.JTextField();
+ downloadGB = new javax.swing.JLabel();
+ explanation = new javax.swing.JLabel();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(desktopgui.Main.class).getContext().getResourceMap(SpeedSelector3.class);
+ setTitle(resourceMap.getString("Form.title")); // NOI18N
+ setMinimumSize(new java.awt.Dimension(670, 330));
+ setName("Form"); // NOI18N
+ setResizable(false);
+ getContentPane().setLayout(null);
+
+ finishButton.setText(resourceMap.getString("finishButton.text")); // NOI18N
+ finishButton.setName("finishButton"); // NOI18N
+ finishButton.addMouseListener(new java.awt.event.MouseAdapter() {
+ public void mouseClicked(java.awt.event.MouseEvent evt) {
+ finishButtonMouseClicked(evt);
+ }
+ });
+ getContentPane().add(finishButton);
+ finishButton.setBounds(440, 250, 90, 29);
+
+ previousButton.setText(resourceMap.getString("previousButton.text")); // NOI18N
+ previousButton.setName("previousButton"); // NOI18N
+ previousButton.addMouseListener(new java.awt.event.MouseAdapter() {
+ public void mouseClicked(java.awt.event.MouseEvent evt) {
+ previousButtonMouseClicked(evt);
+ }
+ });
+ getContentPane().add(previousButton);
+ previousButton.setBounds(336, 250, 90, 29);
+
+ settingsInfo.setText(resourceMap.getString("settingsInfo.text")); // NOI18N
+ settingsInfo.setName("settingsInfo"); // NOI18N
+ getContentPane().add(settingsInfo);
+ settingsInfo.setBounds(20, 30, 532, 17);
+
+ uploadLabel.setText(resourceMap.getString("uploadLabel.text")); // NOI18N
+ uploadLabel.setName("uploadLabel"); // NOI18N
+ getContentPane().add(uploadLabel);
+ uploadLabel.setBounds(20, 70, 140, 30);
+
+ downloadLabel.setText(resourceMap.getString("downloadLabel.text")); // NOI18N
+ downloadLabel.setName("downloadLabel"); // NOI18N
+ getContentPane().add(downloadLabel);
+ downloadLabel.setBounds(340, 70, 160, 30);
+
+ uploadBurstLabel.setText(resourceMap.getString("uploadBurstLabel.text")); // NOI18N
+ uploadBurstLabel.setName("uploadBurstLabel"); // NOI18N
+ getContentPane().add(uploadBurstLabel);
+ uploadBurstLabel.setBounds(20, 110, 140, 30);
+
+ downloadBurstLabel.setText(resourceMap.getString("downloadBurstLabel.text")); // NOI18N
+ downloadBurstLabel.setName("downloadBurstLabel"); // NOI18N
+ getContentPane().add(downloadBurstLabel);
+ downloadBurstLabel.setBounds(340, 110, 160, 30);
+
+ uploadUsageLabel.setText(resourceMap.getString("uploadUsageLabel.text")); // NOI18N
+ uploadUsageLabel.setName("uploadUsageLabel"); // NOI18N
+ getContentPane().add(uploadUsageLabel);
+ uploadUsageLabel.setBounds(20, 150, 19, 30);
+
+ downloadUsageLabel.setText(resourceMap.getString("downloadUsageLabel.text")); // NOI18N
+ downloadUsageLabel.setName("downloadUsageLabel"); // NOI18N
+ getContentPane().add(downloadUsageLabel);
+ downloadUsageLabel.setBounds(340, 150, 19, 30);
+
+ uploadField.setText(resourceMap.getString("uploadField.text")); // NOI18N
+ uploadField.setMinimumSize(new java.awt.Dimension(77, 27));
+ uploadField.setName("uploadField"); // NOI18N
+ uploadField.addKeyListener(new java.awt.event.KeyAdapter() {
+ public void keyReleased(java.awt.event.KeyEvent evt) {
+ speedFieldKeyReleased(evt);
+ }
+ });
+ getContentPane().add(uploadField);
+ uploadField.setBounds(160, 70, 77, 27);
+
+ uploadBurstField.setText(resourceMap.getString("uploadBurstField.text")); // NOI18N
+ uploadBurstField.setMinimumSize(new java.awt.Dimension(77, 27));
+ uploadBurstField.setName("uploadBurstField"); // NOI18N
+ getContentPane().add(uploadBurstField);
+ uploadBurstField.setBounds(160, 110, 77, 27);
+
+ downloadField.setText(resourceMap.getString("downloadField.text")); // NOI18N
+ downloadField.setMinimumSize(new java.awt.Dimension(77, 27));
+ downloadField.setName("downloadField"); // NOI18N
+ downloadField.addKeyListener(new java.awt.event.KeyAdapter() {
+ public void keyReleased(java.awt.event.KeyEvent evt) {
+ speedFieldKeyReleased(evt);
+ }
+ });
+ getContentPane().add(downloadField);
+ downloadField.setBounds(500, 70, 77, 27);
+
+ downloadBurstField.setText(resourceMap.getString("downloadBurstField.text")); // NOI18N
+ downloadBurstField.setMinimumSize(new java.awt.Dimension(77, 27));
+ downloadBurstField.setName("downloadBurstField"); // NOI18N
+ getContentPane().add(downloadBurstField);
+ downloadBurstField.setBounds(500, 110, 77, 27);
+
+ kbpsBurstDownload.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "kbps", "kBps" }));
+ kbpsBurstDownload.setName("kbpsBurstDownload"); // NOI18N
+ kbpsBurstDownload.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ kbpsBurstDownloadActionPerformed(evt);
+ }
+ });
+ getContentPane().add(kbpsBurstDownload);
+ kbpsBurstDownload.setBounds(580, 110, 68, 27);
+
+ kbpsUpload.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "kbps", "kBps" }));
+ kbpsUpload.setName("kbpsUpload"); // NOI18N
+ kbpsUpload.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ kbpsUploadActionPerformed(evt);
+ }
+ });
+ getContentPane().add(kbpsUpload);
+ kbpsUpload.setBounds(240, 70, 68, 27);
+
+ kbpsBurstUpload.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "kbps", "kBps" }));
+ kbpsBurstUpload.setName("kbpsBurstUpload"); // NOI18N
+ kbpsBurstUpload.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ kbpsBurstUploadActionPerformed(evt);
+ }
+ });
+ getContentPane().add(kbpsBurstUpload);
+ kbpsBurstUpload.setBounds(240, 110, 68, 27);
+
+ kbpsDownload.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "kbps", "kBps" }));
+ kbpsDownload.setName("kbpsDownload"); // NOI18N
+ kbpsDownload.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ kbpsDownloadActionPerformed(evt);
+ }
+ });
+ getContentPane().add(kbpsDownload);
+ kbpsDownload.setBounds(580, 70, 68, 27);
+
+ uploadGB.setText(resourceMap.getString("uploadUsageLabel.text")); // NOI18N
+ uploadGB.setName("uploadUsageLabel"); // NOI18N
+ getContentPane().add(uploadGB);
+ uploadGB.setBounds(240, 150, 45, 30);
+
+ uploadMonth.setText(resourceMap.getString("uploadMonth.text")); // NOI18N
+ uploadMonth.setName("uploadMonth"); // NOI18N
+ uploadMonth.addKeyListener(new java.awt.event.KeyAdapter() {
+ public void keyReleased(java.awt.event.KeyEvent evt) {
+ monthKeyReleased(evt);
+ }
+ });
+ getContentPane().add(uploadMonth);
+ uploadMonth.setBounds(160, 150, 77, 27);
+
+ downloadMonth.setText(resourceMap.getString("downloadMonth.text")); // NOI18N
+ downloadMonth.setName("downloadMonth"); // NOI18N
+ downloadMonth.addKeyListener(new java.awt.event.KeyAdapter() {
+ public void keyReleased(java.awt.event.KeyEvent evt) {
+ monthKeyReleased(evt);
+ }
+ });
+ getContentPane().add(downloadMonth);
+ downloadMonth.setBounds(500, 150, 77, 27);
+
+ downloadGB.setText(resourceMap.getString("downloadUsageLabel.text")); // NOI18N
+ downloadGB.setName("downloadUsageLabel"); // NOI18N
+ getContentPane().add(downloadGB);
+ downloadGB.setBounds(580, 150, 19, 30);
+
+ explanation.setText(resourceMap.getString("explanation.text")); // NOI18N
+ explanation.setName("explanation"); // NOI18N
+ getContentPane().add(explanation);
+ explanation.setBounds(20, 180, 600, 70);
+
+ pack();
+ }// //GEN-END:initComponents
+
+private void previousButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_previousButtonMouseClicked
+ saveSpeeds();
+ PropertyManager.saveProps(props);
+ new SpeedSelector2(this.getLocationOnScreen());
+ this.dispose();
+}//GEN-LAST:event_previousButtonMouseClicked
+
+private void finishButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_finishButtonMouseClicked
+ saveSpeeds();
+ PropertyManager.saveProps(props);
+
+ int maxDownload = Integer.parseInt(props.getProperty(SpeedSelectorConstants.MAXDOWNLOAD));
+ int maxUpload = Integer.parseInt(props.getProperty(SpeedSelectorConstants.MAXUPLOAD));
+ int maxUploadBurst = Integer.parseInt(props.getProperty(SpeedSelectorConstants.MAXUPLOADBURST));
+ int maxDownloadBurst = Integer.parseInt(props.getProperty(SpeedSelectorConstants.MAXDOWNLOADBURST));
+
+ //Working in kB, not kb!
+ SpeedHandler.setInboundBandwidth(maxDownload/8);
+ SpeedHandler.setOutboundBandwidth(maxUpload/8);
+ SpeedHandler.setInboundBurstBandwidth(maxDownloadBurst/8);
+ SpeedHandler.setOutboundBurstBandwidth(maxUploadBurst/8);
+
+ this.dispose();
+}//GEN-LAST:event_finishButtonMouseClicked
+
+private void speedFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_speedFieldKeyReleased
+ try {
+ String upload = "";
+ if(kbpsUpload.getSelectedIndex() == KILOBIT)
+ upload = uploadField.getText();
+ else
+ upload = "" + Integer.parseInt(uploadField.getText())*8;
+ String download = "";
+ if(kbpsDownload.getSelectedIndex() == KILOBIT)
+ download = downloadField.getText();
+ else
+ download = "" + Integer.parseInt(downloadField.getText())*8;
+ initUsage(upload, download);
+ }
+ catch(NumberFormatException e) {
+ return;
+ }
+}//GEN-LAST:event_speedFieldKeyReleased
+
+private void kbpsUploadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_kbpsUploadActionPerformed
+ kbpsSwitchPerformed(kbpsUpload, uploadField);
+}//GEN-LAST:event_kbpsUploadActionPerformed
+
+private void kbpsBurstUploadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_kbpsBurstUploadActionPerformed
+ kbpsSwitchPerformed(kbpsBurstUpload, uploadBurstField);
+}//GEN-LAST:event_kbpsBurstUploadActionPerformed
+
+private void kbpsDownloadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_kbpsDownloadActionPerformed
+ kbpsSwitchPerformed(kbpsDownload, downloadField);
+}//GEN-LAST:event_kbpsDownloadActionPerformed
+
+private void kbpsBurstDownloadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_kbpsBurstDownloadActionPerformed
+ kbpsSwitchPerformed(kbpsBurstDownload, downloadBurstField);
+}//GEN-LAST:event_kbpsBurstDownloadActionPerformed
+
+private void monthKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_monthKeyReleased
+ try {
+ int uploadMonthValue = Integer.parseInt(uploadMonth.getText());
+ int downloadMonthValue = Integer.parseInt(downloadMonth.getText());
+
+ String upload = "";
+ String burstUpload = "";
+ String download = "";
+ String burstDownload = "";
+
+ if(kbpsUpload.getSelectedIndex() == KILOBIT)
+ upload = "" + SpeedHelper.calculateSpeed(uploadMonthValue)*8; //kbit
+ else
+ upload = "" + SpeedHelper.calculateSpeed(uploadMonthValue); //kbyte
+
+ if(kbpsBurstUpload.getSelectedIndex() == KILOBIT)
+ burstUpload = "" + SpeedHelper.calculateSpeed(uploadMonthValue)*8; //kbit
+ else
+ burstUpload = "" + SpeedHelper.calculateSpeed(uploadMonthValue); //kbyte
+
+ if(kbpsDownload.getSelectedIndex() == KILOBIT)
+ download = "" + SpeedHelper.calculateSpeed(downloadMonthValue)*8; //kbit
+ else
+ download = "" + SpeedHelper.calculateSpeed(downloadMonthValue); //kbyte
+
+ if(kbpsBurstDownload.getSelectedIndex() == KILOBIT)
+ burstDownload = "" + SpeedHelper.calculateSpeed(downloadMonthValue)*8; //kbit
+ else
+ burstDownload = "" + SpeedHelper.calculateSpeed(downloadMonthValue); //kbyte
+
+ initSpeeds(upload, burstUpload, download, burstDownload);
+ }
+ catch(NumberFormatException e) {
+ e.printStackTrace();
+ return;
+ }
+}//GEN-LAST:event_monthKeyReleased
+
+private void kbpsSwitchPerformed(JComboBox kbps, JTextField speed) {
+ int index = kbps.getSelectedIndex();
+ int previous = Integer.parseInt(speed.getText());
+ if(index == KILOBIT) {
+ speed.setText("" + previous*8);
+ }
+ else {
+ speed.setText("" + previous/8);
+ }
+}
+
+ protected void initSpeeds() {
+ String up = "" + SpeedHelper.calculateSpeed(
+ props.getProperty(SpeedSelectorConstants.MAXUPLOADCAPABLE), props.getProperty(SpeedSelectorConstants.USERTYPE));
+ String upBurst = "" + SpeedHelper.calculateSpeed(
+ props.getProperty(SpeedSelectorConstants.MAXUPLOADCAPABLE), props.getProperty(SpeedSelectorConstants.USERTYPE));
+ String down = "" + SpeedHelper.calculateSpeed(
+ props.getProperty(SpeedSelectorConstants.MAXDOWNLOADCAPABLE), props.getProperty(SpeedSelectorConstants.USERTYPE));
+ String downBurst = "" + SpeedHelper.calculateSpeed(
+ props.getProperty(SpeedSelectorConstants.MAXDOWNLOADCAPABLE), props.getProperty(SpeedSelectorConstants.USERTYPE));
+ String userType = props.getProperty(SpeedSelectorConstants.USERTYPE);
+
+ initSpeeds(up, upBurst, down, downBurst);
+ }
+
+ protected void initSpeeds(String up, String upBurst, String down, String downBurst) {
+ uploadField.setText(up);
+ uploadBurstField.setText(upBurst);
+ downloadField.setText(down);
+ downloadBurstField.setText(downBurst);
+ }
+
+ protected void saveSpeeds() {
+ if(kbpsUpload.getSelectedIndex() == KILOBIT)
+ props.setProperty(SpeedSelectorConstants.MAXUPLOAD, uploadField.getText());
+ else
+ props.setProperty(SpeedSelectorConstants.MAXUPLOAD, "" + Integer.parseInt(uploadField.getText())*8);
+ if(kbpsBurstUpload.getSelectedIndex() == KILOBIT)
+ props.setProperty(SpeedSelectorConstants.MAXUPLOADBURST, uploadBurstField.getText());
+ else
+ props.setProperty(SpeedSelectorConstants.MAXUPLOADBURST, "" + Integer.parseInt(uploadBurstField.getText())*8);
+ if(kbpsDownload.getSelectedIndex() == KILOBIT)
+ props.setProperty(SpeedSelectorConstants.MAXDOWNLOAD, downloadField.getText());
+ else
+ props.setProperty(SpeedSelectorConstants.MAXDOWNLOAD, "" + Integer.parseInt(downloadField.getText())*8);
+ if(kbpsBurstDownload.getSelectedIndex() == KILOBIT)
+ props.setProperty(SpeedSelectorConstants.MAXDOWNLOADBURST, downloadBurstField.getText());
+ else
+ props.setProperty(SpeedSelectorConstants.MAXDOWNLOADBURST, "" + Integer.parseInt(downloadBurstField.getText())*8);
+ }
+
+ protected void initUsage(String upload, String download) {
+ uploadMonth.setText("" + SpeedHelper.calculateMonthlyUsage(Integer.parseInt(upload)/8));
+ downloadMonth.setText("" + SpeedHelper.calculateMonthlyUsage(Integer.parseInt(download)/8));
+ }
+
+ protected void initUsage() {
+ String upload = "";
+ if(kbpsUpload.getSelectedIndex() == KILOBIT)
+ upload = uploadField.getText();
+ else
+ upload = "" + Integer.parseInt(uploadField.getText())/8;
+ String download = "";
+ if(kbpsDownload.getSelectedIndex() == KILOBIT)
+ download = downloadField.getText();
+ else
+ download = "" + Integer.parseInt(downloadField.getText())/8;
+ initUsage(upload, download);
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JTextField downloadBurstField;
+ private javax.swing.JLabel downloadBurstLabel;
+ private javax.swing.JTextField downloadField;
+ private javax.swing.JLabel downloadGB;
+ private javax.swing.JLabel downloadLabel;
+ private javax.swing.JTextField downloadMonth;
+ private javax.swing.JLabel downloadUsageLabel;
+ private javax.swing.JLabel explanation;
+ private javax.swing.JButton finishButton;
+ private javax.swing.JComboBox kbpsBurstDownload;
+ private javax.swing.JComboBox kbpsBurstUpload;
+ private javax.swing.JComboBox kbpsDownload;
+ private javax.swing.JComboBox kbpsUpload;
+ private javax.swing.JButton previousButton;
+ private javax.swing.JLabel settingsInfo;
+ private javax.swing.JTextField uploadBurstField;
+ private javax.swing.JLabel uploadBurstLabel;
+ private javax.swing.JTextField uploadField;
+ private javax.swing.JLabel uploadGB;
+ private javax.swing.JLabel uploadLabel;
+ private javax.swing.JTextField uploadMonth;
+ private javax.swing.JLabel uploadUsageLabel;
+ // End of variables declaration//GEN-END:variables
+
+ private static final int KILOBIT = 0;
+ private static final int KILOBYTE = 1;
+}
diff --git a/apps/desktopgui/src/gui/SpeedSelectorConstants.java b/apps/desktopgui/src/gui/SpeedSelectorConstants.java
new file mode 100644
index 0000000000..ea5e32427b
--- /dev/null
+++ b/apps/desktopgui/src/gui/SpeedSelectorConstants.java
@@ -0,0 +1,25 @@
+package gui;
+
+/**
+ *
+ * @author mathias
+ */
+public class SpeedSelectorConstants {
+ ///Maximum upload speed for the internet connection
+ public static final String MAXUPLOADCAPABLE = "maxUploadCapable";
+ ///Maximum download speed for the internet connection
+ public static final String MAXDOWNLOADCAPABLE = "maxDownloadCapable";
+
+ //User profile type: what behaviour does this user have while using IP2?
+ public static final String USERTYPE = "userType";
+
+ //Maximum upload speed for I2P
+ public static final String MAXUPLOAD = "maxUpload";
+ //Maximum upload burst speed for I2P
+ public static final String MAXUPLOADBURST = "maxUploadBurst";
+
+ //Maximum download speed for I2P
+ public static final String MAXDOWNLOAD = "maxDownload";
+ //Maximum download burst speed for I2P
+ public static final String MAXDOWNLOADBURST = "maxDownloadBurst";
+}
diff --git a/apps/desktopgui/src/gui/Tray.java b/apps/desktopgui/src/gui/Tray.java
new file mode 100644
index 0000000000..5a8da78db9
--- /dev/null
+++ b/apps/desktopgui/src/gui/Tray.java
@@ -0,0 +1,194 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package gui;
+
+import desktopgui.*;
+import java.awt.AWTException;
+import java.awt.Desktop;
+import java.awt.Image;
+import java.awt.SystemTray;
+import java.awt.Toolkit;
+import java.awt.TrayIcon;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import router.RouterHandler;
+import router.RouterHelper;
+import router.configuration.PeerHelper;
+
+/**
+ *
+ * @author mathias
+ */
+public class Tray {
+
+ public Tray() {
+ tray = SystemTray.getSystemTray();
+ loadSystemTray();
+ }
+
+ private void loadSystemTray() {
+
+ Image image = Toolkit.getDefaultToolkit().getImage("desktopgui/resources/logo/logo.jpg");
+
+ final JPopupMenu popup = new JPopupMenu();
+
+ //Create menu items to put in the popup menu
+ JMenuItem browserLauncher = new JMenuItem("Launch browser");
+ browserLauncher.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ if(Desktop.isDesktopSupported()) {
+ Desktop desktop = Desktop.getDesktop();
+ try {
+ if(desktop.isSupported(Desktop.Action.BROWSE)) {
+ desktop.browse(new URI("http://localhost:7657"));
+ }
+ else {
+ trayIcon.displayMessage("Browser not found", "The default browser for your system was not found.", TrayIcon.MessageType.WARNING);
+ }
+ } catch (URISyntaxException ex) {
+ Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
+ } catch(IOException ex) {
+ Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ });
+ JMenuItem howto = new JMenuItem("How to use I2P");
+ howto.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ if(Desktop.isDesktopSupported()) {
+ Desktop desktop = Desktop.getDesktop();
+ try {
+ File f = new File("desktopgui/resources/howto/howto.html");
+ desktop.browse(new URI("file://" + f.getAbsolutePath()));
+ } catch (URISyntaxException ex) {
+ Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
+ } catch(IOException ex) {
+ Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ });
+ JMenu config = new JMenu("Configuration");
+ JMenuItem speedConfig = new JMenuItem("Speed");
+ speedConfig.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ (new SpeedSelector()).setVisible(true);
+ }
+
+ });
+ JMenuItem advancedConfig = new JMenuItem("Advanced Configuration");
+ advancedConfig.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ if(Desktop.isDesktopSupported()) {
+ Desktop desktop = Desktop.getDesktop();
+ try {
+ desktop.browse(new URI("http://localhost:7657/config.jsp"));
+ } catch (URISyntaxException ex) {
+ Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
+ } catch(IOException ex) {
+ Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ });
+ JMenuItem viewLog = new JMenuItem("View log");
+ viewLog.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ new LogViewer();
+ }
+
+ });
+ JMenuItem shutdown = new JMenuItem("Shutdown I2P");
+ shutdown.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ RouterHandler.setStatus(RouterHandler.SHUTDOWN_GRACEFULLY);
+ long shutdownTime = RouterHelper.getGracefulShutdownTimeRemaining();
+ System.out.println(shutdownTime);
+ if(shutdownTime>0) {
+ trayIcon.displayMessage("Shutting down...", "Shutdown time remaining: " + shutdownTime/1000 + " seconds."
+ + System.getProperty("line.separator") + "Shutdown will not happen immediately, because we are still participating in the network.", TrayIcon.MessageType.INFO);
+ }
+ else {
+ trayIcon.displayMessage("Shutting down...", "Shutting down immediately.", TrayIcon.MessageType.INFO);
+ }
+ }
+
+ });
+
+ //Add menu items to popup menu
+ popup.add(browserLauncher);
+ popup.add(howto);
+
+ config.add(speedConfig);
+ config.add(advancedConfig);
+ popup.add(config);
+
+ popup.add(viewLog);
+
+ popup.add(shutdown);
+
+ //Add tray icon
+ trayIcon = new JPopupTrayIcon(image, "I2P: the anonymous network", popup);
+ PeerHelper.addReachabilityListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ trayIcon.setToolTip("I2P Network status: " + PeerHelper.getReachability());
+ }
+
+ });
+ PeerHelper.addActivePeerListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ int activePeers = PeerHelper.getActivePeers();
+ if(activePeers == 0)
+ trayIcon.setImage(Toolkit.getDefaultToolkit().getImage("desktopgui/resources/logo/logo_red.jpg"));
+ else if(activePeers < 10)
+ trayIcon.setImage(Toolkit.getDefaultToolkit().getImage("desktopgui/resources/logo/logo_orange.jpg"));
+ else
+ trayIcon.setImage(Toolkit.getDefaultToolkit().getImage("desktopgui/resources/logo/logo_green.jpg"));
+
+ }
+
+ });
+
+ try {
+ tray.add(trayIcon);
+ } catch (AWTException ex) {
+ Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ private SystemTray tray = null;
+ private JPopupTrayIcon trayIcon = null;
+
+}
diff --git a/apps/desktopgui/src/gui/resources/LogViewer.properties b/apps/desktopgui/src/gui/resources/LogViewer.properties
new file mode 100644
index 0000000000..8cb0e62091
--- /dev/null
+++ b/apps/desktopgui/src/gui/resources/LogViewer.properties
@@ -0,0 +1,3 @@
+refreshButton.text=Refresh
+clearButton.text=Clear
+explanationText.text=Explanation ...
diff --git a/apps/desktopgui/src/gui/resources/SpeedSelector.properties b/apps/desktopgui/src/gui/resources/SpeedSelector.properties
new file mode 100644
index 0000000000..00eb6c973d
--- /dev/null
+++ b/apps/desktopgui/src/gui/resources/SpeedSelector.properties
@@ -0,0 +1,6 @@
+
+Form.title=I2P Speed Configuration
+nextButton.text=Next
+uploadLabel.text=What is your maximum upload speed?
+downloadLabel.text=What is your maximum download speed?
+speedExplanation.text=The maximum speed is set by your provider. It can be given in kilobit (kbps) or kilobyte (kBps).
One kilobyte equals eight kilobit.
diff --git a/apps/desktopgui/src/gui/resources/SpeedSelector2.properties b/apps/desktopgui/src/gui/resources/SpeedSelector2.properties
new file mode 100644
index 0000000000..909518ada2
--- /dev/null
+++ b/apps/desktopgui/src/gui/resources/SpeedSelector2.properties
@@ -0,0 +1,9 @@
+returnButton.text=Previous
+Form.title=I2P Speed Configuration
+questionLabel.text=Which of these descriptions fits you best?
+browseButton.text=Browsing: I want to use I2P to browse websites anonymously, no heavy usage.
+downloadButton.text=Downloading: I want to use I2P for downloads and filesharing, heavy usage.
+nextButton.text=Next
+browseButton.actionCommand=Browsing
+downloadButton.actionCommand=Downloading
+jLabel1.text=I2P can be used for many different purposes. Here, we present two possible descriptions. If you use a lot of bandwidth in I2P (for example using downloading), please check the downloading option. If your bandwidth usage is limited, please check the browsing option.
diff --git a/apps/desktopgui/src/gui/resources/SpeedSelector3.properties b/apps/desktopgui/src/gui/resources/SpeedSelector3.properties
new file mode 100644
index 0000000000..6dca3ca516
--- /dev/null
+++ b/apps/desktopgui/src/gui/resources/SpeedSelector3.properties
@@ -0,0 +1,17 @@
+Form.title=I2P Configuration
+previousButton.text=Previous
+finishButton.text=Finish
+uploadLabel.text=Upload Speed:
+uploadBurstLabel.text=Burst Upload Speed:
+downloadLabel.text=Download Speed:
+downloadBurstLabel.text=Burst Download Speed:
+uploadUsageLabel.text=GB
+downloadUsageLabel.text=GB
+uploadField.text=jTextField1
+uploadBurstField.text=jTextField2
+downloadField.text=jTextField4
+downloadBurstField.text=jTextField5
+uploadMonth.text=jTextField1
+downloadMonth.text=jTextField2
+settingsInfo.text=The profile information your entered, indicates that these are your optimal settings:
+explanation.text=We give a suggested upload and download speed. If your provider imposes a monthly bandwidth limit (usually given in gigabyte (GB)), please enter a value lower than that limit. If you run I2P only 50% of the time, you can double the bandwidth limit to use the same amount as when you are online 100% of the time.
diff --git a/apps/desktopgui/src/persistence/PropertyManager.java b/apps/desktopgui/src/persistence/PropertyManager.java
new file mode 100644
index 0000000000..bacbf348ac
--- /dev/null
+++ b/apps/desktopgui/src/persistence/PropertyManager.java
@@ -0,0 +1,72 @@
+package persistence;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author mathias
+ */
+public class PropertyManager {
+
+ public static void setProps(Properties props) {
+ PropertyManager.props = props;
+ }
+
+ public static Properties getProps() {
+ return props;
+ }
+
+ public static Properties loadProps() {
+ Properties defaultProps = new Properties();
+ defaultProps.setProperty("firstLoad", "true");
+
+ // create application properties with default
+ Properties applicationProps = new Properties(defaultProps);
+
+ // now load properties from last invocation
+ FileInputStream in;
+ try {
+ in = new FileInputStream(PROPSLOCATION);
+ applicationProps.load(in);
+ in.close();
+ } catch (FileNotFoundException ex) {
+ //Nothing serious, just means it's being loaded for the first time.
+ } catch(IOException ex) {
+ Logger.getLogger(PropertyManager.class.getName()).log(Level.INFO, null, ex);
+ }
+ props = applicationProps;
+ return applicationProps;
+ }
+
+ public static void saveProps(Properties props) {
+ FileOutputStream out;
+ try {
+ File d = new File(PROPSDIRECTORY);
+ if(!d.exists())
+ d.mkdir();
+ File f = new File(PROPSLOCATION);
+ if(!f.exists())
+ f.createNewFile();
+ out = new FileOutputStream(f);
+ props.store(out, PROPSLOCATION);
+ } catch (FileNotFoundException ex) {
+ Logger.getLogger(PropertyManager.class.getName()).log(Level.SEVERE, null, ex);
+ } catch(IOException ex) {
+ Logger.getLogger(PropertyManager.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ private static Properties props;
+
+ ///Location where we store the Application Properties
+ public static final String PROPSDIRECTORY = "desktopgui";
+ public static final String PROPSFILENAME = "appProperties";
+ public static final String PROPSLOCATION = PROPSDIRECTORY + File.separator + PROPSFILENAME;
+}
diff --git a/apps/desktopgui/src/router/RouterHandler.java b/apps/desktopgui/src/router/RouterHandler.java
new file mode 100644
index 0000000000..0752f877b5
--- /dev/null
+++ b/apps/desktopgui/src/router/RouterHandler.java
@@ -0,0 +1,38 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package router;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import net.i2p.router.RouterContext;
+
+/**
+ *
+ * @author mathias
+ */
+public class RouterHandler {
+ public static final int SHUTDOWN_GRACEFULLY = 0;
+ public static void setStatus(int status) {
+ if(status == SHUTDOWN_GRACEFULLY) {
+ Thread t = new Thread(new Runnable() {
+
+ public void run() {
+ RouterContext context = RouterHelper.getContext();
+ context.router().shutdownGracefully();
+ while(context.router().getShutdownTimeRemaining()>0)
+ try {
+ Thread.sleep(context.router().getShutdownTimeRemaining());
+ } catch (InterruptedException ex) {
+ Logger.getLogger(RouterHandler.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ System.exit(0);
+ }
+
+ });
+ t.start();
+ }
+ }
+}
diff --git a/apps/desktopgui/src/router/RouterHelper.java b/apps/desktopgui/src/router/RouterHelper.java
new file mode 100644
index 0000000000..6d3cddd03d
--- /dev/null
+++ b/apps/desktopgui/src/router/RouterHelper.java
@@ -0,0 +1,17 @@
+package router;
+
+import net.i2p.router.RouterContext;
+
+/**
+ *
+ * @author mathias
+ */
+public class RouterHelper {
+ public static RouterContext getContext() {
+ return (RouterContext) RouterContext.listContexts().get(0);
+ }
+
+ public static long getGracefulShutdownTimeRemaining() {
+ return RouterHelper.getContext().router().getShutdownTimeRemaining();
+ }
+}
diff --git a/apps/desktopgui/src/router/configuration/PeerHelper.java b/apps/desktopgui/src/router/configuration/PeerHelper.java
new file mode 100644
index 0000000000..2272456f8d
--- /dev/null
+++ b/apps/desktopgui/src/router/configuration/PeerHelper.java
@@ -0,0 +1,165 @@
+package router.configuration;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+import net.i2p.data.RouterAddress;
+import net.i2p.router.CommSystemFacade;
+import net.i2p.router.RouterContext;
+import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
+import net.i2p.router.transport.ntcp.NTCPAddress;
+import router.RouterHelper;
+
+/**
+ * Part of the code imported and adapted from the I2P Router Console (which is licensed as public domain)
+ */
+public class PeerHelper {
+ public static String getReachability() {
+ RouterContext context = RouterHelper.getContext();
+ if (context.router().getUptime() > 60*1000
+ && (!context.router().gracefulShutdownInProgress())
+ && !context.clientManager().isAlive())
+ return "ERROR: Client Manager I2CP Error - check logs"; // not a router problem but the user should know
+ if (!context.clock().getUpdatedSuccessfully())
+ return "ERROR: ClockSkew";
+ if (context.router().isHidden())
+ return "Hidden";
+
+ int status = context.commSystem().getReachabilityStatus();
+ switch (status) {
+ case CommSystemFacade.STATUS_OK:
+ RouterAddress ra = context.router().getRouterInfo().getTargetAddress("NTCP");
+ if (ra == null || (new NTCPAddress(ra)).isPubliclyRoutable())
+ return "OK";
+ return "ERROR: Private TCP Address";
+ case CommSystemFacade.STATUS_DIFFERENT:
+ return "ERROR: You are behind a symmetric NAT.";
+ case CommSystemFacade.STATUS_REJECT_UNSOLICITED:
+ if (context.router().getRouterInfo().getTargetAddress("NTCP") != null)
+ return "WARNING: You are behind a firewall and have Inbound TCP Enabled";
+ if (((FloodfillNetworkDatabaseFacade)context.netDb()).floodfillEnabled())
+ return "WARNING: You are behind a firewall and are a floodfill router";
+ if (context.router().getRouterInfo().getCapabilities().indexOf('O') >= 0)
+ return "WARNING: You are behind a firewall and are a fast router";
+ return "Firewalled";
+ case CommSystemFacade.STATUS_HOSED:
+ return "ERROR: The UDP port is already in use. Set i2np.udp.internalPort=xxxx to a different value in the advanced config and restart";
+ case CommSystemFacade.STATUS_UNKNOWN: // fallthrough
+ default:
+ ra = context.router().getRouterInfo().getTargetAddress("UDP");
+ if (ra == null && context.router().getUptime() > 5*60*1000) {
+ if (context.getProperty(PROP_I2NP_NTCP_HOSTNAME) == null ||
+ context.getProperty(PROP_I2NP_NTCP_PORT) == null)
+ return "ERROR: UDP is disabled and the inbound TCP host/port combination is not set";
+ else
+ return "WARNING: You are behind a firewall and have UDP Disabled";
+ }
+ return "Testing";
+ }
+ }
+
+ /**
+ * How many peers we are talking to now
+ *
+ */
+ public static int getActivePeers() {
+ RouterContext context = RouterHelper.getContext();
+ if (context == null)
+ return 0;
+ else
+ return context.commSystem().countActivePeers();
+ }
+
+ public static void addActivePeerListener(ActionListener listener) {
+ synchronized(activePeerListeners) {
+ activePeerListeners.add(listener);
+ if(activePeerTimer == null) {
+ activePeerTimer = new Timer();
+ TimerTask t = new TimerTask() {
+ private int activePeers = 0;
+
+ @Override
+ public void run() {
+ int newActivePeers = getActivePeers();
+ if(!(activePeers == newActivePeers)) {
+ synchronized(activePeerListeners) {
+ for(int i=0; i reachabilityListeners = new ArrayList();
+ private static Timer reachabilityTimer = null;
+
+ private static List activePeerListeners = new ArrayList();
+ private static Timer activePeerTimer = null;
+
+ /** copied from various private components */
+ public final static String PROP_I2NP_UDP_PORT = "i2np.udp.port";
+ public final static String PROP_I2NP_INTERNAL_UDP_PORT = "i2np.udp.internalPort";
+ public final static String PROP_I2NP_NTCP_HOSTNAME = "i2np.ntcp.hostname";
+ public final static String PROP_I2NP_NTCP_PORT = "i2np.ntcp.port";
+ public final static String PROP_I2NP_NTCP_AUTO_PORT = "i2np.ntcp.autoip";
+ public final static String PROP_I2NP_NTCP_AUTO_IP = "i2np.ntcp.autoport";
+}
diff --git a/apps/desktopgui/src/router/configuration/SpeedHandler.java b/apps/desktopgui/src/router/configuration/SpeedHandler.java
new file mode 100644
index 0000000000..235790792a
--- /dev/null
+++ b/apps/desktopgui/src/router/configuration/SpeedHandler.java
@@ -0,0 +1,34 @@
+package router.configuration;
+
+import net.i2p.router.RouterContext;
+import net.i2p.router.transport.FIFOBandwidthRefiller;
+import router.RouterHelper;
+
+/**
+ *
+ * @author mathias
+ */
+public class SpeedHandler {
+
+ public static void setInboundBandwidth(int kbytes) {
+ context.router().setConfigSetting(FIFOBandwidthRefiller.PROP_INBOUND_BANDWIDTH, "" + kbytes);
+ context.router().saveConfig();
+ }
+
+ public static void setOutboundBandwidth(int kbytes) {
+ context.router().setConfigSetting(FIFOBandwidthRefiller.PROP_OUTBOUND_BANDWIDTH, "" + kbytes);
+ context.router().saveConfig();
+ }
+
+ public static void setInboundBurstBandwidth(int kbytes) {
+ context.router().setConfigSetting(FIFOBandwidthRefiller.PROP_INBOUND_BURST_BANDWIDTH, "" + kbytes);
+ context.router().saveConfig();
+ }
+
+ public static void setOutboundBurstBandwidth(int kbytes) {
+ context.router().setConfigSetting(FIFOBandwidthRefiller.PROP_OUTBOUND_BURST_BANDWIDTH, "" + kbytes);
+ context.router().saveConfig();
+ }
+
+ private static final RouterContext context = RouterHelper.getContext();
+}
diff --git a/apps/desktopgui/src/router/configuration/SpeedHelper.java b/apps/desktopgui/src/router/configuration/SpeedHelper.java
new file mode 100644
index 0000000000..acad2adb14
--- /dev/null
+++ b/apps/desktopgui/src/router/configuration/SpeedHelper.java
@@ -0,0 +1,32 @@
+package router.configuration;
+
+/**
+ *
+ * @author mathias
+ */
+public class SpeedHelper {
+ public static final String USERTYPE_BROWSING = "Browsing";
+ public static final String USERTYPE_DOWNLOADING = "Downloading";
+
+ public static int calculateSpeed(String capable, String profile) {
+ int capableSpeed = Integer.parseInt(capable);
+ int advisedSpeed = capableSpeed;
+ if(capableSpeed > 1000) {
+ if(profile.equals(USERTYPE_BROWSING)) //Don't overdo usage for people just wanting to browse (we don't want to drive them away due to resource hogging)
+ advisedSpeed *= 0.6;
+ else if(profile.equals(USERTYPE_DOWNLOADING))
+ advisedSpeed *= 0.8;
+ }
+ else
+ advisedSpeed *= 0.6; //Lower available bandwidth: don't hog all the bandwidth
+ return advisedSpeed;
+ }
+
+ public static int calculateMonthlyUsage(int kbytes) {
+ return (int) ((((long)kbytes)*3600*24*31)/1000000);
+ }
+
+ public static int calculateSpeed(int gigabytes) {
+ return (int) (((long)gigabytes)*1000000/31/24/3600);
+ }
+}
diff --git a/apps/desktopgui/src/util/IntegerVerifier.java b/apps/desktopgui/src/util/IntegerVerifier.java
new file mode 100644
index 0000000000..74f87961da
--- /dev/null
+++ b/apps/desktopgui/src/util/IntegerVerifier.java
@@ -0,0 +1,32 @@
+package util;
+
+import javax.swing.InputVerifier;
+import javax.swing.JComponent;
+import javax.swing.JTextField;
+
+/**
+ *
+ * @author mathias
+ */
+
+public class IntegerVerifier extends InputVerifier {
+
+ @Override
+ public boolean verify(JComponent arg0) {
+ JTextField jtf = (JTextField) arg0;
+ return verify(jtf.getText());
+ }
+
+ @Override
+ public boolean shouldYieldFocus(JComponent input) {
+ return verify(input);
+ }
+
+ public static boolean verify(String s) {
+ for(int i=0;i '9' || s.charAt(i) < '0')
+ return false;
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/BufferLogger.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/BufferLogger.java
index 29f954fc4f..4c3da08988 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/BufferLogger.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/BufferLogger.java
@@ -14,7 +14,7 @@ import net.i2p.util.Log;
*/
class BufferLogger implements Logging {
private final static Log _log = new Log(BufferLogger.class);
- private ByteArrayOutputStream _baos;
+ private ByteArrayOutputStream _baos; // should be final and use a factory. LINT
private boolean _ignore;
/**
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/HTTPResponseOutputStream.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/HTTPResponseOutputStream.java
index 411b2c4426..12940a81bc 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/HTTPResponseOutputStream.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/HTTPResponseOutputStream.java
@@ -59,13 +59,16 @@ class HTTPResponseOutputStream extends FilterOutputStream {
_buf1 = new byte[1];
}
+ @Override
public void write(int c) throws IOException {
_buf1[0] = (byte)c;
write(_buf1, 0, 1);
}
+ @Override
public void write(byte buf[]) throws IOException {
write(buf, 0, buf.length);
}
+ @Override
public void write(byte buf[], int off, int len) throws IOException {
if (_headerWritten) {
out.write(buf, off, len);
@@ -207,6 +210,7 @@ class HTTPResponseOutputStream extends FilterOutputStream {
out.write("\r\n".getBytes()); // end of the headers
}
+ @Override
public void close() throws IOException {
out.close();
}
@@ -303,11 +307,13 @@ class HTTPResponseOutputStream extends FilterOutputStream {
return true;
}
}
+ @Override
public String toString() {
return "Read: " + getTotalRead() + " expanded: " + getTotalExpanded() + " remaining: " + getRemaining() + " finished: " + getFinished();
}
}
+ @Override
public String toString() {
return super.toString() + ": " + _in;
}
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java
index b11f954e7e..015f5c9c58 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java
@@ -75,7 +75,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
private static long __tunnelId = 0;
private long _tunnelId;
private Properties _clientOptions;
- private List _sessions;
+ private final List _sessions;
public static final int PACKET_DELAY = 100;
@@ -89,7 +89,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
private static final String nocli_args[] = { "-nocli", "-die"};
- private List tasks = new ArrayList();
+ private final List tasks = new ArrayList();
private int next_task_id = 1;
private Set listeners = new HashSet();
@@ -606,9 +606,9 @@ public class I2PTunnel implements Logging, EventDispatcher {
*/
public void runHttpClient(String args[], Logging l) {
if (args.length >= 1 && args.length <= 3) {
- int port = -1;
+ int clientPort = -1;
try {
- port = Integer.parseInt(args[0]);
+ clientPort = Integer.parseInt(args[0]);
} catch (NumberFormatException nfe) {
l.log("invalid port");
_log.error(getPrefix() + "Port specified is not valid: " + args[0], nfe);
@@ -642,12 +642,12 @@ public class I2PTunnel implements Logging, EventDispatcher {
I2PTunnelTask task;
ownDest = !isShared;
try {
- task = new I2PTunnelHTTPClient(port, l, ownDest, proxy, (EventDispatcher) this, this);
+ task = new I2PTunnelHTTPClient(clientPort, l, ownDest, proxy, (EventDispatcher) this, this);
addtask(task);
notifyEvent("httpclientTaskId", Integer.valueOf(task.getId()));
} catch (IllegalArgumentException iae) {
- _log.error(getPrefix() + "Invalid I2PTunnel config to create an httpclient [" + host + ":"+ port + "]", iae);
- l.log("Invalid I2PTunnel configuration [" + host + ":" + port + "]");
+ _log.error(getPrefix() + "Invalid I2PTunnel config to create an httpclient [" + host + ":"+ clientPort + "]", iae);
+ l.log("Invalid I2PTunnel configuration [" + host + ":" + clientPort + "]");
notifyEvent("httpclientTaskId", Integer.valueOf(-1));
}
} else {
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java
index 502bb28d5c..12931f3a27 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java
@@ -44,11 +44,11 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
while (tok.hasMoreTokens()) {
String destination = tok.nextToken();
try {
- Destination dest = I2PTunnel.destFromName(destination);
- if (dest == null)
+ Destination destN = I2PTunnel.destFromName(destination);
+ if (destN == null)
l.log("Could not resolve " + destination);
else
- dests.add(dest);
+ dests.add(destN);
} catch (DataFormatException dfe) {
l.log("Bad format parsing \"" + destination + "\"");
}
@@ -71,10 +71,10 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
public long getReadTimeout() { return readTimeout; }
protected void clientConnectionRun(Socket s) {
- Destination dest = pickDestination();
+ Destination destN = pickDestination();
I2PSocket i2ps = null;
try {
- i2ps = createI2PSocket(dest);
+ i2ps = createI2PSocket(destN);
i2ps.setReadTimeout(readTimeout);
new I2PTunnelRunner(s, i2ps, sockLock, null, mySockets);
} catch (Exception ex) {
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java
index b6eb392243..c4eafde506 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java
@@ -41,8 +41,8 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
private static volatile long __clientId = 0;
protected long _clientId;
- protected Object sockLock = new Object(); // Guards sockMgr and mySockets
- protected I2PSocketManager sockMgr;
+ protected final Object sockLock = new Object(); // Guards sockMgr and mySockets
+ protected I2PSocketManager sockMgr; // should be final and use a factory. LINT
protected List mySockets = new ArrayList();
protected Destination dest = null;
@@ -52,20 +52,20 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
private ServerSocket ss;
- private Object startLock = new Object();
+ private final Object startLock = new Object();
private boolean startRunning = false;
- private Object closeLock = new Object();
+ // private Object closeLock = new Object();
- private byte[] pubkey;
+ // private byte[] pubkey;
private String handlerName;
private String privKeyFile;
- private Object conLock = new Object();
+ // private Object conLock = new Object();
/** List of Socket for those accept()ed but not yet started up */
- private List _waitingSockets = new ArrayList();
+ private List _waitingSockets = new ArrayList(); // should be final and use a factory. LINT
/** How many connections will we allow to be in the process of being built at once? */
private int _numConnectionBuilders;
/** How long will we allow sockets to sit in the _waitingSockets map before killing them? */
@@ -100,7 +100,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
}
/**
- * @param privKeyFile null to generate a transient key
+ * @param pkf null to generate a transient key
*
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
* badly that we cant create a socketManager
@@ -278,6 +278,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
}
}
sockManager.setName("Client");
+ tunnel.addSession(sockManager.getSession());
return sockManager;
}
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java
index bf7ebf0a7a..d781866d95 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java
@@ -17,7 +17,6 @@ import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.client.streaming.I2PSocketOptions;
-import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.util.EventDispatcher;
@@ -55,7 +54,7 @@ import net.i2p.util.Log;
public class I2PTunnelConnectClient extends I2PTunnelClientBase implements Runnable {
private static final Log _log = new Log(I2PTunnelConnectClient.class);
- private List _proxyList;
+ private final List _proxyList;
private final static byte[] ERR_DESTINATION_UNKNOWN =
("HTTP/1.1 503 Service Unavailable\r\n"+
@@ -116,12 +115,12 @@ public class I2PTunnelConnectClient extends I2PTunnelClientBase implements Runna
I2PTunnel tunnel) throws IllegalArgumentException {
super(localPort, ownDest, l, notifyThis, "HTTPHandler " + (++__clientId), tunnel);
+ _proxyList = new ArrayList();
if (waitEventValue("openBaseClientResult").equals("error")) {
notifyEvent("openConnectClientResult", "error");
return;
}
- _proxyList = new ArrayList();
if (wwwProxy != null) {
StringTokenizer tok = new StringTokenizer(wwwProxy, ",");
while (tok.hasMoreTokens())
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
index 8e5ef9f4dc..93c8e86742 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
@@ -50,7 +50,7 @@ import net.i2p.util.Log;
public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable {
private static final Log _log = new Log(I2PTunnelHTTPClient.class);
- private List proxyList;
+ private final List proxyList;
private HashMap addressHelpers = new HashMap();
@@ -145,12 +145,12 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
I2PTunnel tunnel) throws IllegalArgumentException {
super(localPort, ownDest, l, notifyThis, "HTTPHandler " + (++__clientId), tunnel);
+ proxyList = new ArrayList();
if (waitEventValue("openBaseClientResult").equals("error")) {
notifyEvent("openHTTPClientResult", "error");
return;
}
- proxyList = new ArrayList();
if (wwwProxy != null) {
StringTokenizer tok = new StringTokenizer(wwwProxy, ",");
while (tok.hasMoreTokens())
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientRunner.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientRunner.java
index 9ade9021f5..6afc940f7d 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientRunner.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientRunner.java
@@ -30,11 +30,13 @@ public class I2PTunnelHTTPClientRunner extends I2PTunnelRunner {
_log = I2PAppContext.getGlobalContext().logManager().getLog(I2PTunnelHTTPClientRunner.class);
}
+ @Override
protected OutputStream getSocketOut() throws IOException {
OutputStream raw = super.getSocketOut();
return new HTTPResponseOutputStream(raw);
}
+ @Override
protected void close(OutputStream out, InputStream in, OutputStream i2pout, InputStream i2pin, Socket s, I2PSocket i2ps, Thread t1, Thread t2) throws InterruptedException, IOException {
try {
i2pin.close();
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java
index d6cb40a259..d43639cb7e 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java
@@ -59,6 +59,7 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
* Called by the thread pool of I2PSocket handlers
*
*/
+ @Override
protected void blockingHandle(I2PSocket socket) {
long afterAccept = getTunnel().getContext().clock().now();
long afterSocket = -1;
@@ -247,7 +248,9 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
super(o);
}
+ @Override
protected boolean shouldCompress() { return true; }
+ @Override
protected void finishHeaders() throws IOException {
if (_log.shouldLog(Log.INFO))
_log.info("Including x-i2p-gzip as the content encoding in the response");
@@ -255,6 +258,7 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
super.finishHeaders();
}
+ @Override
protected void beginProcessing() throws IOException {
if (_log.shouldLog(Log.INFO))
_log.info("Beginning compression processing");
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java
index 732c222a71..8b62702198 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java
@@ -51,11 +51,11 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
while (tok.hasMoreTokens()) {
String destination = tok.nextToken();
try {
- Destination dest = I2PTunnel.destFromName(destination);
- if (dest == null)
+ Destination destN = I2PTunnel.destFromName(destination);
+ if (destN == null)
l.log("Could not resolve " + destination);
else
- dests.add(dest);
+ dests.add(destN);
} catch (DataFormatException dfe) {
l.log("Bad format parsing \"" + destination + "\"");
}
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java
index 7e12aa30a6..2e209dbd74 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java
@@ -3,22 +3,18 @@ package net.i2p.i2ptunnel;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.Properties;
-import net.i2p.I2PAppContext;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.crypto.SHA256Generator;
-import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.data.Hash;
import net.i2p.data.Base32;
import net.i2p.util.EventDispatcher;
-import net.i2p.util.I2PThread;
import net.i2p.util.Log;
/**
@@ -83,6 +79,7 @@ public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable {
this.hostname = opts.getProperty(PROP_HOSTNAME, PROP_HOSTNAME_DEFAULT);
}
+ @Override
protected void blockingHandle(I2PSocket socket) {
try {
// give them 15 seconds to send in the request
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java
index f237b97efb..76480a9403 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java
@@ -36,7 +36,7 @@ public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorL
private Socket s;
private I2PSocket i2ps;
- Object slock, finishLock = new Object();
+ final Object slock, finishLock = new Object();
boolean finished = false;
HashMap ostreams, sockets;
byte[] initialI2PData;
@@ -114,6 +114,7 @@ public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorL
protected InputStream getSocketIn() throws IOException { return s.getInputStream(); }
protected OutputStream getSocketOut() throws IOException { return s.getOutputStream(); }
+ @Override
public void run() {
try {
InputStream in = getSocketIn();
@@ -239,6 +240,7 @@ public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorL
start();
}
+ @Override
public void run() {
String from = i2ps.getThisDestination().calculateHash().toBase64().substring(0,6);
String to = i2ps.getPeerDestination().calculateHash().toBase64().substring(0,6);
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java
index fa3478c71d..76246d7b66 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java
@@ -18,8 +18,6 @@ import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
-import net.i2p.client.I2PClient;
-import net.i2p.client.I2PClientFactory;
import net.i2p.client.streaming.I2PServerSocket;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.client.streaming.I2PSocketManager;
@@ -36,8 +34,8 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
protected I2PSocketManager sockMgr;
protected I2PServerSocket i2pss;
- private Object lock = new Object();
- protected Object slock = new Object();
+ private final Object lock = new Object();
+ protected final Object slock = new Object();
protected InetAddress remoteHost;
protected int remotePort;
@@ -203,17 +201,17 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
public void run() {
if (shouldUsePool()) {
- I2PServerSocket i2pss = sockMgr.getServerSocket();
+ I2PServerSocket i2pS_S = sockMgr.getServerSocket();
int handlers = getHandlerCount();
for (int i = 0; i < handlers; i++) {
- I2PThread handler = new I2PThread(new Handler(i2pss), "Handle Server " + i);
+ I2PThread handler = new I2PThread(new Handler(i2pS_S), "Handle Server " + i);
handler.start();
}
} else {
- I2PServerSocket i2pss = sockMgr.getServerSocket();
+ I2PServerSocket i2pS_S = sockMgr.getServerSocket();
while (true) {
try {
- final I2PSocket i2ps = i2pss.accept();
+ final I2PSocket i2ps = i2pS_S.accept();
if (i2ps == null) throw new I2PException("I2PServerSocket closed");
new I2PThread(new Runnable() { public void run() { blockingHandle(i2ps); } }).start();
} catch (I2PException ipe) {
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelTask.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelTask.java
index 6aa8ca18f7..4a6a0bb66e 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelTask.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelTask.java
@@ -73,6 +73,7 @@ public abstract class I2PTunnelTask implements EventDispatcher {
public void reportAbuse(I2PSession session, int severity) {
}
+ @Override
public String toString() {
return name;
}
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java
index 019bc7826c..f57ecd23d1 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java
@@ -37,11 +37,11 @@ public class I2Ping extends I2PTunnelTask implements Runnable {
private String command;
private long timeout = PING_TIMEOUT;
- private Object simulLock = new Object();
+ private final Object simulLock = new Object();
private int simulPings = 0;
private long lastPingTime = 0;
- private Object lock = new Object(), slock = new Object();
+ private final Object lock = new Object(), slock = new Object();
//public I2Ping(String cmd, Logging l,
// boolean ownDest) {
@@ -197,6 +197,7 @@ public class I2Ping extends I2PTunnelTask implements Runnable {
start();
}
+ @Override
public void run() {
try {
Destination dest = I2PTunnel.destFromName(destination);
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelControllerGroup.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelControllerGroup.java
index 3b6e765399..16f418be9e 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelControllerGroup.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelControllerGroup.java
@@ -40,7 +40,7 @@ public class TunnelControllerGroup {
* no more tunnels are using it)
*
*/
- private Map _sessions;
+ private final Map _sessions;
public static TunnelControllerGroup getInstance() {
synchronized (TunnelControllerGroup.class) {
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/ReplyTracker.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/ReplyTracker.java
index f6a124c951..fbdf2939d1 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/ReplyTracker.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/ReplyTracker.java
@@ -1,6 +1,5 @@
package net.i2p.i2ptunnel.socks;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;
import net.i2p.data.Destination;
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKS5Server.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKS5Server.java
index 5e52926074..cc397c414c 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKS5Server.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKS5Server.java
@@ -379,7 +379,7 @@ public class SOCKS5Server extends SOCKSServer {
// This isn't really the right place for this, we can't stop the tunnel once it starts.
static SOCKSUDPTunnel _tunnel;
- static Object _startLock = new Object();
+ static final Object _startLock = new Object();
static byte[] dummyIP = new byte[4];
/**
* We got a UDP associate command.
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKSServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKSServer.java
index 06c3fab552..09e9284deb 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKSServer.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKSServer.java
@@ -9,7 +9,6 @@ package net.i2p.i2ptunnel.socks;
import java.net.Socket;
import net.i2p.client.streaming.I2PSocket;
-import net.i2p.i2ptunnel.I2PTunnel;
import net.i2p.util.Log;
/**
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKSUDPTunnel.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKSUDPTunnel.java
index 0adaa19506..0490a6f0af 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKSUDPTunnel.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKSUDPTunnel.java
@@ -7,10 +7,7 @@ import java.util.Map;
import net.i2p.data.Destination;
import net.i2p.i2ptunnel.I2PTunnel;
-import net.i2p.i2ptunnel.Logging;
-import net.i2p.i2ptunnel.udp.*;
import net.i2p.i2ptunnel.udpTunnel.I2PTunnelUDPClientBase;
-import net.i2p.util.EventDispatcher;
/**
* A Datagram Tunnel that can have multiple bidirectional ports on the UDP side.
@@ -63,12 +60,14 @@ public class SOCKSUDPTunnel extends I2PTunnelUDPClientBase {
}
}
+ @Override
public final void startRunning() {
super.startRunning();
// demuxer start() doesn't do anything
startall();
}
+ @Override
public boolean close(boolean forced) {
stopall();
return super.close(forced);
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/Pinger.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/Pinger.java
index a3a7975361..29d1186c4d 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/Pinger.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/Pinger.java
@@ -54,6 +54,6 @@ public class Pinger implements Source, Runnable {
protected Sink sink;
protected Thread thread;
- protected Object waitlock;
+ protected Object waitlock; // should be final and use a factory. LINT
protected boolean running;
}
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/StreamrConsumer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/StreamrConsumer.java
index 87ea0eefe6..9c1d584ae0 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/StreamrConsumer.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/StreamrConsumer.java
@@ -7,7 +7,6 @@ package net.i2p.i2ptunnel.streamr;
import java.net.InetAddress;
-import net.i2p.data.Destination;
import net.i2p.i2ptunnel.I2PTunnel;
import net.i2p.i2ptunnel.Logging;
import net.i2p.i2ptunnel.udp.*;
@@ -38,6 +37,7 @@ public class StreamrConsumer extends I2PTunnelUDPClientBase {
this.pinger.setSink(this);
}
+ @Override
public final void startRunning() {
super.startRunning();
// send subscribe-message
@@ -45,6 +45,7 @@ public class StreamrConsumer extends I2PTunnelUDPClientBase {
l.log("Streamr client ready");
}
+ @Override
public boolean close(boolean forced) {
// send unsubscribe-message
this.pinger.stop();
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/StreamrProducer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/StreamrProducer.java
index b801cb94f4..7d6b14491d 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/StreamrProducer.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/StreamrProducer.java
@@ -9,7 +9,6 @@ package net.i2p.i2ptunnel.streamr;
import java.io.File;
// i2p
-import net.i2p.client.I2PSession;
import net.i2p.i2ptunnel.I2PTunnel;
import net.i2p.i2ptunnel.Logging;
import net.i2p.i2ptunnel.udp.*;
@@ -45,12 +44,14 @@ public class StreamrProducer extends I2PTunnelUDPServerBase {
this.server.setSink(this.multi);
}
+ @Override
public final void startRunning() {
super.startRunning();
this.server.start();
l.log("Streamr server ready");
}
+ @Override
public boolean close(boolean forced) {
this.server.stop();
this.multi.stop();
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/Subscriber.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/Subscriber.java
index 97abdb8890..377292ddef 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/Subscriber.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/Subscriber.java
@@ -6,17 +6,12 @@
package net.i2p.i2ptunnel.streamr;
// system
-import java.io.File;
import java.util.Set;
// i2p
import net.i2p.client.I2PSession;
import net.i2p.data.Destination;
-import net.i2p.i2ptunnel.I2PTunnel;
-import net.i2p.i2ptunnel.Logging;
import net.i2p.i2ptunnel.udp.*;
-import net.i2p.i2ptunnel.udpTunnel.I2PTunnelUDPServerBase;
-import net.i2p.util.EventDispatcher;
import net.i2p.util.ConcurrentHashSet;
/**
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udp/I2PSink.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udp/I2PSink.java
index f7a1bf541e..e08596af11 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udp/I2PSink.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udp/I2PSink.java
@@ -69,5 +69,5 @@ public class I2PSink implements Sink {
protected boolean raw;
protected I2PSession sess;
protected Destination dest;
- protected I2PDatagramMaker maker;
+ protected I2PDatagramMaker maker; // should be final and use a factory. LINT
}
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udp/I2PSinkAnywhere.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udp/I2PSinkAnywhere.java
index 54d5a7d97d..2da942a74a 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udp/I2PSinkAnywhere.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udp/I2PSinkAnywhere.java
@@ -67,5 +67,5 @@ public class I2PSinkAnywhere implements Sink {
protected boolean raw;
protected I2PSession sess;
protected Destination dest;
- protected I2PDatagramMaker maker;
+ protected I2PDatagramMaker maker; // should be final and use a factory. LINT
}
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udpTunnel/I2PTunnelUDPClientBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udpTunnel/I2PTunnelUDPClientBase.java
index c92da6ae8a..14945c8422 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udpTunnel/I2PTunnelUDPClientBase.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udpTunnel/I2PTunnelUDPClientBase.java
@@ -5,21 +5,9 @@ package net.i2p.i2ptunnel.udpTunnel;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.ConnectException;
-import java.net.InetAddress;
-import java.net.NoRouteToHostException;
import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Properties;
import net.i2p.I2PAppContext;
-import net.i2p.I2PException;
import net.i2p.client.I2PClient;
import net.i2p.client.I2PClientFactory;
import net.i2p.client.I2PSession;
@@ -31,10 +19,31 @@ import net.i2p.i2ptunnel.I2PTunnelTask;
import net.i2p.i2ptunnel.Logging;
import net.i2p.i2ptunnel.udp.*;
import net.i2p.util.EventDispatcher;
-import net.i2p.util.I2PThread;
import net.i2p.util.Log;
-public abstract class I2PTunnelUDPClientBase extends I2PTunnelTask implements Source, Sink {
+ /**
+ * Base client class that sets up an I2P Datagram client destination.
+ * The UDP side is not implemented here, as there are at least
+ * two possibilities:
+ *
+ * 1) UDP side is a "server"
+ * Example: Streamr Consumer
+ * - Configure a destination host and port
+ * - External application sends no data
+ * - Extending class must have a constructor with host and port arguments
+ *
+ * 2) UDP side is a client/server
+ * Example: SOCKS UDP (DNS requests?)
+ * - configure an inbound port and a destination host and port
+ * - External application sends and receives data
+ * - Extending class must have a constructor with host and 2 port arguments
+ *
+ * So the implementing class must create a UDPSource and/or UDPSink,
+ * and must call setSink().
+ *
+ * @author zzz with portions from welterde's streamr
+ */
+ public abstract class I2PTunnelUDPClientBase extends I2PTunnelTask implements Source, Sink {
private static final Log _log = new Log(I2PTunnelUDPClientBase.class);
protected I2PAppContext _context;
@@ -69,33 +78,11 @@ public abstract class I2PTunnelUDPClientBase extends I2PTunnelTask implements So
private Source _i2pSource;
private Sink _i2pSink;
private Destination _otherDest;
-
/**
- * Base client class that sets up an I2P Datagram client destination.
- * The UDP side is not implemented here, as there are at least
- * two possibilities:
- *
- * 1) UDP side is a "server"
- * Example: Streamr Consumer
- * - Configure a destination host and port
- * - External application sends no data
- * - Extending class must have a constructor with host and port arguments
- *
- * 2) UDP side is a client/server
- * Example: SOCKS UDP (DNS requests?)
- * - configure an inbound port and a destination host and port
- * - External application sends and receives data
- * - Extending class must have a constructor with host and 2 port arguments
- *
- * So the implementing class must create a UDPSource and/or UDPSink,
- * and must call setSink().
- *
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
* badly that we cant create a socketManager
- *
- * @author zzz with portions from welterde's streamr
*/
- public I2PTunnelUDPClientBase(String destination, Logging l, EventDispatcher notifyThis,
+ public I2PTunnelUDPClientBase(String destination, Logging l, EventDispatcher notifyThis,
I2PTunnel tunnel) throws IllegalArgumentException {
super("UDPServer", notifyThis, tunnel);
_clientId = ++__clientId;
@@ -107,11 +94,11 @@ public abstract class I2PTunnelUDPClientBase extends I2PTunnelTask implements So
// create i2pclient and destination
I2PClient client = I2PClientFactory.createClient();
- Destination dest;
+ Destination destN;
byte[] key;
try {
ByteArrayOutputStream out = new ByteArrayOutputStream(512);
- dest = client.createDestination(out);
+ destN = client.createDestination(out);
key = out.toByteArray();
} catch(Exception exc) {
throw new RuntimeException("failed to create i2p-destination", exc);
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udpTunnel/I2PTunnelUDPServerBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udpTunnel/I2PTunnelUDPServerBase.java
index 8dcd66a365..6ba8379f94 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udpTunnel/I2PTunnelUDPServerBase.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udpTunnel/I2PTunnelUDPServerBase.java
@@ -3,54 +3,24 @@
*/
package net.i2p.i2ptunnel.udpTunnel;
-import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.net.ConnectException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketException;
-import java.net.SocketTimeoutException;
-import java.util.Iterator;
-import java.util.Properties;
-import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.client.I2PClient;
import net.i2p.client.I2PClientFactory;
import net.i2p.client.I2PSession;
import net.i2p.client.I2PSessionException;
-import net.i2p.data.Base64;
import net.i2p.data.Destination;
import net.i2p.i2ptunnel.I2PTunnel;
import net.i2p.i2ptunnel.I2PTunnelTask;
import net.i2p.i2ptunnel.Logging;
import net.i2p.i2ptunnel.udp.*;
import net.i2p.util.EventDispatcher;
-import net.i2p.util.I2PThread;
import net.i2p.util.Log;
-public class I2PTunnelUDPServerBase extends I2PTunnelTask implements Source, Sink {
-
- private final static Log _log = new Log(I2PTunnelUDPServerBase.class);
-
- private Object lock = new Object();
- protected Object slock = new Object();
-
- private static volatile long __serverId = 0;
-
- protected Logging l;
-
- private static final long DEFAULT_READ_TIMEOUT = -1; // 3*60*1000;
- /** default timeout to 3 minutes - override if desired */
- protected long readTimeout = DEFAULT_READ_TIMEOUT;
-
- private I2PSession _session;
- private Source _i2pSource;
- private Sink _i2pSink;
-
/**
* Base client class that sets up an I2P Datagram server destination.
* The UDP side is not implemented here, as there are at least
@@ -70,11 +40,34 @@ public class I2PTunnelUDPServerBase extends I2PTunnelTask implements Source, Sin
*
* So the implementing class must create a UDPSource and/or UDPSink,
* and must call setSink().
+ *
+ * @author zzz with portions from welterde's streamr
+ */
+
+public class I2PTunnelUDPServerBase extends I2PTunnelTask implements Source, Sink {
+
+ private final static Log _log = new Log(I2PTunnelUDPServerBase.class);
+
+ private final Object lock = new Object();
+ protected Object slock = new Object();
+
+ private static volatile long __serverId = 0;
+
+ protected Logging l;
+
+ private static final long DEFAULT_READ_TIMEOUT = -1; // 3*60*1000;
+ /** default timeout to 3 minutes - override if desired */
+ protected long readTimeout = DEFAULT_READ_TIMEOUT;
+
+ private I2PSession _session;
+ private Source _i2pSource;
+ private Sink _i2pSink;
+
+ /**
*
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
* badly that we cant create a socketManager
*
- * @author zzz with portions from welterde's streamr
*/
public I2PTunnelUDPServerBase(boolean verify, File privkey, String privkeyname, Logging l,
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java
index 0a909c62ec..a029de725a 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java
@@ -8,7 +8,6 @@ package net.i2p.i2ptunnel.web;
*
*/
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
diff --git a/apps/streaming/java/src/net/i2p/client/streaming/Connection.java b/apps/streaming/java/src/net/i2p/client/streaming/Connection.java
index 6b99fdc00a..f73632683c 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/Connection.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/Connection.java
@@ -187,12 +187,12 @@ public class Connection {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Outbound window is full (" + _outboundPackets.size() + "/" + _options.getWindowSize() + "/"
+ _activeResends + "), waiting " + timeLeft);
- try { _outboundPackets.wait(Math.min(timeLeft,250l)); } catch (InterruptedException ie) {}
+ try { _outboundPackets.wait(Math.min(timeLeft,250l)); } catch (InterruptedException ie) { if (_log.shouldLog(Log.DEBUG)) _log.debug("InterruptedException while Outbound window is full (" + _outboundPackets.size() + "/" + _activeResends +")"); return false;}
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Outbound window is full (" + _outboundPackets.size() + "/" + _activeResends
+ "), waiting indefinitely");
- try { _outboundPackets.wait(250); } catch (InterruptedException ie) {} //10*1000
+ try { _outboundPackets.wait(250); } catch (InterruptedException ie) {if (_log.shouldLog(Log.DEBUG)) _log.debug("InterruptedException while Outbound window is full (" + _outboundPackets.size() + "/" + _activeResends + ")"); return false;} //10*1000
}
} else {
_context.statManager().addRateData("stream.chokeSizeEnd", _outboundPackets.size(), _context.clock().now() - start);
@@ -810,7 +810,11 @@ public class Connection {
synchronized (_connectLock) {
_connectLock.wait(timeLeft);
}
- } catch (InterruptedException ie) {}
+ } catch (InterruptedException ie) {
+ if (_log.shouldLog(Log.DEBUG)) _log.debug("waitForConnect(): InterruptedException");
+ _connectionError = "InterruptedException";
+ return;
+ }
}
}
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 b96eaea633..2d198ad66e 100644
--- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java
+++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionHandler.java
@@ -126,7 +126,7 @@ class ConnectionHandler {
if (timeoutMs <= 0) {
try {
syn = _synQueue.take(); // waits forever
- } catch (InterruptedException ie) {}
+ } catch (InterruptedException ie) { break;}
} else {
long remaining = expiration - _context.clock().now();
// (dont think this applies anymore for LinkedBlockingQueue)
@@ -138,7 +138,7 @@ class ConnectionHandler {
break;
try {
syn = _synQueue.poll(remaining, TimeUnit.MILLISECONDS); // waits the specified time max
- } catch (InterruptedException ie) {}
+ } catch (InterruptedException ie) { }
break;
}
}
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 cbb89e79ec..197b927541 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) {}
+ } catch (InterruptedException ie) { break; }
}
if (!writeSuccessful())
releasePayload();
diff --git a/build.xml b/build.xml
index ef84b2aab3..3a30ff8e7f 100644
--- a/build.xml
+++ b/build.xml
@@ -487,4 +487,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java b/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java
index b08d01c264..a3e5e57a7f 100644
--- a/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java
+++ b/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java
@@ -146,8 +146,8 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 implements I2PSession {
* I2PSession.PROTO_STREAMING
* I2PSession.PROTO_DATAGRAM
* 255 disallowed
- * @param fromport 1-65535 or 0 for unset
- * @param toport 1-65535 or 0 for unset
+ * @param fromPort 1-65535 or 0 for unset
+ * @param toPort 1-65535 or 0 for unset
*/
public boolean sendMessage(Destination dest, byte[] payload, int offset, int size,
SessionKey keyUsed, Set tagsSent, long expires,
diff --git a/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java b/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java
index 13b01a67ad..79066c4c62 100644
--- a/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java
+++ b/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java
@@ -178,7 +178,11 @@ public class I2CPMessageReader {
// pause .5 secs when we're paused
try {
Thread.sleep(500);
- } catch (InterruptedException ie) { // nop
+ } catch (InterruptedException ie) {
+ // we should break away here.
+ _log.warn("Breaking away stream", ie);
+ _listener.disconnected(I2CPMessageReader.this);
+ cancelRunner();
}
}
}
diff --git a/core/java/src/net/i2p/util/ConvertToHash.java b/core/java/src/net/i2p/util/ConvertToHash.java
index 0878556400..28da87d217 100644
--- a/core/java/src/net/i2p/util/ConvertToHash.java
+++ b/core/java/src/net/i2p/util/ConvertToHash.java
@@ -16,12 +16,15 @@ import net.i2p.data.Hash;
* Base32 desthash.b32.i2p
* example.i2p
*
- * @return null on failure
- *
* @author zzz
*/
public class ConvertToHash {
+ /**
+ * Convert any kind of destination String to a hash
+ *
+ * @return null on failure
+ */
public static Hash getHash(String peer) {
if (peer == null)
return null;
diff --git a/core/java/src/net/i2p/util/SimpleScheduler.java b/core/java/src/net/i2p/util/SimpleScheduler.java
index becf100995..ee7d36e99a 100644
--- a/core/java/src/net/i2p/util/SimpleScheduler.java
+++ b/core/java/src/net/i2p/util/SimpleScheduler.java
@@ -1,7 +1,6 @@
package net.i2p.util;
import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ThreadFactory;
@@ -43,6 +42,7 @@ public class SimpleScheduler {
_name = name;
_count = 0;
_executor = new ScheduledThreadPoolExecutor(THREADS, new CustomThreadFactory());
+ _executor.prestartAllCoreThreads();
}
/**
@@ -91,6 +91,11 @@ public class SimpleScheduler {
public Thread newThread(Runnable r) {
Thread rv = Executors.defaultThreadFactory().newThread(r);
rv.setName(_name + ' ' + (++_count) + '/' + THREADS);
+// Uncomment this to test threadgrouping, but we should be all safe now that the constructor preallocates!
+// String name = rv.getThreadGroup().getName();
+// if(!name.equals("main")) {
+// (new Exception("OWCH! DAMN! Wrong ThreadGroup `" + name +"', `" + rv.getName() + "'")).printStackTrace();
+// }
rv.setDaemon(true);
return rv;
}
@@ -144,9 +149,11 @@ public class SimpleScheduler {
_timeoutMs = timeoutMs;
_scheduled = initialDelay + System.currentTimeMillis();
}
+ @Override
public void schedule() {
_executor.scheduleWithFixedDelay(this, _initialDelay, _timeoutMs, TimeUnit.MILLISECONDS);
}
+ @Override
public void run() {
super.run();
_scheduled = _timeoutMs + System.currentTimeMillis();
diff --git a/core/java/src/net/i2p/util/SimpleTimer2.java b/core/java/src/net/i2p/util/SimpleTimer2.java
index 6239ed42f2..b2af33cf2b 100644
--- a/core/java/src/net/i2p/util/SimpleTimer2.java
+++ b/core/java/src/net/i2p/util/SimpleTimer2.java
@@ -5,7 +5,6 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ThreadFactory;
-import java.util.Map;
import net.i2p.I2PAppContext;
@@ -42,6 +41,7 @@ public class SimpleTimer2 {
_name = name;
_count = 0;
_executor = new CustomScheduledThreadPoolExecutor(THREADS, new CustomThreadFactory());
+ _executor.prestartAllCoreThreads();
}
/**
@@ -56,6 +56,7 @@ public class SimpleTimer2 {
super(threads, factory);
}
+ @Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if (t != null) // shoudn't happen, caught in RunnableEvent.run()
@@ -67,6 +68,11 @@ public class SimpleTimer2 {
public Thread newThread(Runnable r) {
Thread rv = Executors.defaultThreadFactory().newThread(r);
rv.setName(_name + ' ' + (++_count) + '/' + THREADS);
+// Uncomment this to test threadgrouping, but we should be all safe now that the constructor preallocates!
+// String name = rv.getThreadGroup().getName();
+// if(!name.equals("main")) {
+// (new Exception("OWCH! DAMN! Wrong ThreadGroup `" + name +"', `" + rv.getName() + "'")).printStackTrace();
+// }
rv.setDaemon(true);
return rv;
}
@@ -232,6 +238,7 @@ public class SimpleTimer2 {
public abstract void timeReached();
}
+ @Override
public String toString() {
return _name;
}
diff --git a/history.txt b/history.txt
index f027db23a5..5d2643a9d0 100644
--- a/history.txt
+++ b/history.txt
@@ -1,3 +1,94 @@
+2009-04-11 sponge
+ * i2ptunnel janitorial work and fixes on most locks.
+ Some locks still need work, and are marked with LINT in the comment.
+ Just grep for "LINT" to see where the remaining places are.
+
+2009-04-10 sponge
+ * More BOB threadgroup fixes, plus debug dump when things go wrong.
+ * Fixes to streaminglib, I2CP, which are related to the TG problem.
+ * JavaDocs fixups.
+
+2009-04-08 sponge
+ * More hopeful fixups to the infamous orpahned tunnel problem. *Sigh*
+
+2009-04-08 zzz
+ * IPV6/localhost:
+ - Enable IPv6 stack in the JVM, hopefully won't break anything
+ - Patch Jetty to support binding to IPv6 addresses
+ - Allow multiple bind addresses for the router console
+ in the clients.config file; for new installs the
+ default is now "127.0.0.1,::1"
+ - Change most instances of "localhost" to "127.0.0.1"
+ throughout the code
+ * Router:
+ - Move some classes to private static inner
+
+2009-04-07 sponge
+ * BOB prevent jvac from optimizing out thread-group code from -10
+
+2009-04-07 zzz
+ * NTCP: Prevent occasional NPE introduced in -4
+ * streamr: Synchronize DatagramMaker
+
+2009-04-07 sponge
+ * SimpleTimer2, SimpleScheduler fixed so that the threads all run from
+ The main threadgroup, not in the current possible child threadgroup.
+ So long as any SimpleTimer2/SimpleScheduler is started *BEFORE* any
+ child threadgroups, the constructors are threadgroup safe. What would
+ be super cool is if they were to be all jailed within thier very own
+ threadgroup too, but, I2P isn't up to the task of this yet.
+ * Fixes to BOB to ensure the above is true.
+
+2009-04-06 sponge
+ * Debugging to make SimpleTimer2 and SimpleScheduler easier to debug.
+ * Fix for the config files in the GUI from mathiasdm
+
+2009-04-04 sponge
+ * Hopeful fixups to the infamous orpahned tunnel problem.
+ * BOB now 0.0.5
+
+2009-04-04 zzz
+ * NTCP: Don't bid on messages too big to handle
+
+2009-04-03 zzz
+ * Console:
+ - Fix bug with IE buttons not working,
+ because it sends the label instead of the value
+ - Display version of downloaded update
+ * Update:
+ - Change default to "Download and verify"
+ - Change news fetch default to 24h (was 12h)
+
+2009-04-03 sponge
+ * Fix broken dependencies for BOB.jar
+ * Router build version incremented to 5.
+
+2009-04-02 zzz
+ * Profiles:
+ - Remove unused calculators and RateStats:
+ CapacityCalculator, StrictSpeedCalculator, IsFailingCalculator;
+ sendFailureSize, processSuccessRate, processfailureRate, commErrorRate,
+ tunnelTestResponseTimeSlow
+ - Reduced number of Rates in these RateStats:
+ sendSuccessSize, receiveSize, rejectRate, failRate
+ - ~5KB/profile savings total
+ - Deflate speed calculation once an hour instead of once a day,
+ to improve fast tier selection
+ - Remove dup comment in persisted files
+ * StatisticsManager - effective in 0.7.2:
+ - Spoof uptime to 90m for all
+ - Change tunnel stats from 10m to 60m
+ * Transport:
+ - Maintain a router hash -> IP map in transport,
+ to support additional IP checks (unused for now)
+ - Catch error on pre-2.6 kernels
+ - Some concurrent conversion
+ - Fix an HTML error on peers.jsp
+
+2009-04-01 zzz
+ * I2PTunnel: Fix tunnel close
+ http://forum.i2p/viewtopic.php?t=3231
+
2009-03-30 zzz
* I2CP:
- Implement BandwidthLimitsMessage
diff --git a/installer/resources/wrapper.config b/installer/resources/wrapper.config
index 4d09ba12c2..42958ba779 100644
--- a/installer/resources/wrapper.config
+++ b/installer/resources/wrapper.config
@@ -54,6 +54,10 @@ wrapper.java.classpath.17=lib/systray.jar
wrapper.java.classpath.18=lib/systray4j.jar
# BOB
wrapper.java.classpath.19=lib/BOB.jar
+# desktopgui
+wrapper.java.classpath.20=lib/appframework.jar
+wrapper.java.classpath.21=lib/swing-worker.jar
+wrapper.java.classpath.22=lib/desktopgui.jar
# Java Library Path (location of Wrapper.DLL or libwrapper.so)
wrapper.java.library.path.1=.
diff --git a/readme.html b/readme.html
index 0e4891b5d8..c359913350 100644
--- a/readme.html
+++ b/readme.html
@@ -16,6 +16,7 @@ you can:
eepsites.i2p: an anonymously hosted search engine of eepsites
ugha.i2p: ugha's eepsite, a wiki that anyone can edit, and lots of links
fproxy.tino.i2p: Freenet proxy
+ echelon.i2p: software archive and information for I2P
There are many more eepsites - just follow the links from the ones you see,
bookmark your favorites, and visit them often!
diff --git a/readme_de.html b/readme_de.html
index 1534585dab..e6fd916188 100644
--- a/readme_de.html
+++ b/readme_de.html
@@ -12,7 +12,8 @@
eepsites.i2p: Eine anonym gehostete Suchseite für Eepsites
ugha.i2p: Ugha's Eepsite, ein öffentliches Wiki mit vielen Links
fproxy.tino.i2p: Freenet proxy
-
+ echelon.i2p: Software Archive und Informationen zu I2P
+
Es gibt viel mehr Eepsites - folge einfach den Links die du findest,
bookmarke Deine Favoriten und besuche sie oft!
Im Internet surfen - Es gibt einen HTTP "outproxy" in I2P in Deinem
diff --git a/readme_fr.html b/readme_fr.html
index 5e619cff2b..f2accf826c 100644
--- a/readme_fr.html
+++ b/readme_fr.html
@@ -11,6 +11,7 @@
eepsites.i2p: un moteur de recherche d'eepsites
ugha.i2p: l'eepsite d'ugha, un wiki que chaucun peut éditer ainsi que
fproxy.tino.i2p: un proxy Freenet 0.5
+ echelon.i2p: archive
Il y a bien plus d'eepsites - suivez juste les liens au départ de ceux sur lesquels vous êtes, mettez-les dans vos favoris et visitez-les souvent!
Parcourez le web - Il y a pour l'instant un outproxy HTTP sur I2P attaché à votre propre proxy HTTP sur le port 4444 - vous devez simplement configurer le proxy de votre navigateur pour l'utiliser (comme expliqué ci-dessus) et aller sur n'importe quel URL normale - vos requêtes seront relayées par le réseau i2p.
diff --git a/readme_sv.html b/readme_sv.html
index b1f59fa04d..eab177cd14 100644
--- a/readme_sv.html
+++ b/readme_sv.html
@@ -27,6 +27,7 @@ sökmotor
wiki som alla kan förändra, innehåller många länkar
fproxy.tino.i2p:
Freenet proxy
+ echelon.i2p: software archive and information for I2P
Det finns många fler eepsidor - följ bara länkarna från dom du ser,
spara dina favoriter och besök dom ofta!
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index 1d4797d6fc..9900aa2884 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 = 16;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID);