diff --git a/apps/BOB/nbproject/private/private.xml b/apps/BOB/nbproject/private/private.xml index c1f155a78..ccaab1e5c 100644 --- a/apps/BOB/nbproject/private/private.xml +++ b/apps/BOB/nbproject/private/private.xml @@ -1,4 +1,7 @@ + + file:/usblv/NetBeansProjects/i2p.i2p/apps/BOB/src/net/i2p/BOB/BOB.java + diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index 655282922..51c9373b0 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -561,7 +561,7 @@ public class SnarkManager implements Snark.CompleteListener { if ( (files != null) && (files.size() > MAX_FILES_PER_TORRENT) ) { return _("Too many files in \"{0}\" ({1}), deleting it!", info.getName(), files.size()); } else if ( (files == null) && (info.getName().endsWith(".torrent")) ) { - return _("Torrent file \"{0}\" cannot end in '.torrent', deleting it!", info.getName()); + return _("Torrent file \"{0}\" cannot end in \".torrent\", deleting it!", info.getName()); } else if (info.getPieces() <= 0) { return _("No pieces in \"{0}\", deleting it!", info.getName()); } else if (info.getPieces() > Storage.MAX_PIECES) { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/BufferLogger.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/BufferLogger.java deleted file mode 100644 index 80d1fd054..000000000 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/BufferLogger.java +++ /dev/null @@ -1,72 +0,0 @@ -/* I2PTunnel is GPL'ed (with the exception mentioned in I2PTunnel.java) - * (c) 2003 - 2004 mihi - */ -package net.i2p.i2ptunnel; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import net.i2p.util.Log; - -/** - * Read what i2ptunnel logs, and expose it in a buffer - * - */ -class BufferLogger implements Logging { - private final static Log _log = new Log(BufferLogger.class); - private ByteArrayOutputStream _baos; // FIXME should be final and use a factory. FIXME - private boolean _ignore; - - /** - * Constructs a buffered logger. - */ - public BufferLogger() { - _baos = new ByteArrayOutputStream(512); - _ignore = false; - } - - private final static String EMPTY = ""; - - /** - * Retrieves the buffer - * @return the buffer - */ - public String getBuffer() { - if (_ignore) - return EMPTY; - - return new String(_baos.toByteArray()); - } - - /** - * We don't care about anything else the logger receives. This is useful - * for loggers passed in to servers and clients, since they will continue - * to add info to the logger, but if we're instantiated by the tunnel manager, - * its likely we only care about the first few messages it sends us. - * - */ - public void ignoreFurtherActions() { - _ignore = true; - synchronized (_baos) { - _baos.reset(); - } - _baos = null; - } - - /** - * Pass in some random data - * @param s String containing what we're logging. - */ - public void log(String s) { - if (_ignore) return; - if (s != null) { - _log.debug("logging [" + s + "]"); - try { - _baos.write(s.getBytes()); - _baos.write('\n'); - } catch (IOException ioe) { - _log.error("Error logging [" + s + "]"); - } - } - } -} \ No newline at end of file diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java index 0b2d2d7c0..bfe311d3c 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java @@ -236,6 +236,8 @@ public class I2PTunnel implements Logging, EventDispatcher { runServer(args, l); } else if ("httpserver".equals(cmdname)) { runHttpServer(args, l); + } else if ("httpbidirserver".equals(cmdname)) { + runHttpBidirServer(args, l); } else if ("ircserver".equals(cmdname)) { runIrcServer(args, l); } else if ("textserver".equals(cmdname)) { @@ -300,6 +302,7 @@ public class I2PTunnel implements Logging, EventDispatcher { l.log("ping "); l.log("server "); l.log("httpserver "); + l.log("httpbidirserver "); l.log("textserver "); l.log("genkeys []"); l.log("gentextkeys"); @@ -503,6 +506,80 @@ public class I2PTunnel implements Logging, EventDispatcher { } } + /** + * Run the HTTP server pointing at the host and port specified using the private i2p + * destination loaded from the specified file, replacing the HTTP headers + * so that the Host: specified is the one spoofed. Also runs an HTTP proxy for + * bidirectional communications on the same tunnel destination.

+ * + * Sets the event "serverTaskId" = Integer(taskId) after the tunnel has been started (or -1 on error) + * Also sets the event "openServerResult" = "ok" or "error" (displaying "Ready!" on the logger after + * 'ok'). So, success = serverTaskId != -1 and openServerResult = ok. + * + * @param args {hostname, portNumber, proxyPortNumber, spoofedHost, privKeyFilename} + * @param l logger to receive events and output + */ + public void runHttpBidirServer(String args[], Logging l) { + if (args.length == 5) { + InetAddress serverHost = null; + int portNum = -1; + int port2Num = -1; + File privKeyFile = null; + try { + serverHost = InetAddress.getByName(args[0]); + } catch (UnknownHostException uhe) { + l.log("unknown host"); + _log.error(getPrefix() + "Error resolving " + args[0], uhe); + notifyEvent("serverTaskId", Integer.valueOf(-1)); + return; + } + + try { + portNum = Integer.parseInt(args[1]); + } catch (NumberFormatException nfe) { + l.log("invalid port"); + _log.error(getPrefix() + "Port specified is not valid: " + args[1], nfe); + notifyEvent("serverTaskId", Integer.valueOf(-1)); + return; + } + + try { + port2Num = Integer.parseInt(args[2]); + } catch (NumberFormatException nfe) { + l.log("invalid port"); + _log.error(getPrefix() + "Port specified is not valid: " + args[2], nfe); + notifyEvent("serverTaskId", Integer.valueOf(-1)); + return; + } + + String spoofedHost = args[3]; + + privKeyFile = new File(args[4]); + if (!privKeyFile.isAbsolute()) + privKeyFile = new File(_context.getConfigDir(), args[4]); + if (!privKeyFile.canRead()) { + l.log("private key file does not exist"); + _log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[4]); + notifyEvent("serverTaskId", Integer.valueOf(-1)); + return; + } + + I2PTunnelHTTPBidirServer serv = new I2PTunnelHTTPBidirServer(serverHost, portNum, port2Num, privKeyFile, args[3], spoofedHost, l, (EventDispatcher) this, this); + serv.setReadTimeout(readTimeout); + serv.startRunning(); + addtask(serv); + notifyEvent("serverTaskId", Integer.valueOf(serv.getId())); + return; + } else { + l.log("httpserver "); + l.log(" creates a bidirectional HTTP server that sends all incoming data\n" + + " of its destination to host:port., filtering the HTTP\n" + + " headers so it looks like the request is to the spoofed host," + + " and listens to host:proxyport to proxy HTTP requests."); + notifyEvent("serverTaskId", Integer.valueOf(-1)); + } + } + /** * Run the server pointing at the host and port specified using the private i2p * destination loaded from the given base64 stream.

diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java index a7197a006..b3ffcdb45 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java @@ -67,7 +67,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna // private Object conLock = new Object(); /** List of Socket for those accept()ed but not yet started up */ - private List _waitingSockets = new ArrayList(); // FIXME should be final and use a factory. FIXME + protected final List _waitingSockets = new ArrayList(4); // FIXME should be final and use a factory. FIXME /** 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? */ @@ -89,12 +89,52 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna private static final int DEFAULT_NUM_CONNECTION_BUILDERS = 5; private static final int DEFAULT_MAX_WAIT_TIME = 30*1000; - - //public I2PTunnelClientBase(int localPort, boolean ownDest, - // Logging l) { - // I2PTunnelClientBase(localPort, ownDest, l, (EventDispatcher)null); - //} + // true if we are chained from a server. + private boolean chained = false; + + public I2PTunnelClientBase(int localPort, Logging l, I2PSocketManager sktMgr, + I2PTunnel tunnel, EventDispatcher notifyThis, long clientId ) + throws IllegalArgumentException { + super(localPort + " (uninitialized)", notifyThis, tunnel); + chained = true; + sockMgr = sktMgr; + _clientId = clientId; + this.localPort = localPort; + this.l = l; + this.handlerName = handlerName + _clientId; + _ownDest = true; // == ! shared client + _context = tunnel.getContext(); + _context.statManager().createRateStat("i2ptunnel.client.closeBacklog", "How many pending sockets remain when we close one due to backlog?", "I2PTunnel", new long[] { 60*1000, 10*60*1000, 60*60*1000 }); + _context.statManager().createRateStat("i2ptunnel.client.closeNoBacklog", "How many pending sockets remain when it was removed prior to backlog timeout?", "I2PTunnel", new long[] { 60*1000, 10*60*1000, 60*60*1000 }); + _context.statManager().createRateStat("i2ptunnel.client.manageTime", "How long it takes to accept a socket and fire it into an i2ptunnel runner (or queue it for the pool)?", "I2PTunnel", new long[] { 60*1000, 10*60*1000, 60*60*1000 }); + _context.statManager().createRateStat("i2ptunnel.client.buildRunTime", "How long it takes to run a queued socket into an i2ptunnel runner?", "I2PTunnel", new long[] { 60*1000, 10*60*1000, 60*60*1000 }); + + Thread t = new I2PAppThread(this); + t.setName("Client " + _clientId); + listenerReady = false; + t.start(); + open = true; + synchronized (this) { + while (!listenerReady && open) { + try { + wait(); + } catch (InterruptedException e) { + // ignore + } + } + } + + configurePool(tunnel); + + if (open && listenerReady) { + l.log("Ready! Port " + getLocalPort()); + notifyEvent("openBaseClientResult", "ok"); + } else { + l.log("Error listening - please see the logs!"); + notifyEvent("openBaseClientResult", "error"); + } + } public I2PTunnelClientBase(int localPort, boolean ownDest, Logging l, EventDispatcher notifyThis, String handlerName, I2PTunnel tunnel) throws IllegalArgumentException { @@ -188,7 +228,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna * */ private void configurePool(I2PTunnel tunnel) { - _waitingSockets = new ArrayList(4); + //_waitingSockets = new ArrayList(4); Properties opts = tunnel.getClientOptions(); String maxWait = opts.getProperty(PROP_MAX_WAIT_TIME, DEFAULT_MAX_WAIT_TIME+""); @@ -559,10 +599,12 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna } return false; } - I2PSession session = sockMgr.getSession(); - if (session != null) { - getTunnel().removeSession(session); - } + if (!chained) { + I2PSession session = sockMgr.getSession(); + if (session != null) { + getTunnel().removeSession(session); + } + } // else the app chaining to this one closes it! } l.log("Closing client " + toString()); open = false; diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPBidirProxy.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPBidirProxy.java new file mode 100644 index 000000000..8c188d115 --- /dev/null +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPBidirProxy.java @@ -0,0 +1,54 @@ +/** + * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + * Version 2, December 2004 + * + * Copyright (C) sponge + * Planet Earth + * Everyone is permitted to copy and distribute verbatim or modified + * copies of this license document, and changing it is allowed as long + * as the name is changed. + * + * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + * TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + * + * 0. You just DO WHAT THE FUCK YOU WANT TO. + * + * See... + * + * http://sam.zoy.org/wtfpl/ + * and + * http://en.wikipedia.org/wiki/WTFPL + * + * ...for any additional details and liscense questions. + */ + +package net.i2p.i2ptunnel; + +// import java.util.ArrayList; + +import net.i2p.client.streaming.I2PSocketManager; +import net.i2p.util.EventDispatcher; + + +/** + * Reuse HTTP server's I2PSocketManager for a proxy with no outproxy capability. + * + * @author sponge + */ +public class I2PTunnelHTTPBidirProxy extends I2PTunnelHTTPClient implements Runnable { + + + /** + * @throws IllegalArgumentException if the I2PTunnel does not contain + * valid config to contact the router + */ + public I2PTunnelHTTPBidirProxy(int localPort, Logging l, I2PSocketManager sockMgr, I2PTunnel tunnel, EventDispatcher notifyThis, long clientId) { + super(localPort, l, sockMgr, tunnel, notifyThis, clientId); + // proxyList = new ArrayList(); + + setName(getLocalPort() + " -> HTTPClient [NO PROXIES]"); + startRunning(); + + notifyEvent("openHTTPClientResult", "ok"); + } +} diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPBidirServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPBidirServer.java new file mode 100644 index 000000000..54b2046cf --- /dev/null +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPBidirServer.java @@ -0,0 +1,44 @@ +/* I2PTunnel is GPL'ed (with the exception mentioned in I2PTunnel.java) + * (c) 2003 - 2004 mihi + */ +package net.i2p.i2ptunnel; + +import java.io.File; +import java.io.InputStream; +import java.net.InetAddress; + +import net.i2p.util.EventDispatcher; +import net.i2p.util.Log; + +public class I2PTunnelHTTPBidirServer extends I2PTunnelHTTPServer { + private final static Log log = new Log(I2PTunnelHTTPBidirServer.class); + + public I2PTunnelHTTPBidirServer(InetAddress host, int port, int proxyport, String privData, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) { + super(host, port, privData, spoofHost, l, notifyThis, tunnel); + finishSetupI2PTunnelHTTPBidirServer(l, proxyport); + } + + public I2PTunnelHTTPBidirServer(InetAddress host, int port, int proxyport, File privkey, String privkeyname, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) { + super(host, port, privkey, privkeyname, spoofHost, l, notifyThis, tunnel); + finishSetupI2PTunnelHTTPBidirServer(l, proxyport); + } + + public I2PTunnelHTTPBidirServer(InetAddress host, int port, int proxyport, InputStream privData, String privkeyname, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) { + super(host, port, privData, privkeyname, spoofHost, l, notifyThis, tunnel); + finishSetupI2PTunnelHTTPBidirServer(l, proxyport); + } + + private void finishSetupI2PTunnelHTTPBidirServer(Logging l, int proxyport) { + + localPort = proxyport; + bidir = true; + + /* start the httpclient */ + task = new I2PTunnelHTTPBidirProxy(localPort, l, sockMgr, getTunnel(), getEventDispatcher(), __serverId); + sockMgr.setName("Server"); // TO-DO: Need to change this to "Bidir"! + getTunnel().addSession(sockMgr.getSession()); + l.log("Ready!"); + notifyEvent("openServerResult", "ok"); + } +} + diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java index 3598ac05c..a86e01c65 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java @@ -24,6 +24,7 @@ import java.util.StringTokenizer; import net.i2p.I2PAppContext; import net.i2p.I2PException; import net.i2p.client.streaming.I2PSocket; +import net.i2p.client.streaming.I2PSocketManager; import net.i2p.client.streaming.I2PSocketOptions; import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; @@ -56,7 +57,7 @@ import net.i2p.util.Translate; public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable { private static final Log _log = new Log(I2PTunnelHTTPClient.class); - private final List proxyList; + protected final List proxyList = new ArrayList(); private HashMap addressHelpers = new HashMap(); @@ -150,7 +151,15 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable private static final File _errorDir = new File(I2PAppContext.getGlobalContext().getBaseDir(), "docs"); + public I2PTunnelHTTPClient(int localPort, Logging l, I2PSocketManager sockMgr, I2PTunnel tunnel, EventDispatcher notifyThis, long clientId) { + super(localPort, l, sockMgr, tunnel, notifyThis, clientId); + // proxyList = new ArrayList(); + setName(getLocalPort() + " -> HTTPClient [NO PROXIES]"); + startRunning(); + + notifyEvent("openHTTPClientResult", "ok"); + } /** * @throws IllegalArgumentException if the I2PTunnel does not contain * valid config to contact the router @@ -160,7 +169,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable I2PTunnel tunnel) throws IllegalArgumentException { super(localPort, ownDest, l, notifyThis, "HTTPHandler " + (++__clientId), tunnel); - proxyList = new ArrayList(); + //proxyList = new ArrayList(); // We won't use outside of i2p if (waitEventValue("openBaseClientResult").equals("error")) { notifyEvent("openHTTPClientResult", "error"); return; @@ -251,6 +260,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable /** * Overridden to close internal socket too. */ + @Override public boolean close(boolean forced) { boolean rv = super.close(forced); if (this.isr != null) diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java index af9f1c1ec..d23185780 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java @@ -39,21 +39,21 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer { public I2PTunnelHTTPServer(InetAddress host, int port, String privData, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) { super(host, port, privData, l, notifyThis, tunnel); - _spoofHost = spoofHost; - getTunnel().getContext().statManager().createRateStat("i2ptunnel.httpserver.blockingHandleTime", "how long the blocking handle takes to complete", "I2PTunnel", new long[] { 60*1000, 10*60*1000, 3*60*60*1000 }); - getTunnel().getContext().statManager().createRateStat("i2ptunnel.httpNullWorkaround", "How often an http server works around a streaming lib or i2ptunnel bug", "I2PTunnel", new long[] { 60*1000, 10*60*1000 }); + setupI2PTunnelHTTPServer(spoofHost); } public I2PTunnelHTTPServer(InetAddress host, int port, File privkey, String privkeyname, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) { super(host, port, privkey, privkeyname, l, notifyThis, tunnel); - _spoofHost = spoofHost; - getTunnel().getContext().statManager().createRateStat("i2ptunnel.httpserver.blockingHandleTime", "how long the blocking handle takes to complete", "I2PTunnel.HTTPServer", new long[] { 60*1000, 10*60*1000, 3*60*60*1000 }); - getTunnel().getContext().statManager().createRateStat("i2ptunnel.httpNullWorkaround", "How often an http server works around a streaming lib or i2ptunnel bug", "I2PTunnel.HTTPServer", new long[] { 60*1000, 10*60*1000 }); + setupI2PTunnelHTTPServer(spoofHost); } public I2PTunnelHTTPServer(InetAddress host, int port, InputStream privData, String privkeyname, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) { super(host, port, privData, privkeyname, l, notifyThis, tunnel); - _spoofHost = spoofHost; + setupI2PTunnelHTTPServer(spoofHost); + } + + private void setupI2PTunnelHTTPServer(String spoofHost) { + _spoofHost = spoofHost; getTunnel().getContext().statManager().createRateStat("i2ptunnel.httpserver.blockingHandleTime", "how long the blocking handle takes to complete", "I2PTunnel.HTTPServer", new long[] { 60*1000, 10*60*1000, 3*60*60*1000 }); getTunnel().getContext().statManager().createRateStat("i2ptunnel.httpNullWorkaround", "How often an http server works around a streaming lib or i2ptunnel bug", "I2PTunnel.HTTPServer", new long[] { 60*1000, 10*60*1000 }); } diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java index 2471fcc50..ff21c27c4 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java @@ -48,26 +48,29 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { protected long readTimeout = DEFAULT_READ_TIMEOUT; private static final boolean DEFAULT_USE_POOL = false; - + protected static volatile long __serverId = 0; + private static final String PROP_HANDLER_COUNT = "i2ptunnel.blockingHandlerCount"; + private static final int DEFAULT_HANDLER_COUNT = 10; + + + + protected I2PTunnelTask task = null; + protected boolean bidir = false; + + private int DEFAULT_LOCALPORT = 4488; + protected int localPort = DEFAULT_LOCALPORT; + 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)); - String usePool = tunnel.getClientOptions().getProperty("i2ptunnel.usePool"); - if (usePool != null) - _usePool = "true".equalsIgnoreCase(usePool); - else - _usePool = DEFAULT_USE_POOL; + SetUsePool(tunnel); init(host, port, bais, privData, l); } public I2PTunnelServer(InetAddress host, int port, File privkey, String privkeyname, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) { super(host + ":" + port + " <- " + privkeyname, notifyThis, tunnel); - String usePool = tunnel.getClientOptions().getProperty("i2ptunnel.usePool"); - if (usePool != null) - _usePool = "true".equalsIgnoreCase(usePool); - else - _usePool = DEFAULT_USE_POOL; + SetUsePool(tunnel); FileInputStream fis = null; try { fis = new FileInputStream(privkey); @@ -83,14 +86,18 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { public I2PTunnelServer(InetAddress host, int port, InputStream privData, String privkeyname, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) { super(host + ":" + port + " <- " + privkeyname, notifyThis, tunnel); - String usePool = tunnel.getClientOptions().getProperty("i2ptunnel.usePool"); + SetUsePool(tunnel); + init(host, port, privData, privkeyname, l); + } + + + private void SetUsePool(I2PTunnel Tunnel) { + String usePool = Tunnel.getClientOptions().getProperty("i2ptunnel.usePool"); if (usePool != null) _usePool = "true".equalsIgnoreCase(usePool); else _usePool = DEFAULT_USE_POOL; - init(host, port, privData, privkeyname, l); } - private void init(InetAddress host, int port, InputStream privData, String privkeyname, Logging l) { this.l = l; this.remoteHost = host; @@ -117,6 +124,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { try { Thread.sleep(10*1000); } catch (InterruptedException ie) {} } } + sockMgr.setName("Server"); getTunnel().addSession(sockMgr.getSession()); l.log("Ready!"); @@ -125,8 +133,6 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { } - private static volatile long __serverId = 0; - /** * Start running the I2PTunnelServer. * @@ -158,6 +164,9 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { public boolean close(boolean forced) { if (!open) return true; + if (task != null) { + task.close(forced); + } synchronized (lock) { if (!forced && sockMgr.listSockets().size() != 0) { l.log("There are still active connections!"); @@ -181,9 +190,6 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { } } - private static final String PROP_HANDLER_COUNT = "i2ptunnel.blockingHandlerCount"; - private static final int DEFAULT_HANDLER_COUNT = 10; - protected int getHandlerCount() { int rv = DEFAULT_HANDLER_COUNT; String cnt = getTunnel().getClientOptions().getProperty(PROP_HANDLER_COUNT); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java index 06beffae5..4084b702c 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java @@ -154,6 +154,8 @@ public class TunnelController implements Logging { startServer(); } else if ("httpserver".equals(type)) { startHttpServer(); + } else if ("httpbidirserver".equals(type)) { + startHttpBidirServer(); } else if ("ircserver".equals(type)) { startIrcServer(); } else if ("streamrserver".equals(type)) { @@ -294,6 +296,16 @@ public class TunnelController implements Logging { _tunnel.runHttpServer(new String[] { targetHost, targetPort, spoofedHost, privKeyFile }, this); } + private void startHttpBidirServer() { + setListenOn(); + String targetHost = getTargetHost(); + String targetPort = getTargetPort(); + String listenPort = getListenPort(); + String spoofedHost = getSpoofedHost(); + String privKeyFile = getPrivKeyFile(); + _tunnel.runHttpBidirServer(new String[] { targetHost, targetPort, listenPort, spoofedHost, privKeyFile }, this); + } + private void startIrcServer() { String targetHost = getTargetHost(); String targetPort = getTargetPort(); 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 b1abd47e1..695e0e25a 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/Pinger.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/streamr/Pinger.java @@ -16,7 +16,7 @@ public class Pinger implements Source, Runnable { public void start() { this.running = true; - this.waitlock = new Object(); + //this.waitlock = new Object(); this.thread.start(); } @@ -54,6 +54,6 @@ public class Pinger implements Source, Runnable { protected Sink sink; protected Thread thread; - protected Object waitlock; // FIXME should be final and use a factory. FIXME + private final Object waitlock = new Object(); protected boolean running; } 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 6d8737f48..c0e4c6693 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udp/I2PSink.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udp/I2PSink.java @@ -29,7 +29,7 @@ public class I2PSink implements Sink { // create maker if (!raw) - this.maker = new I2PDatagramMaker(this.sess); + this.maker.setI2PDatagramMaker(this.sess); } /** @param src ignored */ @@ -54,20 +54,8 @@ public class I2PSink implements Sink { } } - - - - - - - - - - - - protected boolean raw; protected I2PSession sess; protected Destination dest; - protected I2PDatagramMaker maker; // FIXME should be final and use a factory. FIXME + protected final I2PDatagramMaker maker= new I2PDatagramMaker(); // FIXME should be final and use a factory. FIXME } 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 143422ce4..a2793e7dd 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udp/I2PSinkAnywhere.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udp/I2PSinkAnywhere.java @@ -28,7 +28,7 @@ public class I2PSinkAnywhere implements Sink { // create maker if (!raw) - this.maker = new I2PDatagramMaker(this.sess); + this.maker.setI2PDatagramMaker(this.sess); } /** @param to - where it's going */ @@ -52,20 +52,8 @@ public class I2PSinkAnywhere implements Sink { } } - - - - - - - - - - - - protected boolean raw; protected I2PSession sess; protected Destination dest; - protected I2PDatagramMaker maker; // FIXME should be final and use a factory. FIXME + protected final I2PDatagramMaker maker = new I2PDatagramMaker(); } diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java index 6951286dc..ac1f7c77f 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java @@ -389,6 +389,7 @@ public class IndexBean { else if ("ircserver".equals(internalType)) return _("IRC server"); else if ("streamrclient".equals(internalType)) return _("Streamr client"); else if ("streamrserver".equals(internalType)) return _("Streamr server"); + else if ("httpbidirserver".equals(internalType)) return _("HTTP bidir"); else return internalType; } @@ -779,8 +780,11 @@ public class IndexBean { config.setProperty("listenPort", _port); if (_reachableByOther != null) config.setProperty("interface", _reachableByOther); - else + else if (_reachableBy != null) config.setProperty("interface", _reachableBy); + else + config.setProperty("interface", ""); + config.setProperty("sharedClient", _sharedClient + ""); for (String p : _booleanClientOpts) config.setProperty("option." + p, "" + _booleanOptions.contains(p)); @@ -806,11 +810,22 @@ public class IndexBean { } else if ("ircclient".equals(_type) || "client".equals(_type) || "streamrclient".equals(_type)) { if (_targetDestination != null) config.setProperty("targetDestination", _targetDestination); - } else if ("httpserver".equals(_type)) { + } else if ("httpserver".equals(_type) || "httpbidirserver".equals(_type)) { if (_spoofedHost != null) config.setProperty("spoofedHost", _spoofedHost); } - + if ("httpbidirserver".equals(_type)) { + if (_port != null) + config.setProperty("listenPort", _port); + if (_reachableByOther != null) + config.setProperty("interface", _reachableByOther); + else if (_reachableBy != null) + config.setProperty("interface", _reachableBy); + else if (_targetHost != null) + config.setProperty("interface", _targetHost); + else + config.setProperty("interface", ""); + } return config; } diff --git a/apps/i2ptunnel/jsp/editServer.jsp b/apps/i2ptunnel/jsp/editServer.jsp index 24f6b0d03..90a7614f2 100644 --- a/apps/i2ptunnel/jsp/editServer.jsp +++ b/apps/i2ptunnel/jsp/editServer.jsp @@ -113,11 +113,58 @@ + <% if ("httpbidirserver".equals(tunnelType)) { + %> +

+
+
+
+ +
+
+ + +
+ <% String otherInterface = ""; + String clientInterface = editBean.getClientInterface(curTunnel); + %> +
+ + +
+
+ + +
+ <% } %>

- <% if ("httpserver".equals(tunnelType)) { + <% if (("httpserver".equals(tunnelType)) || ("httpbidirserver".equals(tunnelType))) { %>