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/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java index a7197a006..535e1d2b9 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java @@ -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 MGR, + I2PTunnel tunnel, EventDispatcher notifyThis, long clientId ) + throws IllegalArgumentException { + super(localPort + " (uninitialized)", notifyThis, tunnel); + chained = true; + sockMgr = MGR; + _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 { @@ -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/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java index 3598ac05c..a01f30664 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; @@ -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/I2PTunnelServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java index 2471fcc50..455856448 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java @@ -48,7 +48,13 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { protected long readTimeout = DEFAULT_READ_TIMEOUT; private static final boolean DEFAULT_USE_POOL = false; - + + private I2PTunnelTask task = null; + private boolean bidir = false; + private int localPort = 4445; + + private int DEFAULT_LOCALPORT = 4445; + 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)); @@ -57,6 +63,16 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { _usePool = "true".equalsIgnoreCase(usePool); else _usePool = DEFAULT_USE_POOL; + String biDir = tunnel.getClientOptions().getProperty("i2ptunnel.bidir"); + if (biDir != null) { + bidir = "true".equalsIgnoreCase(biDir); + String lp = tunnel.getClientOptions().getProperty("i2ptunnel.bidir.port"); + if (lp != null) + localPort = Integer.parseInt(lp); + else + localPort = DEFAULT_LOCALPORT; + } else + bidir = false; init(host, port, bais, privData, l); } @@ -68,6 +84,11 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { _usePool = "true".equalsIgnoreCase(usePool); else _usePool = DEFAULT_USE_POOL; + String biDir = tunnel.getClientOptions().getProperty("i2ptunnel.bidir"); + if (biDir != null) + bidir = "true".equalsIgnoreCase(biDir); + else + bidir = false; FileInputStream fis = null; try { fis = new FileInputStream(privkey); @@ -88,9 +109,15 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { _usePool = "true".equalsIgnoreCase(usePool); else _usePool = DEFAULT_USE_POOL; + String biDir = tunnel.getClientOptions().getProperty("i2ptunnel.bidir"); + if (biDir != null) + bidir = "true".equalsIgnoreCase(biDir); + else + bidir = false; 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 +144,10 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { try { Thread.sleep(10*1000); } catch (InterruptedException ie) {} } } + if(bidir == true) { + /* start the httpclient */ + task = new I2PTunnelHTTPClient(localPort, l, sockMgr, getTunnel(), getEventDispatcher(), __serverId); + } sockMgr.setName("Server"); getTunnel().addSession(sockMgr.getSession()); l.log("Ready!"); @@ -158,6 +189,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!"); diff --git a/history.txt b/history.txt index fe338bdc3..218b53c02 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,7 @@ +2010-01-10 sponge + * Insert reverse connection ability into the http server code so that + seedless can start to get worked on. It's disabled by default. + 2010-01-09 zzz * Include new eepsite indexes in pkg diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 684de3214..2a0f94da6 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 18; + public final static long BUILD = 19; /** for example "-test" */ public final static String EXTRA = "-rc"; public final static String FULL_VERSION = VERSION + "-" + BUILD + EXTRA;