diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java index 3fb439387..3e1960ec0 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java @@ -46,6 +46,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; @@ -69,6 +70,7 @@ public class I2PTunnel implements Logging, EventDispatcher { private I2PAppContext _context; private static long __tunnelId = 0; private long _tunnelId; + private Properties _clientOptions; public static final int PACKET_DELAY = 100; @@ -104,6 +106,9 @@ public class I2PTunnel implements Logging, EventDispatcher { _tunnelId = ++__tunnelId; _log = _context.logManager().getLog(I2PTunnel.class); _event = new EventDispatcherImpl(); + _clientOptions = new Properties(); + _clientOptions.putAll(System.getProperties()); + addConnectionEventListener(lsnr); boolean gui = true; boolean checkRunByE = true; @@ -167,6 +172,8 @@ public class I2PTunnel implements Logging, EventDispatcher { } } + public Properties getClientOptions() { return _clientOptions; } + private void addtask(I2PTunnelTask tsk) { tsk.setTunnel(this); if (tsk.isOpen()) { @@ -197,6 +204,8 @@ public class I2PTunnel implements Logging, EventDispatcher { if ("help".equals(cmdname)) { runHelp(l); + } else if ("clientoptions".equals(cmdname)) { + runClientOptions(args, l); } else if ("server".equals(cmdname)) { runServer(args, l); } else if ("textserver".equals(cmdname)) { @@ -262,6 +271,29 @@ public class I2PTunnel implements Logging, EventDispatcher { l.log("list"); l.log("run "); } + + /** + * Configure the extra I2CP options to use in any subsequent I2CP sessions. + * Usage: "clientoptions[ key=value]*" . + * + * Sets the event "clientoptions_onResult" = "ok" after completion. + * + * @param args each args[i] is a key=value pair to add to the options + * @param l logger to receive events and output + */ + public void runClientOptions(String args[], Logging l) { + _clientOptions.clear(); + if (args != null) { + for (int i = 0; i < args.length; i++) { + int index = args[i].indexOf('='); + if (index <= 0) continue; + String key = args[i].substring(0, index); + String val = args[i].substring(index+1); + _clientOptions.setProperty(key, val); + } + } + notifyEvent("clientoptions_onResult", "ok"); + } /** * Run the server pointing at the host and port specified using the private i2p @@ -304,7 +336,7 @@ public class I2PTunnel implements Logging, EventDispatcher { notifyEvent("serverTaskId", new Integer(-1)); return; } - I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, privKeyFile, args[2], l, (EventDispatcher) this); + I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, privKeyFile, args[2], l, (EventDispatcher) this, this); serv.setReadTimeout(readTimeout); serv.startRunning(); addtask(serv); @@ -350,7 +382,7 @@ public class I2PTunnel implements Logging, EventDispatcher { return; } - I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, args[2], l, (EventDispatcher) this); + I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, args[2], l, (EventDispatcher) this, this); serv.setReadTimeout(readTimeout); serv.startRunning(); addtask(serv); @@ -386,7 +418,7 @@ public class I2PTunnel implements Logging, EventDispatcher { return; } I2PTunnelTask task; - task = new I2PTunnelClient(port, args[1], l, ownDest, (EventDispatcher) this); + task = new I2PTunnelClient(port, args[1], l, ownDest, (EventDispatcher) this, this); addtask(task); notifyEvent("clientTaskId", new Integer(task.getId())); } else { @@ -423,7 +455,7 @@ public class I2PTunnel implements Logging, EventDispatcher { proxy = args[1]; } I2PTunnelTask task; - task = new I2PTunnelHTTPClient(port, l, ownDest, proxy, (EventDispatcher) this); + task = new I2PTunnelHTTPClient(port, l, ownDest, proxy, (EventDispatcher) this, this); addtask(task); notifyEvent("httpclientTaskId", new Integer(task.getId())); } else { @@ -460,7 +492,7 @@ public class I2PTunnel implements Logging, EventDispatcher { } I2PTunnelTask task; - task = new I2PSOCKSTunnel(port, l, ownDest, (EventDispatcher) this); + task = new I2PSOCKSTunnel(port, l, ownDest, (EventDispatcher) this, this); addtask(task); notifyEvent("sockstunnelTaskId", new Integer(task.getId())); } else { @@ -779,7 +811,7 @@ public class I2PTunnel implements Logging, EventDispatcher { if (allargs.length() != 0) { I2PTunnelTask task; // pings always use the main destination - task = new I2Ping(allargs, l, false, (EventDispatcher) this); + task = new I2Ping(allargs, l, false, (EventDispatcher) this, this); addtask(task); notifyEvent("pingTaskId", new Integer(task.getId())); } else { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java index 3f7b2e12e..ab62413fd 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java @@ -19,8 +19,8 @@ public class I2PTunnelClient extends I2PTunnelClientBase { private static final long DEFAULT_READ_TIMEOUT = 5*60*1000; // -1 protected long readTimeout = DEFAULT_READ_TIMEOUT; - public I2PTunnelClient(int localPort, String destination, Logging l, boolean ownDest, EventDispatcher notifyThis) { - super(localPort, ownDest, l, notifyThis, "SynSender"); + public I2PTunnelClient(int localPort, String destination, Logging l, boolean ownDest, EventDispatcher notifyThis, I2PTunnel tunnel) { + super(localPort, ownDest, l, notifyThis, "SynSender", tunnel); if (waitEventValue("openBaseClientResult").equals("error")) { notifyEvent("openClientResult", "error"); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java index 0deb8ae51..5a2c3ea04 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java @@ -60,8 +60,8 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna // I2PTunnelClientBase(localPort, ownDest, l, (EventDispatcher)null); //} - public I2PTunnelClientBase(int localPort, boolean ownDest, Logging l, EventDispatcher notifyThis, String handlerName) { - super(localPort + " (uninitialized)", notifyThis); + public I2PTunnelClientBase(int localPort, boolean ownDest, Logging l, EventDispatcher notifyThis, String handlerName, I2PTunnel tunnel) { + super(localPort + " (uninitialized)", notifyThis, tunnel); _clientId = ++__clientId; this.localPort = localPort; this.l = l; @@ -103,16 +103,25 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna private static I2PSocketManager socketManager; - protected static synchronized I2PSocketManager getSocketManager() { + protected synchronized I2PSocketManager getSocketManager() { + return getSocketManager(getTunnel()); + } + protected static synchronized I2PSocketManager getSocketManager(I2PTunnel tunnel) { if (socketManager == null) { - socketManager = buildSocketManager(); + socketManager = buildSocketManager(tunnel); } return socketManager; } - protected static I2PSocketManager buildSocketManager() { + protected I2PSocketManager buildSocketManager() { + return buildSocketManager(getTunnel()); + } + protected static I2PSocketManager buildSocketManager(I2PTunnel tunnel) { Properties props = new Properties(); - props.putAll(System.getProperties()); + if (tunnel == null) + props.putAll(System.getProperties()); + else + props.putAll(tunnel.getClientOptions()); I2PSocketManager sockManager = I2PSocketManagerFactory.createManager(I2PTunnel.host, Integer.parseInt(I2PTunnel.port), props); sockManager.setName("Client"); return sockManager; diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java index 30c3a0d67..98aa290e4 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java @@ -81,8 +81,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable /** used to assign unique IDs to the threads / clients. no logic or functionality */ private static volatile long __clientId = 0; - public I2PTunnelHTTPClient(int localPort, Logging l, boolean ownDest, String wwwProxy, EventDispatcher notifyThis) { - super(localPort, ownDest, l, notifyThis, "HTTPHandler " + (++__clientId)); + public I2PTunnelHTTPClient(int localPort, Logging l, boolean ownDest, String wwwProxy, EventDispatcher notifyThis, I2PTunnel tunnel) { + super(localPort, ownDest, l, notifyThis, "HTTPHandler " + (++__clientId), tunnel); if (waitEventValue("openBaseClientResult").equals("error")) { notifyEvent("openHTTPClientResult", "error"); @@ -127,7 +127,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable if (pos == -1) break; method = line.substring(0, pos); String request = line.substring(pos + 1); - if (request.startsWith("/") && System.getProperty("i2ptunnel.noproxy") != null) { + if (request.startsWith("/") && getTunnel().getClientOptions().getProperty("i2ptunnel.noproxy") != null) { request = "http://i2p" + request; } pos = request.indexOf("//"); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java index 5b9f8eb52..9b0e2b0a0 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java @@ -45,15 +45,15 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { /** default timeout to 3 minutes - override if desired */ private long readTimeout = DEFAULT_READ_TIMEOUT; - public I2PTunnelServer(InetAddress host, int port, String privData, Logging l, EventDispatcher notifyThis) { - super(host + ":" + port + " <- " + privData, notifyThis); + public I2PTunnelServer(InetAddress host, int port, String privData, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) { + super(host + ":" + port + " <- " + privData, notifyThis, tunnel); ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(privData)); init(host, port, bais, privData, l); } public I2PTunnelServer(InetAddress host, int port, File privkey, String privkeyname, Logging l, - EventDispatcher notifyThis) { - super(host + ":" + port + " <- " + privkeyname, notifyThis); + EventDispatcher notifyThis, I2PTunnel tunnel) { + super(host + ":" + port + " <- " + privkeyname, notifyThis, tunnel); try { init(host, port, new FileInputStream(privkey), privkeyname, l); } catch (IOException ioe) { @@ -62,8 +62,8 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { } } - public I2PTunnelServer(InetAddress host, int port, InputStream privData, String privkeyname, Logging l, EventDispatcher notifyThis) { - super(host + ":" + port + " <- " + privkeyname, notifyThis); + public I2PTunnelServer(InetAddress host, int port, InputStream privData, String privkeyname, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) { + super(host + ":" + port + " <- " + privkeyname, notifyThis, tunnel); init(host, port, privData, privkeyname, l); } @@ -73,7 +73,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { this.remotePort = port; I2PClient client = I2PClientFactory.createClient(); Properties props = new Properties(); - props.putAll(System.getProperties()); + props.putAll(getTunnel().getClientOptions()); synchronized (slock) { sockMgr = I2PSocketManagerFactory.createManager(privData, I2PTunnel.host, Integer.parseInt(I2PTunnel.port), props); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelTask.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelTask.java index 24657a7a1..9faf82ad4 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelTask.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelTask.java @@ -26,16 +26,19 @@ public abstract class I2PTunnelTask implements EventDispatcher { // I2PTunnelTask(name, (EventDispatcher)null); //} - protected I2PTunnelTask(String name, EventDispatcher notifyThis) { + protected I2PTunnelTask(String name, EventDispatcher notifyThis, I2PTunnel tunnel) { attachEventDispatcher(notifyThis); this.name = name; this.id = -1; + this.tunnel = tunnel; } /** for apps that use multiple I2PTunnel instances */ public void setTunnel(I2PTunnel pTunnel) { tunnel = pTunnel; } + + public I2PTunnel getTunnel() { return tunnel; } public int getId() { return this.id; diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java index 5061800ec..d53eed17a 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java @@ -47,15 +47,15 @@ public class I2Ping extends I2PTunnelTask implements Runnable { // I2Ping(cmd, l, (EventDispatcher)null); //} - public I2Ping(String cmd, Logging l, boolean ownDest, EventDispatcher notifyThis) { - super("I2Ping [" + cmd + "]", notifyThis); + public I2Ping(String cmd, Logging l, boolean ownDest, EventDispatcher notifyThis, I2PTunnel tunnel) { + super("I2Ping [" + cmd + "]", notifyThis, tunnel); this.l = l; command = cmd; synchronized (slock) { if (ownDest) { - sockMgr = I2PTunnelClient.buildSocketManager(); + sockMgr = I2PTunnelClient.buildSocketManager(tunnel); } else { - sockMgr = I2PTunnelClient.getSocketManager(); + sockMgr = I2PTunnelClient.getSocketManager(tunnel); } } Thread t = new I2PThread(this); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/I2PSOCKSTunnel.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/I2PSOCKSTunnel.java index 264eda1ef..628e415f0 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/I2PSOCKSTunnel.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/I2PSOCKSTunnel.java @@ -10,6 +10,7 @@ import java.net.Socket; import net.i2p.client.streaming.I2PSocket; import net.i2p.data.Destination; +import net.i2p.i2ptunnel.I2PTunnel; import net.i2p.i2ptunnel.I2PTunnelClientBase; import net.i2p.i2ptunnel.I2PTunnelRunner; import net.i2p.i2ptunnel.Logging; @@ -26,8 +27,8 @@ public class I2PSOCKSTunnel extends I2PTunnelClientBase { // I2PSOCKSTunnel(localPort, l, ownDest, (EventDispatcher)null); //} - public I2PSOCKSTunnel(int localPort, Logging l, boolean ownDest, EventDispatcher notifyThis) { - super(localPort, ownDest, l, notifyThis, "SOCKSHandler"); + public I2PSOCKSTunnel(int localPort, Logging l, boolean ownDest, EventDispatcher notifyThis, I2PTunnel tunnel) { + super(localPort, ownDest, l, notifyThis, "SOCKSHandler", tunnel); if (waitEventValue("openBaseClientResult").equals("error")) { notifyEvent("openSOCKSTunnelResult", "error");