diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelManager.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelManager.java deleted file mode 100644 index 3b76c5e32c501088284f505c24cbb3a1c9926908..0000000000000000000000000000000000000000 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelManager.java +++ /dev/null @@ -1,445 +0,0 @@ -/* I2PTunnel is GPL'ed (with the exception mentioned in I2PTunnel.java) - * (c) 2003 - 2004 mihi - */ - -package net.i2p.i2ptunnel; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; - -import net.i2p.data.DataFormatException; -import net.i2p.data.Destination; -import net.i2p.util.Clock; -import net.i2p.util.I2PThread; -import net.i2p.util.Log; - -/** - * Quick and dirty socket listener to control an I2PTunnel. - * Basically run this class as TunnelManager [listenHost] [listenPort] and - * then send it commands on that port. Commands are one shot deals - - * Send a command + newline, get a response plus newline, then get disconnected. - * <p /> - * <b>Implemented commands:</b> - * <pre> - * ------------------------------------------------- - * lookup <name>\n - * -- - * <base64 of the destination>\n - * or - * <error message, usually 'Unknown host'>\n - * - * Lookup the public key of a named destination (i.e. listed in hosts.txt) - * ------------------------------------------------- - * genkey\n - * -- - * <base64 of the destination>\t<base64 of private data>\n - * - * Generates a new public and private key pair - * ------------------------------------------------- - * convertprivate <base64 of privkey> - * -- - * <base64 of destination>\n - * or - * <error message>\n - * - * Returns the destination (pubkey) of a given private key. - * ------------------------------------------------- - * listen_on <ip>\n - * -- - * ok\n - * or - * error\n - * - * Sets the ip address clients will listen on. By default this is the - * localhost (127.0.0.1) - * ------------------------------------------------- - * openclient <listenPort> <peer>[ <sharedClient>]\n - * -- - * ok [<jobId>]\n - * or - * ok <listenPort> [<jobId>]\n - * or - * error\n - * - * Open a tunnel on the given <listenport> to the destination specified - * by <peer>. If <listenPort> is 0 a free port is picked and returned in - * the reply message. Otherwise the short reply message is used. - * Peer can be the base64 of the destination, a file with the public key - * specified as 'file:<filename>' or the name of a destination listed in - * hosts.txt. The <jobId> returned together with "ok" and <listenport> can - * later be used as argument for the "close" command. - * <sharedClient> indicates if this httpclient shares tunnels with other - * clients or not (just use 'true' and 'false' - * ------------------------------------------------- - * openhttpclient <listenPort> [<sharedClient>] [<proxy>]\n - * -- - * ok [<jobId>]\n - * or - * ok <listenPort> [<jobId>]\n - * or - * error\n - * - * Open an HTTP proxy through the I2P on the given - * <listenport>. <proxy> (optional) specifies a - * destination to be used as an outbound proxy, to access normal WWW - * sites out of the .i2p domain. If <listenPort> is 0 a free - * port is picked and returned in the reply message. Otherwise the - * short reply message is used. <proxy> can be the base64 of the - * destination, a file with the public key specified as - * 'file:<filename>' or the name of a destination listed in - * hosts.txt. The <jobId> returned together with "ok" and - * <listenport> can later be used as argument for the "close" - * command. - * <sharedClient> indicates if this httpclient shares tunnels with other - * clients or not (just use 'true' and 'false' - * ------------------------------------------------- - * opensockstunnel <listenPort>\n - * -- - * ok [<jobId>]\n - * or - * ok <listenPort> [<jobId>]\n - * or - * error\n - * - * Open an SOCKS tunnel through the I2P on the given - * <listenport>. If <listenPort> is 0 a free port is - * picked and returned in the reply message. Otherwise the short - * reply message is used. The <jobId> returned together with - * "ok" and <listenport> can later be used as argument for the - * "close" command. - * ------------------------------------------------- - * openserver <serverHost> <serverPort> <serverKeys>\n - * -- - * ok [<jobId>]\n - * or - * error\n - * - * Starts receiving traffic for the destination specified by <serverKeys> - * and forwards it to the <serverPort> of <serverHost>. - * <serverKeys> is the base 64 encoded private key set of the local - * destination. The <joId> returned together with "ok" can later be used - * as argument for the "close" command. - * ------------------------------------------------- - * close [forced] <jobId>\n - * or - * close [forced] all\n - * -- - * ok\n - * or - * error\n - * - * Closes the job specified by <jobId> or all jobs. Use the list command - * for a list of running jobs. - * Normally a connection job is not closed when it still has an active - * connection. Use the optional 'forced' keyword to close connections - * regardless of their use. - * ------------------------------------------------- - * list\n - * -- - * Example output: - * - * [0] i2p.dnsalias.net/69.55.226.145:5555 <- C:\i2pKeys\squidPriv - * [1] 8767 -> HTTPClient - * [2] 7575 -> file:C:\i2pKeys\squidPub - * [3] 5252 -> sCcSANIO~f4AQtCNI1BvDp3ZBS~9Ag5O0k0Msm7XBWWz5eOnZWL3MQ-2rxlesucb9XnpASGhWzyYNBpWAfaIB3pux1J1xujQLOwscMIhm7T8BP76Ly5jx6BLZCYrrPj0BI0uV90XJyT~4UyQgUlC1jzFQdZ9HDgBPJDf1UI4-YjIwEHuJgdZynYlQ1oUFhgno~HhcDByXO~PDaO~1JDMDbBEfIh~v6MgmHp-Xchod1OfKFrxFrzHgcJbn7E8edTFjZA6JCi~DtFxFelQz1lSBd-QB1qJnA0g-pVL5qngNUojXJCXs4qWcQ7ICLpvIc-Fpfj-0F1gkVlGDSGkb1yLH3~8p4czYgR3W5D7OpwXzezz6clpV8kmbd~x2SotdWsXBPRhqpewO38coU4dJG3OEUbuYmdN~nJMfWbmlcM1lXzz2vBsys4sZzW6dV3hZnbvbfxNTqbdqOh-KXi1iAzXv7CVTun0ubw~CfeGpcAqutC5loRUq7Mq62ngOukyv8Z9AAAA - * - * Lists descriptions of all running jobs. The exact format of the - * description depends on the type of job. - * ------------------------------------------------- - * </pre> - * - * - * @deprecated this isn't run by default, and no one seems to use it, and has - * lots of things to maintain. so, at some point this may dissapear - * unless someone pipes up ;) - */ -public class TunnelManager implements Runnable { - private final static Log _log = new Log(TunnelManager.class); - private I2PTunnel _tunnel; - private ServerSocket _socket; - private boolean _keepAccepting; - - public TunnelManager(int listenPort) { - this(null, listenPort); - } - - public TunnelManager(String listenHost, int listenPort) { - _tunnel = new I2PTunnel(); - _keepAccepting = true; - try { - if (listenHost != null) { - _socket = new ServerSocket(listenPort, 0, InetAddress.getByName(listenHost)); - _log.info("Listening for tunnel management clients on " + listenHost + ":" + listenPort); - } else { - _socket = new ServerSocket(listenPort); - _log.info("Listening for tunnel management clients on localhost:" + listenPort); - } - } catch (Exception e) { - _log.error("Error starting up tunnel management listener on " + listenPort, e); - } - } - - public static void main(String args[]) { - int port = 7676; - String host = null; - if (args.length == 1) { - try { - port = Integer.parseInt(args[0]); - } catch (NumberFormatException nfe) { - _log.error("Usage: TunnelManager [host] [port]"); - return; - } - } else if (args.length == 2) { - host = args[0]; - try { - port = Integer.parseInt(args[1]); - } catch (NumberFormatException nfe) { - _log.error("Usage: TunnelManager [host] [port]"); - return; - } - } - - TunnelManager mgr = new TunnelManager(host, port); - Thread t = new I2PThread(mgr, "Listener"); - t.start(); - } - - public void run() { - if (_socket == null) { - _log.error("Unable to start listening, since the socket was not bound. Already running?"); - return; - } - _log.debug("Running"); - try { - while (_keepAccepting) { - Socket socket = _socket.accept(); - _log.debug("Client accepted"); - if (socket != null) { - Thread t = new I2PThread(new TunnelManagerClientRunner(this, socket)); - t.setName("TunnelManager Client"); - t.setPriority(I2PThread.MIN_PRIORITY); - t.start(); - } - } - } catch (IOException ioe) { - _log.error("Error accepting connections", ioe); - } catch (Exception e) { - _log.error("Other error?!", e); - } finally { - if (_socket != null) try { - _socket.close(); - } catch (IOException ioe) { - } - } - try { - Thread.sleep(5000); - } catch (InterruptedException ie) { - } - } - - public void error(String msg, OutputStream out) throws IOException { - out.write(msg.getBytes()); - out.write('\n'); - } - - public void processQuit(OutputStream out) throws IOException { - out.write("Nice try".getBytes()); - out.write('\n'); - } - - public void processList(OutputStream out) throws IOException { - BufferLogger buf = new BufferLogger(); - long startCommand = Clock.getInstance().now(); - _tunnel.runCommand("list", buf); - Object obj = _tunnel.waitEventValue("listDone"); - long endCommand = Clock.getInstance().now(); - String str = buf.getBuffer(); - _log.debug("ListDone complete after " + (endCommand - startCommand) + "ms: [" + str + "]"); - out.write(str.getBytes()); - out.write('\n'); - buf.ignoreFurtherActions(); - } - - public void processListenOn(String ip, OutputStream out) throws IOException { - BufferLogger buf = new BufferLogger(); - _tunnel.runCommand("listen_on " + ip, buf); - String status = (String) _tunnel.waitEventValue("listen_onResult"); - out.write((status + "\n").getBytes()); - buf.ignoreFurtherActions(); - } - - /** - * "lookup <name>" returns with the result in base64, else "Unknown host" [or something like that], - * then a newline. - * - */ - public void processLookup(String name, OutputStream out) throws IOException { - BufferLogger buf = new BufferLogger(); - _tunnel.runCommand("lookup " + name, buf); - String rv = (String) _tunnel.waitEventValue("lookupResult"); - out.write(rv.getBytes()); - out.write('\n'); - buf.ignoreFurtherActions(); - } - - public void processTestDestination(String destKey, OutputStream out) throws IOException { - try { - Destination d = new Destination(); - d.fromBase64(destKey); - out.write("valid\n".getBytes()); - } catch (DataFormatException dfe) { - out.write("invalid\n".getBytes()); - } - out.flush(); - } - - public void processConvertPrivate(String priv, OutputStream out) throws IOException { - try { - Destination dest = new Destination(); - dest.fromBase64(priv); - String str = dest.toBase64(); - out.write(str.getBytes()); - out.write('\n'); - } catch (DataFormatException dfe) { - _log.error("Error converting private data", dfe); - out.write("Error converting private key\n".getBytes()); - } - } - - public void processClose(String which, boolean forced, OutputStream out) throws IOException { - BufferLogger buf = new BufferLogger(); - _tunnel.runCommand((forced ? "close forced " : "close ") + which, buf); - String str = (String) _tunnel.waitEventValue("closeResult"); - out.write((str + "\n").getBytes()); - buf.ignoreFurtherActions(); - } - - /** - * "genkey" returns with the base64 of the destination, followed by a tab, then the base64 of that - * destination's private keys, then a newline. - * - */ - public void processGenKey(OutputStream out) throws IOException { - BufferLogger buf = new BufferLogger(); - _tunnel.runCommand("gentextkeys", buf); - String priv = (String) _tunnel.waitEventValue("privateKey"); - String pub = (String) _tunnel.waitEventValue("publicDestination"); - out.write((pub + "\t" + priv).getBytes()); - out.write('\n'); - buf.ignoreFurtherActions(); - } - - public void processOpenClient(int listenPort, String peer, String sharedClient, OutputStream out) throws IOException { - BufferLogger buf = new BufferLogger(); - _tunnel.runCommand("client " + listenPort + " " + peer + " " + sharedClient, buf); - Integer taskId = (Integer) _tunnel.waitEventValue("clientTaskId"); - if (taskId.intValue() < 0) { - out.write("error\n".getBytes()); - buf.ignoreFurtherActions(); - return; - } - String rv = (String) _tunnel.waitEventValue("openClientResult"); - if (rv.equals("error")) { - out.write((rv + "\n").getBytes()); - buf.ignoreFurtherActions(); - return; - } - - if (listenPort != 0) { - out.write((rv + " [" + taskId.intValue() + "]\n").getBytes()); - buf.ignoreFurtherActions(); - return; - } - Integer port = (Integer) _tunnel.waitEventValue("clientLocalPort"); - out.write((rv + " " + port.intValue() + " [" + taskId.intValue() + "]\n").getBytes()); - buf.ignoreFurtherActions(); - } - - public void processOpenHTTPClient(int listenPort, String sharedClient, String proxy, OutputStream out) throws IOException { - BufferLogger buf = new BufferLogger(); - _tunnel.runCommand("httpclient " + listenPort + " " + sharedClient + " " + proxy, buf); - Integer taskId = (Integer) _tunnel.waitEventValue("httpclientTaskId"); - if (taskId.intValue() < 0) { - out.write("error\n".getBytes()); - buf.ignoreFurtherActions(); - return; - } - String rv = (String) _tunnel.waitEventValue("openHTTPClientResult"); - if (rv.equals("error")) { - out.write((rv + "\n").getBytes()); - buf.ignoreFurtherActions(); - return; - } - - if (listenPort != 0) { - out.write((rv + " [" + taskId.intValue() + "]\n").getBytes()); - buf.ignoreFurtherActions(); - return; - } - Integer port = (Integer) _tunnel.waitEventValue("clientLocalPort"); - out.write((rv + " " + port.intValue() + " [" + taskId.intValue() + "]\n").getBytes()); - buf.ignoreFurtherActions(); - } - - public void processOpenSOCKSTunnel(int listenPort, OutputStream out) throws IOException { - BufferLogger buf = new BufferLogger(); - _tunnel.runCommand("sockstunnel " + listenPort, buf); - Integer taskId = (Integer) _tunnel.waitEventValue("sockstunnelTaskId"); - if (taskId.intValue() < 0) { - out.write("error\n".getBytes()); - buf.ignoreFurtherActions(); - return; - } - String rv = (String) _tunnel.waitEventValue("openSOCKSTunnelResult"); - if (rv.equals("error")) { - out.write((rv + "\n").getBytes()); - buf.ignoreFurtherActions(); - return; - } - - if (listenPort != 0) { - out.write((rv + " [" + taskId.intValue() + "]\n").getBytes()); - buf.ignoreFurtherActions(); - return; - } - Integer port = (Integer) _tunnel.waitEventValue("clientLocalPort"); - out.write((rv + " " + port.intValue() + " [" + taskId.intValue() + "]\n").getBytes()); - buf.ignoreFurtherActions(); - } - - public void processOpenServer(String serverHost, int serverPort, String privateKeys, OutputStream out) - throws IOException { - BufferLogger buf = new BufferLogger(); - _tunnel.runCommand("textserver " + serverHost + " " + serverPort + " " + privateKeys, buf); - Integer taskId = (Integer) _tunnel.waitEventValue("serverTaskId"); - if (taskId.intValue() < 0) { - out.write("error\n".getBytes()); - buf.ignoreFurtherActions(); - return; - } - - String rv = (String) _tunnel.waitEventValue("openServerResult"); - - if (rv.equals("error")) { - out.write((rv + "\n").getBytes()); - buf.ignoreFurtherActions(); - return; - } - - out.write((rv + " [" + taskId.intValue() + "]\n").getBytes()); - buf.ignoreFurtherActions(); - } - - /** - * Frisbee. - * - */ - public void unknownCommand(String command, OutputStream out) throws IOException { - out.write("Unknown command: ".getBytes()); - out.write(command.getBytes()); - out.write("\n".getBytes()); - } -} diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelManagerClientRunner.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelManagerClientRunner.java deleted file mode 100644 index 6bd9bb730df47faa1d8d124cc6c8b93b6ceaa3e2..0000000000000000000000000000000000000000 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelManagerClientRunner.java +++ /dev/null @@ -1,203 +0,0 @@ -/* I2PTunnel is GPL'ed (with the exception mentioned in I2PTunnel.java) - * (c) 2003 - 2004 mihi - */ - -package net.i2p.i2ptunnel; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.Socket; -import java.util.StringTokenizer; - -import net.i2p.util.Log; - -/** - * Runner thread that reads commands from the socket and fires off commands to - * the TunnelManager - * - */ -class TunnelManagerClientRunner implements Runnable { - private final static Log _log = new Log(TunnelManagerClientRunner.class); - private TunnelManager _mgr; - private Socket _clientSocket; - - public TunnelManagerClientRunner(TunnelManager mgr, Socket socket) { - _clientSocket = socket; - _mgr = mgr; - } - - public void run() { - _log.debug("Client running"); - try { - BufferedReader reader = new BufferedReader(new InputStreamReader(_clientSocket.getInputStream())); - OutputStream out = _clientSocket.getOutputStream(); - - String cmd = reader.readLine(); - if (cmd != null) processCommand(cmd, out); - } catch (IOException ioe) { - _log.error("Error processing client commands", ioe); - } finally { - if (_clientSocket != null) try { - _clientSocket.close(); - } catch (IOException ioe) { - } - } - _log.debug("Client closed"); - } - - /** - * Parse the command string and fire off the appropriate tunnelManager method, - * sending the results to the output stream - */ - private void processCommand(String command, OutputStream out) throws IOException { - _log.debug("Processing [" + command + "]"); - StringTokenizer tok = new StringTokenizer(command); - if (!tok.hasMoreTokens()) { - _mgr.unknownCommand(command, out); - } else { - String cmd = tok.nextToken(); - if ("quit".equalsIgnoreCase(cmd)) { - _mgr.processQuit(out); - } else if ("lookup".equalsIgnoreCase(cmd)) { - if (tok.hasMoreTokens()) - _mgr.processLookup(tok.nextToken(), out); - else - _mgr.error("Usage: lookup <hostname>", out); - } else if ("testdestination".equalsIgnoreCase(cmd)) { - if (tok.hasMoreTokens()) - _mgr.processTestDestination(tok.nextToken(), out); - else - _mgr.error("Usage: testdestination <publicDestination>", out); - } else if ("convertprivate".equalsIgnoreCase(cmd)) { - if (tok.hasMoreTokens()) - _mgr.processConvertPrivate(tok.nextToken(), out); - else - _mgr.error("Usage: convertprivate <privateData>", out); - } else if ("close".equalsIgnoreCase(cmd)) { - if (tok.hasMoreTokens()) { - String closeArg; - if ((closeArg = tok.nextToken()).equals("forced")) { - if (tok.hasMoreTokens()) { - _mgr.processClose(tok.nextToken(), true, out); - } else { - _mgr.error("Usage: close [forced] <jobnumber>|all", out); - } - } else { - _mgr.processClose(closeArg, false, out); - } - } else { - _mgr.error("Usage: close [forced] <jobnumber>|all", out); - } - } else if ("genkey".equalsIgnoreCase(cmd)) { - _mgr.processGenKey(out); - } else if ("list".equalsIgnoreCase(cmd)) { - _mgr.processList(out); - } else if ("listen_on".equalsIgnoreCase(cmd)) { - if (tok.hasMoreTokens()) { - _mgr.processListenOn(tok.nextToken(), out); - } else { - _mgr.error("Usage: listen_on <ip>", out); - } - } else if ("openclient".equalsIgnoreCase(cmd)) { - int listenPort = 0; - String peer = null; - String sharedClient = null; - int numTokens = tok.countTokens(); - if (numTokens < 2 || numTokens > 3) { - _mgr.error("Usage: openclient <listenPort> <peer> <sharedClient>", out); - return; - } - try { - listenPort = Integer.parseInt(tok.nextToken()); - peer = tok.nextToken(); - if (tok.hasMoreTokens()) - sharedClient = tok.nextToken(); - else - sharedClient = "true"; - _mgr.processOpenClient(listenPort, peer, sharedClient, out); - } catch (NumberFormatException nfe) { - _mgr.error("Bad listen port", out); - return; - } - } else if ("openhttpclient".equalsIgnoreCase(cmd)) { - int listenPort = 0; - String proxy = "squid.i2p"; - String sharedClient = "true"; - int numTokens = tok.countTokens(); - if (numTokens < 1 || numTokens > 3) { - _mgr.error("Usage: openhttpclient <listenPort> [<sharedClient>] [<proxy>]", out); - return; - } - try { - listenPort = Integer.parseInt(tok.nextToken()); - if (tok.hasMoreTokens()) { - String val = tok.nextToken(); - if (tok.hasMoreTokens()) { - sharedClient = val; - proxy = tok.nextToken(); - } else { - if ( ("true".equals(val)) || ("false".equals(val)) ) { - sharedClient = val; - } else { - proxy = val; - } - } - } - _mgr.processOpenHTTPClient(listenPort, sharedClient, proxy, out); - } catch (NumberFormatException nfe) { - _mgr.error("Bad listen port", out); - return; - } - } else if ("opensockstunnel".equalsIgnoreCase(cmd)) { - int listenPort = 0; - if (!tok.hasMoreTokens()) { - _mgr.error("Usage: opensockstunnel <listenPort>", out); - return; - } - try { - String portStr = tok.nextToken(); - listenPort = Integer.parseInt(portStr); - } catch (NumberFormatException nfe) { - _mgr.error("Bad listen port", out); - return; - } - if (tok.hasMoreTokens()) { - _mgr.error("Usage: opensockstunnel <listenport>", out); - return; - } - _mgr.processOpenSOCKSTunnel(listenPort, out); - } else if ("openserver".equalsIgnoreCase(cmd)) { - int listenPort = 0; - String serverHost = null; - String serverKeys = null; - if (!tok.hasMoreTokens()) { - _mgr.error("Usage: openserver <serverHost> <serverPort> <serverKeys>", out); - return; - } - serverHost = tok.nextToken(); - - if (!tok.hasMoreTokens()) { - _mgr.error("Usage: openserver <serverHost> <serverPort> <serverKeys>", out); - return; - } - try { - String portStr = tok.nextToken(); - listenPort = Integer.parseInt(portStr); - } catch (NumberFormatException nfe) { - _mgr.error("Bad listen port", out); - return; - } - if (!tok.hasMoreTokens()) { - _mgr.error("Usage: openserver <serverHost> <serverPort> <serverKeys>", out); - return; - } - serverKeys = tok.nextToken(); - _mgr.processOpenServer(serverHost, listenPort, serverKeys, out); - } else { - _mgr.unknownCommand(command, out); - } - } - } -} diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java index 8cf396102e296565ecf71cf7dbcd0a734d324d92..8b039732e7c3e6c073184780685dbc93294a86ce 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java @@ -28,7 +28,8 @@ public class ConfigNetHandler extends FormHandler { private boolean _reseedRequested; private boolean _saveRequested; private boolean _timeSyncEnabled; - private String _port; + private String _tcpPort; + private String _udpPort; private String _inboundRate; private String _inboundBurst; private String _outboundRate; @@ -56,8 +57,11 @@ public class ConfigNetHandler extends FormHandler { public void setHostname(String hostname) { _hostname = (hostname != null ? hostname.trim() : null); } - public void setPort(String port) { - _port = (port != null ? port.trim() : null); + public void setTcpPort(String port) { + _tcpPort = (port != null ? port.trim() : null); + } + public void setUdpPort(String port) { + _udpPort = (port != null ? port.trim() : null); } public void setInboundrate(String rate) { _inboundRate = (rate != null ? rate.trim() : null); @@ -207,14 +211,25 @@ public class ConfigNetHandler extends FormHandler { restartRequired = true; } } - if ( (_port != null) && (_port.length() > 0) ) { + if ( (_tcpPort != null) && (_tcpPort.length() > 0) ) { String oldPort = _context.router().getConfigSetting(ConfigNetHelper.PROP_I2NP_TCP_PORT); - if ( (oldPort == null) && (_port.equals("8887")) ) { + if ( (oldPort == null) && (_tcpPort.equals("8887")) ) { + // still on default.. noop + } else if ( (oldPort == null) || (!oldPort.equalsIgnoreCase(_tcpPort)) ) { + // its not the default OR it has changed + _context.router().setConfigSetting(ConfigNetHelper.PROP_I2NP_TCP_PORT, _tcpPort); + addFormNotice("Updating TCP port from " + oldPort + " to " + _tcpPort); + restartRequired = true; + } + } + if ( (_udpPort != null) && (_udpPort.length() > 0) ) { + String oldPort = _context.router().getConfigSetting(ConfigNetHelper.PROP_I2NP_UDP_PORT); + if ( (oldPort == null) && (_udpPort.equals("8887")) ) { // still on default.. noop - } else if ( (oldPort == null) || (!oldPort.equalsIgnoreCase(_port)) ) { + } else if ( (oldPort == null) || (!oldPort.equalsIgnoreCase(_udpPort)) ) { // its not the default OR it has changed - _context.router().setConfigSetting(ConfigNetHelper.PROP_I2NP_TCP_PORT, _port); - addFormNotice("Updating TCP port from " + oldPort + " to " + _port); + _context.router().setConfigSetting(ConfigNetHelper.PROP_I2NP_TCP_PORT, _udpPort); + addFormNotice("Updating UDP port from " + oldPort + " to " + _udpPort); restartRequired = true; } } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java index fa66bac35e45ce2616cb1f9e4cb08aefe97ad6f5..12e01852a567c6aa0c7d983313532a56c03b7d22 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java @@ -24,11 +24,13 @@ public class ConfigNetHelper { /** copied from various private TCP components */ public final static String PROP_I2NP_TCP_HOSTNAME = "i2np.tcp.hostname"; public final static String PROP_I2NP_TCP_PORT = "i2np.tcp.port"; + public final static String PROP_I2NP_UDP_PORT = "i2np.udp.port"; + public final static String PROP_I2NP_INTERNAL_UDP_PORT = "i2np.udp.internalPort"; public String getHostname() { return _context.getProperty(PROP_I2NP_TCP_HOSTNAME); } - public String getPort() { + public String getTcpPort() { int port = 8887; String val = _context.getProperty(PROP_I2NP_TCP_PORT); if (val != null) { @@ -41,6 +43,21 @@ public class ConfigNetHelper { return "" + port; } + public String getUdpPort() { + int port = 8887; + String val = _context.getProperty(PROP_I2NP_UDP_PORT); + if (val == null) + val = _context.getProperty(PROP_I2NP_INTERNAL_UDP_PORT); + if (val != null) { + try { + port = Integer.parseInt(val); + } catch (NumberFormatException nfe) { + // ignore, use default from above + } + } + return "" + port; + } + public String getEnableTimeSyncChecked() { String disabled = _context.getProperty(Timestamper.PROP_DISABLED, "false"); if ( (disabled != null) && ("true".equalsIgnoreCase(disabled)) ) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigStatsHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigStatsHandler.java index 3aa0dd90e4b51fd06f5f08e47e9a1a082f691025..bcb2af1d5842e00cd02a2d8a532a8ac3ab0322fb 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigStatsHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigStatsHandler.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; +import net.i2p.util.Log; import net.i2p.stat.StatManager; /** @@ -22,6 +23,7 @@ public class ConfigStatsHandler extends FormHandler { public ConfigStatsHandler() { super(); _stats = new ArrayList(); + _explicitFilter = false; } protected void processForm() { @@ -36,29 +38,16 @@ public class ConfigStatsHandler extends FormHandler { if (stats != null) { for (int i = 0; i < stats.length; i++) { String cur = stats[i].trim(); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Stat: [" + cur + "]"); if ( (cur.length() > 0) && (!_stats.contains(cur)) ) _stats.add(cur); } } + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Updated stats: " + _stats); } - public void setStatList(String stat) { - if (stat != null) { - if (stat.indexOf(',') != -1) { - StringTokenizer tok = new StringTokenizer(stat, ","); - while (tok.hasMoreTokens()) { - String cur = tok.nextToken().trim(); - if ( (cur.length() > 0) && (!_stats.contains(cur)) ) - _stats.add(cur); - } - } else { - stat = stat.trim(); - if ( (stat.length() > 0) && (!_stats.contains(stat)) ) - _stats.add(stat); - } - } - } - public void setExplicitFilter(String foo) { _explicitFilter = true; } public void setExplicitFilterValue(String filter) { _explicitFilterValue = filter; } @@ -74,7 +63,19 @@ public class ConfigStatsHandler extends FormHandler { if (_explicitFilter) { _stats.clear(); - setStatList(_explicitFilterValue); + + if (_explicitFilterValue.indexOf(',') != -1) { + StringTokenizer tok = new StringTokenizer(_explicitFilterValue, ","); + while (tok.hasMoreTokens()) { + String cur = tok.nextToken().trim(); + if ( (cur.length() > 0) && (!_stats.contains(cur)) ) + _stats.add(cur); + } + } else { + String stat = _explicitFilterValue.trim(); + if ( (stat.length() > 0) && (!_stats.contains(stat)) ) + _stats.add(stat); + } } StringBuffer stats = new StringBuffer(); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/FormHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/FormHandler.java index 9f14c8b16b6f70009f25724cefd84616b08d76e1..1d66037afe5beeb4893c6be5093cd3f09d7bab93 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/FormHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/FormHandler.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.ArrayList; import net.i2p.router.RouterContext; +import net.i2p.util.Log; /** * Simple form handler base class - does not depend on servlets or jsp, @@ -16,6 +17,7 @@ import net.i2p.router.RouterContext; */ public class FormHandler { protected RouterContext _context; + protected Log _log; private String _nonce; protected String _action; private List _errors; @@ -41,6 +43,7 @@ public class FormHandler { public void setContextId(String contextId) { try { _context = ContextHelper.getContext(contextId); + _log = _context.logManager().getLog(getClass()); } catch (Throwable t) { t.printStackTrace(); } diff --git a/apps/routerconsole/jsp/config.jsp b/apps/routerconsole/jsp/config.jsp index 3209ce3f98fcc2b1b4bf06fe66e19fd9f4d59975..99735f68b7f9fa29cd6b32db19a08f0cd49b90a3 100644 --- a/apps/routerconsole/jsp/config.jsp +++ b/apps/routerconsole/jsp/config.jsp @@ -28,13 +28,13 @@ <input type="hidden" name="nonce" value="<%=System.getProperty("net.i2p.router.web.ConfigNetHandler.nonce")%>" /> <input type="hidden" name="action" value="blah" /> - TCP port: - <input name="port" type="text" size="4" value="<jsp:getProperty name="nethelper" property="port" />" /> <br /> + UDP port: <i><jsp:getProperty name="nethelper" property="udpPort" /></i><br /> +<!-- <input name="udpPort" type="text" size="5" value="<jsp:getProperty name="nethelper" property="udpPort" />" /><br /> --> +<b>You must poke a hole in your firewall or NAT (if applicable) to receive new inbound UDP packets on +this port from arbitrary peers (this requirement will be removed in i2p 0.6.1, but is necessary now)</b><br /> + TCP port: <input name="tcpPort" type="text" size="5" value="<jsp:getProperty name="nethelper" property="tcpPort" />" /> <br /> <b>You must poke a hole in your firewall or NAT (if applicable) so that you can receive inbound TCP - connections on it.</b> Nothing will work if you don't. Sorry. We know how to make it so - this restriction won't be necessary, but its later on in the - <a href="http://www.i2p.net/roadmap">roadmap</a> and we only have so many coder-hours (but if you want - to help, please <a href="http://www.i2p.net/getinvolved">get involved!</a>) + connections on it (this requirement will be removed in i2p 0.6.1, but is necessary now)</b> <hr /> <b>Bandwidth limiter</b><br /> @@ -57,7 +57,7 @@ packets on port 123 to one of the pool.ntp.org machines (or some other SNTP server).</i> <hr /> <input type="submit" name="save" value="Save changes" /> <input type="reset" value="Cancel" /><br /> - <i>Changing the TCP port will force a 'soft restart' - dropping your connections and clients as + <i>Changing the TCP or UDP port will force a 'soft restart' - dropping your connections and clients as if the router was stopped and restarted. <b>Please be patient</b> - it may take a few seconds to complete.</i> </form> @@ -73,6 +73,13 @@ "i2p.reseedURL=someURL" (e.g. java -Di2p.reseedURL=http://dev.i2p.net/i2pdb/ ...). You can also do it manually by getting routerInfo-*.dat files from someone (a friend, someone on IRC, whatever) and saving them to your netDb/ directory.</p> +<p> + With the SSU transport, the internal UDP port may be different from the external + UDP port (in case of a firewall/NAT) - the UDP port field above specifies the + external one and assumes they are the same, but if you want to set the internal + port to something else, you can add "i2np.udp.internalPort=1234" to the + <a href="configadvanced.jsp">advanced</a> config and restart the router. +</p> </div> </body> diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java index aeab27d665803f56f74f3bd04ded1474fbf4ab49..710798b8750d9b963d668896fdc4e772f93b0b45 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java @@ -33,7 +33,7 @@ public class ConnectionPacketHandler { boolean ok = verifyPacket(packet, con); if (!ok) { if ( (!packet.isFlagSet(Packet.FLAG_RESET)) && (_log.shouldLog(Log.ERROR)) ) - _log.error("Packet does NOT verify: " + packet); + _log.error("Packet does NOT verify: " + packet + " on " + con); packet.releasePayload(); return; } @@ -305,16 +305,16 @@ public class ConnectionPacketHandler { if (packet.getSequenceNum() <= 2) { return true; } else { - if (_log.shouldLog(Log.WARN)) - _log.warn("Packet without RST or SYN where we dont know stream ID: " + if (_log.shouldLog(Log.ERROR)) + _log.error("Packet without RST or SYN where we dont know stream ID: " + packet); return false; } } } else { if (!DataHelper.eq(con.getSendStreamId(), packet.getReceiveStreamId())) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Packet received with the wrong reply stream id: " + if (_log.shouldLog(Log.ERROR)) + _log.error("Packet received with the wrong reply stream id: " + con + " / " + packet); return false; } else { @@ -331,8 +331,8 @@ public class ConnectionPacketHandler { if (DataHelper.eq(con.getReceiveStreamId(), packet.getSendStreamId())) { boolean ok = packet.verifySignature(_context, packet.getOptionalFrom(), null); if (!ok) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Received unsigned / forged RST on " + con); + if (_log.shouldLog(Log.ERROR)) + _log.error("Received unsigned / forged RST on " + con); return; } else { if (_log.shouldLog(Log.DEBUG)) diff --git a/core/java/src/net/i2p/CoreVersion.java b/core/java/src/net/i2p/CoreVersion.java index d587fa5faa6ec891c46cba9d6e9040248490a2fa..17d8502055b12e554733fa44634e32b48e20bf04 100644 --- a/core/java/src/net/i2p/CoreVersion.java +++ b/core/java/src/net/i2p/CoreVersion.java @@ -14,8 +14,8 @@ package net.i2p; * */ public class CoreVersion { - public final static String ID = "$Revision: 1.34 $ $Date: 2005/04/06 10:43:26 $"; - public final static String VERSION = "0.5.0.7"; + public final static String ID = "$Revision: 1.35 $ $Date: 2005/04/20 15:14:20 $"; + public final static String VERSION = "0.6"; public static void main(String args[]) { System.out.println("I2P Core version: " + VERSION); diff --git a/core/java/src/net/i2p/client/I2CPMessageProducer.java b/core/java/src/net/i2p/client/I2CPMessageProducer.java index 068e41dafe32657d147ab6914ccd37b26e78a825..9af1fbd19ccb3ea2d40bbdeb739752ac8f5d2691 100644 --- a/core/java/src/net/i2p/client/I2CPMessageProducer.java +++ b/core/java/src/net/i2p/client/I2CPMessageProducer.java @@ -121,7 +121,7 @@ class I2CPMessageProducer { * garlic crypto added by the router) * */ - static final boolean END_TO_END_CRYPTO = true; + static final boolean END_TO_END_CRYPTO = false; /** * Create a new signed payload and send it off to the destination diff --git a/core/java/src/net/i2p/crypto/DHSessionKeyBuilder.java b/core/java/src/net/i2p/crypto/DHSessionKeyBuilder.java index 7fc4df6a748e823e0a5c7d1ea149ca394f3533f6..0fda386c0fca6f4b5033a54ff688bc5f579bb787 100644 --- a/core/java/src/net/i2p/crypto/DHSessionKeyBuilder.java +++ b/core/java/src/net/i2p/crypto/DHSessionKeyBuilder.java @@ -260,7 +260,10 @@ public class DHSessionKeyBuilder { * */ public byte[] getMyPublicValueBytes() { - BigInteger bi = getMyPublicValue(); + return toByteArray(getMyPublicValue()); + } + + private static final byte[] toByteArray(BigInteger bi) { byte data[] = bi.toByteArray(); byte rv[] = new byte[256]; if (data.length == 257) // high byte has the sign bit @@ -299,6 +302,9 @@ public class DHSessionKeyBuilder { public BigInteger getPeerPublicValue() { return _peerValue; } + public byte[] getPeerPublicValueBytes() { + return toByteArray(getPeerPublicValue()); + } /** * Retrieve the session key, calculating it if necessary (and if possible). diff --git a/core/java/src/net/i2p/util/BufferedRandomSource.java b/core/java/src/net/i2p/util/BufferedRandomSource.java index 8103a56e067595ea3cded86a8be16d5dfcf68d0d..e344b5a2ae531b9d82004c2f689ecf3b54e96036 100644 --- a/core/java/src/net/i2p/util/BufferedRandomSource.java +++ b/core/java/src/net/i2p/util/BufferedRandomSource.java @@ -225,4 +225,4 @@ public class BufferedRandomSource extends RandomSource { } return buf.toString(); } -} \ No newline at end of file +} diff --git a/core/java/test/net/i2p/crypto/DHSessionKeyBuilderTest.java b/core/java/test/net/i2p/crypto/DHSessionKeyBuilderTest.java index 416954e43c898f6ecb565ccc68ff4c84d29d110f..c91948d55b9e76833d7e286f6090030bec9d01af 100644 --- a/core/java/test/net/i2p/crypto/DHSessionKeyBuilderTest.java +++ b/core/java/test/net/i2p/crypto/DHSessionKeyBuilderTest.java @@ -25,9 +25,13 @@ public class DHSessionKeyBuilderTest extends TestCase { DHSessionKeyBuilder builder1 = new DHSessionKeyBuilder(); DHSessionKeyBuilder builder2 = new DHSessionKeyBuilder(); BigInteger pub1 = builder1.getMyPublicValue(); - builder2.setPeerPublicValue(pub1); BigInteger pub2 = builder2.getMyPublicValue(); - builder1.setPeerPublicValue(pub2); + try { + builder2.setPeerPublicValue(pub1); + builder1.setPeerPublicValue(pub2); + } catch (DHSessionKeyBuilder.InvalidPublicParameterException ippe) { + assertTrue(ippe.getMessage(), true); + } SessionKey key1 = builder1.getSessionKey(); SessionKey key2 = builder2.getSessionKey(); @@ -44,4 +48,4 @@ public class DHSessionKeyBuilderTest extends TestCase { assertEquals(origVal, tranVal); } } -} \ No newline at end of file +} diff --git a/core/java/test/net/i2p/data/MessagePayloadMessageTest.java b/core/java/test/net/i2p/data/MessagePayloadMessageTest.java index bdd71bf7d18463044000adc502d5042b26a5d645..f818ade52d7e207fbe9f32ff35f4073ca673c4cc 100644 --- a/core/java/test/net/i2p/data/MessagePayloadMessageTest.java +++ b/core/java/test/net/i2p/data/MessagePayloadMessageTest.java @@ -30,9 +30,9 @@ import net.i2p.util.Log; public class MessagePayloadMessageTest extends StructureTest { public DataStructure createDataStructure() throws DataFormatException { MessagePayloadMessage msg = new MessagePayloadMessage(); - msg.setMessageId((MessageId)(new MessageIdTest()).createDataStructure()); + msg.setMessageId(123); msg.setPayload((Payload)(new PayloadTest()).createDataStructure()); - msg.setSessionId((SessionId)(new SessionIdTest()).createDataStructure()); + msg.setSessionId(321); return msg; } public DataStructure createStructureToRead() { return new MessagePayloadMessage(); } @@ -56,4 +56,4 @@ import net.i2p.util.Log; assertEquals(orig, ds); } -} \ No newline at end of file +} diff --git a/core/java/test/net/i2p/data/MessageStatusMessageTest.java b/core/java/test/net/i2p/data/MessageStatusMessageTest.java index c042fe918ca876b8652508d051b8c7eef55be7be..cd8aabc67a31ea9fbd438b300a671562d62204bc 100644 --- a/core/java/test/net/i2p/data/MessageStatusMessageTest.java +++ b/core/java/test/net/i2p/data/MessageStatusMessageTest.java @@ -22,8 +22,8 @@ import net.i2p.data.i2cp.SessionId; public class MessageStatusMessageTest extends StructureTest { public DataStructure createDataStructure() throws DataFormatException { MessageStatusMessage msg = new MessageStatusMessage(); - msg.setSessionId((SessionId)(new SessionIdTest()).createDataStructure()); - msg.setMessageId((MessageId)(new MessageIdTest()).createDataStructure()); + msg.setSessionId(42); + msg.setMessageId(41); msg.setSize(1024*1024*42L); msg.setStatus(MessageStatusMessage.STATUS_AVAILABLE); msg.setNonce(1); diff --git a/core/java/test/net/i2p/data/ReceiveMessageBeginMessageTest.java b/core/java/test/net/i2p/data/ReceiveMessageBeginMessageTest.java index 9bb09a9dae930892ecebf91d8f91083ad033fa9a..19edd8a61064bc98af075d30d49b12a05ad89452 100644 --- a/core/java/test/net/i2p/data/ReceiveMessageBeginMessageTest.java +++ b/core/java/test/net/i2p/data/ReceiveMessageBeginMessageTest.java @@ -22,8 +22,8 @@ import net.i2p.data.i2cp.SessionId; public class ReceiveMessageBeginMessageTest extends StructureTest { public DataStructure createDataStructure() throws DataFormatException { ReceiveMessageBeginMessage msg = new ReceiveMessageBeginMessage(); - msg.setSessionId((SessionId)(new SessionIdTest()).createDataStructure()); - msg.setMessageId((MessageId)(new MessageIdTest()).createDataStructure()); + msg.setSessionId(321); + msg.setMessageId(123); return msg; } public DataStructure createStructureToRead() { return new ReceiveMessageBeginMessage(); } diff --git a/core/java/test/net/i2p/data/ReceiveMessageEndMessageTest.java b/core/java/test/net/i2p/data/ReceiveMessageEndMessageTest.java index 6402dcee3a774ea893714f41af18a2b8fad6020c..4e33406d5d9aa3944a4cb47dba2db041671a618a 100644 --- a/core/java/test/net/i2p/data/ReceiveMessageEndMessageTest.java +++ b/core/java/test/net/i2p/data/ReceiveMessageEndMessageTest.java @@ -22,8 +22,8 @@ import net.i2p.data.i2cp.SessionId; public class ReceiveMessageEndMessageTest extends StructureTest { public DataStructure createDataStructure() throws DataFormatException { ReceiveMessageEndMessage msg = new ReceiveMessageEndMessage(); - msg.setSessionId((SessionId)(new SessionIdTest()).createDataStructure()); - msg.setMessageId((MessageId)(new MessageIdTest()).createDataStructure()); + msg.setSessionId(321); + msg.setMessageId(123); return msg; } public DataStructure createStructureToRead() { return new ReceiveMessageEndMessage(); } diff --git a/history.txt b/history.txt index c30f9e23dafd9b41ce42f8824f4dc03b6e291506..599496efa224c38fdbcaec287ddad3008b68a248 100644 --- a/history.txt +++ b/history.txt @@ -1,4 +1,23 @@ -$Id: history.txt,v 1.216 2005/07/21 17:37:16 jrandom Exp $ +$Id: history.txt,v 1.217 2005/07/22 19:15:59 jrandom Exp $ + +* 2005-07-27 0.6 released + +2005-07-27 jrandom + * Enabled SSU as the default top priority transport, adjusting the + config.jsp page accordingly. + * Add verification fields to the SSU and TCP connection negotiation (not + compatible with previous builds) + * Enable the backwards incompatible tunnel crypto change as documented in + tunnel-alt.html (have each hop encrypt the received IV before using it, + then encrypt it again before sending it on) + * Disable the I2CP encryption, leaving in place the end to end garlic + encryption (another backwards incompatible change) + * Adjust the protocol versions on the TCP and SSU transports so that they + won't talk to older routers. + * Fix up the config stats handling again + * Fix a rare off-by-one in the SSU fragmentation + * Reduce some unnecessary netDb resending by inluding the peers queried + successfully in the store redundancy count. 2005-07-22 jrandom * Use the small thread pool for I2PTunnelHTTPServer (already used for diff --git a/initialNews.xml b/initialNews.xml index 95048d59f3a06a6c6742aeb052192cc46ec660a7..04c5c35ef4a90a496f71ccc01571d88bbb3f2831 100644 --- a/initialNews.xml +++ b/initialNews.xml @@ -1,12 +1,12 @@ -<i2p.news date="$Date: 2005/04/06 10:43:25 $"> - <i2p.release version="0.5.0.7" date="2005/04/20" minVersion="0.5.0.4" +<i2p.news date="$Date: 2005/04/20 15:14:18 $"> + <i2p.release version="0.6" date="2005/07/27" minVersion="0.6" anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/i2pupdate.sud" publicurl="http://dev.i2p.net/i2p/i2pupdate.sud" anonannouncement="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/April-2005/000709.html" publicannouncement="http://dev.i2p.net/pipermail/i2p/April-2005/000709.html" /> - <i2p.notes date="2005/04/19" - anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/April-2005/000708.html" - publicurl="http://dev.i2p.net/pipermail/i2p/April-2005/000708.html" + <i2p.notes date="2005/07/26" + anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/2005-July/000823.html" + publicurl="http://dev.i2p.net/pipermail/i2p/2005-July/000823.html" anonlogs="http://i2p/Nf3ab-ZFkmI-LyMt7GjgT-jfvZ3zKDl0L96pmGQXF1B82W2Bfjf0n7~288vafocjFLnQnVcmZd~-p0-Oolfo9aW2Rm-AhyqxnxyLlPBqGxsJBXjPhm1JBT4Ia8FB-VXt0BuY0fMKdAfWwN61-tj4zIcQWRxv3DFquwEf035K~Ra4SWOqiuJgTRJu7~o~DzHVljVgWIzwf8Z84cz0X33pv-mdG~~y0Bsc2qJVnYwjjR178YMcRSmNE0FVMcs6f17c6zqhMw-11qjKpY~EJfHYCx4lBWF37CD0obbWqTNUIbL~78vxqZRT3dgAgnLixog9nqTO-0Rh~NpVUZnoUi7fNR~awW5U3Cf7rU7nNEKKobLue78hjvRcWn7upHUF45QqTDuaM3yZa7OsjbcH-I909DOub2Q0Dno6vIwuA7yrysccN1sbnkwZbKlf4T6~iDdhaSLJd97QCyPOlbyUfYy9QLNExlRqKgNVJcMJRrIual~Lb1CLbnzt0uvobM57UpqSAAAA/meeting138" publiclogs="http://www.i2p.net/meeting138" /> <h1>Congratulations on getting I2P installed!</h1> diff --git a/installer/install.xml b/installer/install.xml index 567e9c2da1056d66aa0e832ed5197553ecd166f1..4f4e9670fcfca86f7b669b30decdd9aea3b3a7af 100644 --- a/installer/install.xml +++ b/installer/install.xml @@ -4,7 +4,7 @@ <info> <appname>i2p</appname> - <appversion>0.5.0.7</appversion> + <appversion>0.6</appversion> <authors> <author name="I2P" email="support@i2p.net"/> </authors> diff --git a/news.xml b/news.xml index ae8936df2317356b13a2f9c88d116e3356e146c9..bdab5b05d8c941d715d1722109e8fee10ab9fbf7 100644 --- a/news.xml +++ b/news.xml @@ -1,20 +1,15 @@ -<i2p.news date="$Date: 2005/07/11 22:56:42 $"> - <i2p.release version="0.5.0.7" date="2005/04/20" minVersion="0.5.0.4" +<i2p.news date="$Date: 2005/07/13 16:59:01 $"> + <i2p.release version="0.7" date="2005/07/27" minVersion="0.6" anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/i2pupdate.sud" publicurl="http://dev.i2p.net/i2p/i2pupdate.sud" anonannouncement="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/2005-April/000709.html" publicannouncement="http://dev.i2p.net/pipermail/i2p/2005-April/000709.html" /> <i2p.notes date="2005/04/19" - anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/2005-April/000723.html" - publicurl="http://dev.i2p.net/pipermail/i2p/2005-April/000723.html" + anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/2005-July/000823.html" + publicurl="http://dev.i2p.net/pipermail/i2p/2005-July/000823.html" anonlogs="http://i2p/Nf3ab-ZFkmI-LyMt7GjgT-jfvZ3zKDl0L96pmGQXF1B82W2Bfjf0n7~288vafocjFLnQnVcmZd~-p0-Oolfo9aW2Rm-AhyqxnxyLlPBqGxsJBXjPhm1JBT4Ia8FB-VXt0BuY0fMKdAfWwN61-tj4zIcQWRxv3DFquwEf035K~Ra4SWOqiuJgTRJu7~o~DzHVljVgWIzwf8Z84cz0X33pv-mdG~~y0Bsc2qJVnYwjjR178YMcRSmNE0FVMcs6f17c6zqhMw-11qjKpY~EJfHYCx4lBWF37CD0obbWqTNUIbL~78vxqZRT3dgAgnLixog9nqTO-0Rh~NpVUZnoUi7fNR~awW5U3Cf7rU7nNEKKobLue78hjvRcWn7upHUF45QqTDuaM3yZa7OsjbcH-I909DOub2Q0Dno6vIwuA7yrysccN1sbnkwZbKlf4T6~iDdhaSLJd97QCyPOlbyUfYy9QLNExlRqKgNVJcMJRrIual~Lb1CLbnzt0uvobM57UpqSAAAA/meeting139" publiclogs="http://www.i2p.net/meeting138" /> -Thanks to those helping out with the SSU test - there have been lots -of updates lately, so upgrading to the latest CVS HEAD (currently -0.5.0.7-14 as of 2005/07/13) would be worthwhile, and the archived -i2pupdate.zip mentioned -<a href="http://dev.i2p.net/~jrandom/ssu_test.txt">before</a> -may not always be up to date. +Welcome to the new 0.6 series of releases, using the new SSU transport! <br /> </i2p.news> diff --git a/readme.html b/readme.html index 88108d0cced5b497d2bf231a502ee0073857734c..d1e36dc298953c225df2ff71559c3686a18c7336 100644 --- a/readme.html +++ b/readme.html @@ -15,11 +15,10 @@ listed (if not, <a href="#trouble">see below</a>). Once those are up, you can:< <li><a href="http://duck.i2p/">duck.i2p</a>: duck's eepsite, with links to other active sites</li> <li><a href="http://ugha.i2p/">ugha.i2p</a>: ugha's eepsite, a wiki that anyone can edit, and lots of links</li> <li><a href="http://orion.i2p/">orion.i2p</a>: a site which tracks eepsite uptime and changes</li> - <li><a href="http://files.i2p/">files.i2p</a>: a search engine that tries to keep track of things on I2P</li> <li><a href="http://forum.i2p/">forum.i2p</a>: a secure and anonymous connection to <a href="http://forum.i2p.net/">forum.i2p.net</a></li> <li><a href="http://www.i2p/">www.i2p</a>: a secure and anonymous connection to <a href="http://www.i2p.net/">www.i2p.net</a></li> <li><a href="http://dev.i2p/">dev.i2p</a>: a secure and anonymous connection to <a href="http://dev.i2p.net/">dev.i2p.net</a></li> - <li>Freenet proxies: <a href="http://fproxy.i2p/">fproxy.i2p</a> and <a href="http://freenet.eco.i2p/">freenet.eco.i2p</a></li> + <li>Freenet proxies: <a href="http://fproxy.i2p/">fproxy.i2p</a></li> </ul> There are many more eepsites - just follow the links from the ones you see, bookmark your favorites, and visit them often!</li> @@ -56,7 +55,7 @@ IRC (be sure to split it into two lines, as its too long for one).</p> <p>If the left hand side has a warning, telling you to check your NAT or firewall, please see the <a href="/config.jsp">config page</a> and make sure that you can receive <b>inbound -TCP connections on port 8887</b> (or another port that you specify). Problems forwarding +TCP and UDP connections on port 8887</b> (or another port that you specify). Problems forwarding that port account for the vast majority of issues people run into. When it says "Active: 72/85", the "72" means how many peers you are connected with now, and "85" means how many you have spoken with recently - if that first number is 0, you can bet that there diff --git a/router/doc/tunnel-alt.html b/router/doc/tunnel-alt.html index 1b868e949dd6e443bbda3d7c3f18a8ffb8ab6d37..8749e202800a13be4b9578f0d84b1e2969dd70fa 100644 --- a/router/doc/tunnel-alt.html +++ b/router/doc/tunnel-alt.html @@ -1,4 +1,4 @@ -<code>$Id: tunnel-alt.html,v 1.7 2005/02/16 19:48:18 jrandom Exp $</code> +<code>$Id: tunnel-alt.html,v 1.8 2005/07/07 16:16:57 jrandom Exp $</code> <pre> 1) <a href="#tunnel.overview">Tunnel overview</a> 2) <a href="#tunnel.operation">Tunnel operation</a> @@ -173,9 +173,12 @@ the initial preprocessed data.</p> the same previous hop as before (initialized when the first message comes through the tunnel). If the previous peer is a different router, or if the message has already been seen, the message is dropped. The participant then encrypts the -data with AES256/CBC using the participant's layer key and the received IV, -updates the IV by encrypting it with AES256/ECB using the participant's IV key, -then forwards the tuple {nextTunnelId, nextIV, encryptedData} to the next hop.</p> +received IV with AES256/ECB using their IV key to determine the current IV, uses +that IV with the participant's layer key to encrypt the data, encrypts the +current IV with AES256/ECB using their IV key again, then forwards the tuple +{nextTunnelId, nextIV, encryptedData} to the next hop. This double encryption +of the IV (both before and after use) help address a certain class of +confirmation attacks.</p> <p>Duplicate message detection is handled by a decaying Bloom filter on message IVs. Each router maintains a single Bloom filter to contain the XOR of the IV and diff --git a/router/doc/udp.html b/router/doc/udp.html index ac1eb9256605013236e2b87320bbb5199654c1e7..bafe3411d2a1df7e0924e2d5bffc5a24e83c2bbe 100644 --- a/router/doc/udp.html +++ b/router/doc/udp.html @@ -1,4 +1,4 @@ -<code>$Id: udp.html,v 1.12 2005/04/09 18:15:53 jrandom Exp $</code> +<code>$Id: udp.html,v 1.13 2005/05/01 15:08:08 jrandom Exp $</code> <h1>Secure Semireliable UDP (SSU)</h1> <b>DRAFT</b> @@ -141,7 +141,7 @@ around briefly, to address packet loss and reordering.</p> <li>4 byte timestamp (seconds from the epoch) for use in the DSA signature</li> <li>40 byte DSA signature of the critical exchanged data - (Alice's IP + Alice's port + Bob's IP + Bob's port + Alice's + (X + Y + Alice's IP + Alice's port + Bob's IP + Bob's port + Alice's new relay tag + Bob's signed on time), encrypted with another layer of encryption using the negotiated sessionKey. The IV is reused here.</li> @@ -197,7 +197,7 @@ bits 4-7: total identity fragments</pre></li> <li>on the last identity fragment, the signed on time is included after the identity fragment, and the last 40 bytes contain the DSA signature of the critical exchanged - data (Alice's IP + Alice's port + Bob's IP + Bob's port + data (X + Y + Alice's IP + Alice's port + Bob's IP + Bob's port + Alice's new relay key + Alice's signed on time)</li> </ul></td></tr> <tr><td align="right" valign="top"><b>Key used:</b></td> diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 01616a7f6883d63d9e34bf41033d50fe911457f6..679cbddcdabcafadd42a231d5677f7eddd2843ca 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -15,9 +15,9 @@ import net.i2p.CoreVersion; * */ public class RouterVersion { - public final static String ID = "$Revision: 1.207 $ $Date: 2005/07/21 17:37:15 $"; - public final static String VERSION = "0.5.0.7"; - public final static long BUILD = 19; + public final static String ID = "$Revision: 1.208 $ $Date: 2005/07/22 19:15:58 $"; + public final static String VERSION = "0.6"; + public final static long BUILD = 0; public static void main(String args[]) { System.out.println("I2P Router version: " + VERSION); System.out.println("Router ID: " + RouterVersion.ID); diff --git a/router/java/src/net/i2p/router/StatisticsManager.java b/router/java/src/net/i2p/router/StatisticsManager.java index e3983f655f494de880f6039e0fdfb09945d40ece..ff49f8e0d84206d8f70eb2369e03f956fffd9be9 100644 --- a/router/java/src/net/i2p/router/StatisticsManager.java +++ b/router/java/src/net/i2p/router/StatisticsManager.java @@ -102,12 +102,12 @@ public class StatisticsManager implements Service { stats.putAll(_context.profileManager().summarizePeers(_publishedStats)); includeThroughput(stats); - includeRate("router.invalidMessageTime", stats, new long[] { 10*60*1000 }); + //includeRate("router.invalidMessageTime", stats, new long[] { 10*60*1000 }); includeRate("router.duplicateMessageId", stats, new long[] { 24*60*60*1000 }); - includeRate("tunnel.duplicateIV", stats, new long[] { 24*60*60*1000 }); + //includeRate("tunnel.duplicateIV", stats, new long[] { 24*60*60*1000 }); includeRate("tunnel.fragmentedDropped", stats, new long[] { 10*60*1000, 3*60*60*1000 }); - includeRate("tunnel.fullFragments", stats, new long[] { 10*60*1000, 3*60*60*1000 }); - includeRate("tunnel.smallFragments", stats, new long[] { 10*60*1000, 3*60*60*1000 }); + //includeRate("tunnel.fullFragments", stats, new long[] { 10*60*1000, 3*60*60*1000 }); + //includeRate("tunnel.smallFragments", stats, new long[] { 10*60*1000, 3*60*60*1000 }); includeRate("tunnel.testFailedTime", stats, new long[] { 60*60*1000 }); includeRate("tunnel.buildFailure", stats, new long[] { 60*60*1000 }); @@ -117,22 +117,26 @@ public class StatisticsManager implements Service { includeRate("tunnel.batchMultipleCount", stats, new long[] { 10*60*1000, 60*60*1000 }); includeRate("tunnel.corruptMessage", stats, new long[] { 60*60*1000l, 3*60*60*1000l }); - includeRate("router.throttleTunnelProbTestSlow", stats, new long[] { 60*60*1000 }); - includeRate("router.throttleTunnelProbTooFast", stats, new long[] { 60*60*1000 }); - includeRate("router.throttleTunnelProcessingTime1m", stats, new long[] { 60*60*1000 }); + //includeRate("router.throttleTunnelProbTestSlow", stats, new long[] { 60*60*1000 }); + //includeRate("router.throttleTunnelProbTooFast", stats, new long[] { 60*60*1000 }); + //includeRate("router.throttleTunnelProcessingTime1m", stats, new long[] { 60*60*1000 }); includeRate("router.fastPeers", stats, new long[] { 60*60*1000 }); includeRate("clock.skew", stats, new long[] { 10*60*1000, 3*60*60*1000, 24*60*60*1000 }); - includeRate("transport.sendProcessingTime", stats, new long[] { 60*60*1000 }); - includeRate("jobQueue.jobRunSlow", stats, new long[] { 10*60*1000l, 60*60*1000l }); + //includeRate("transport.sendProcessingTime", stats, new long[] { 60*60*1000 }); + //includeRate("jobQueue.jobRunSlow", stats, new long[] { 10*60*1000l, 60*60*1000l }); includeRate("crypto.elGamal.encrypt", stats, new long[] { 60*60*1000 }); includeRate("tunnel.participatingTunnels", stats, new long[] { 5*60*1000, 60*60*1000 }); includeRate("tunnel.testSuccessTime", stats, new long[] { 60*60*1000l, 24*60*60*1000l }); includeRate("client.sendAckTime", stats, new long[] { 60*60*1000 }, true); - includeRate("stream.con.sendDuplicateSize", stats, new long[] { 60*60*1000 }); - includeRate("stream.con.receiveDuplicateSize", stats, new long[] { 60*60*1000 }); + includeRate("udp.sendConfirmTime", stats, new long[] { 10*60*1000 }); + includeRate("udp.sendVolleyTime", stats, new long[] { 10*60*1000 }); + includeRate("udp.ignoreRecentDuplicate", stats, new long[] { 10*60*1000 }); + includeRate("udp.congestionOccurred", stats, new long[] { 10*60*1000 }); + //includeRate("stream.con.sendDuplicateSize", stats, new long[] { 60*60*1000 }); + //includeRate("stream.con.receiveDuplicateSize", stats, new long[] { 60*60*1000 }); stats.setProperty("stat_uptime", DataHelper.formatDuration(_context.router().getUptime())); stats.setProperty("stat__rateKey", "avg;maxAvg;pctLifetime;[sat;satLim;maxSat;maxSatLim;][num;lifetimeFreq;maxFreq]"); _log.debug("Publishing peer rankings"); diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java index a8359e09faf3a53fb5fa9c7319f2d46ee58b1568..dcdd7405f028690809c024845c927b8de2b88c9c 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java @@ -281,7 +281,7 @@ class StoreJob extends JobImpl { getContext().profileManager().dbStoreSent(_peer.getIdentity().getHash(), howLong); getContext().statManager().addRateData("netDb.ackTime", howLong, howLong); - if (_state.getSuccessful().size() >= REDUNDANCY) { + if (_state.getCompleteCount() >= REDUNDANCY) { succeed(); } else { sendNext(); diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/StoreState.java b/router/java/src/net/i2p/router/networkdb/kademlia/StoreState.java index 584f3eb3a4e9cceb8da3092e77fbea590b410ec0..12520f992f76cef095243d9f0fd7776d432e52d0 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/StoreState.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/StoreState.java @@ -21,6 +21,7 @@ class StoreState { private HashSet _successfulExploratoryPeers; private HashSet _failedPeers; private HashSet _attemptedPeers; + private int _completeCount; private volatile long _completed; private volatile long _started; @@ -34,8 +35,10 @@ class StoreState { _pendingPeers = new HashSet(16); _pendingPeerTimes = new HashMap(16); _attemptedPeers = new HashSet(16); - if (toSkip != null) + if (toSkip != null) { _attemptedPeers.addAll(toSkip); + _completeCount = toSkip.size(); + } _failedPeers = new HashSet(16); _successfulPeers = new HashSet(16); _successfulExploratoryPeers = new HashSet(16); @@ -75,6 +78,7 @@ class StoreState { if (completed) _completed = _context.clock().now(); } + public int getCompleteCount() { return _completeCount; } public long getWhenStarted() { return _started; } public long getWhenCompleted() { return _completed; } @@ -110,6 +114,7 @@ class StoreState { synchronized (_successfulPeers) { _successfulPeers.add(peer); } + _completeCount++; return rv; } diff --git a/router/java/src/net/i2p/router/transport/TransportManager.java b/router/java/src/net/i2p/router/transport/TransportManager.java index 8db02b63b936823327a1afa0d94deeecf8fed1b6..551c9b9f354d74bf9417e0d6637d304798919d67 100644 --- a/router/java/src/net/i2p/router/transport/TransportManager.java +++ b/router/java/src/net/i2p/router/transport/TransportManager.java @@ -34,6 +34,7 @@ public class TransportManager implements TransportEventListener { private final static String PROP_DISABLE_TCP = "i2np.tcp.disable"; private final static String PROP_ENABLE_UDP = "i2np.udp.enable"; + private static final String DEFAULT_ENABLE_UDP = "true"; public TransportManager(RouterContext context) { _context = context; @@ -63,7 +64,9 @@ public class TransportManager implements TransportEventListener { _transports.add(t); } String enableUDP = _context.router().getConfigSetting(PROP_ENABLE_UDP); - if ( (enableUDP != null) && (Boolean.valueOf(enableUDP).booleanValue())) { + if (enableUDP == null) + enableUDP = DEFAULT_ENABLE_UDP; + if ("true".equalsIgnoreCase(enableUDP)) { UDPTransport udp = new UDPTransport(_context); udp.setListener(this); _transports.add(udp); diff --git a/router/java/src/net/i2p/router/transport/tcp/ConnectionBuilder.java b/router/java/src/net/i2p/router/transport/tcp/ConnectionBuilder.java index c0392105100c975dd5f12d1d67e95b776c203dba..62ad79c184c1757d214225dbeabf408a51a05d2b 100644 --- a/router/java/src/net/i2p/router/transport/tcp/ConnectionBuilder.java +++ b/router/java/src/net/i2p/router/transport/tcp/ConnectionBuilder.java @@ -529,8 +529,12 @@ public class ConnectionBuilder { return false; } + // our public == X, since we are establishing the connection + byte X[] = builder.getMyPublicValueBytes(); + byte Y[] = builder.getPeerPublicValueBytes(); + // send: routerInfo + currentTime - // + S(routerInfo + currentTime + nonce + nextTag, routerIdent.signingKey) + // + S(routerInfo + currentTime + nonce + nextTag + X + Y, routerIdent.signingKey) try { ByteArrayOutputStream baos = new ByteArrayOutputStream(512); _context.router().getRouterInfo().writeBytes(baos); @@ -540,6 +544,8 @@ public class ConnectionBuilder { baos.write(_nonce.getData()); baos.write(_nextConnectionTag.getData()); + baos.write(X); + baos.write(Y); Signature sig = _context.dsa().sign(baos.toByteArray(), _context.keyManager().getSigningPrivateKey()); @@ -556,7 +562,7 @@ public class ConnectionBuilder { } // read: routerInfo + status + properties - // + S(routerInfo + status + properties + nonce + nextTag, routerIdent.signingKey) + // + S(routerInfo + status + properties + nonce + nextTag + X + Y, routerIdent.signingKey) try { RouterInfo peer = new RouterInfo(); peer.readBytes(_rawIn); @@ -578,6 +584,8 @@ public class ConnectionBuilder { DataHelper.writeProperties(baos, props); baos.write(_nonce.getData()); baos.write(_nextConnectionTag.getData()); + baos.write(X); + baos.write(Y); ok = _context.dsa().verifySignature(sig, baos.toByteArray(), peer.getIdentity().getSigningPublicKey()); diff --git a/router/java/src/net/i2p/router/transport/tcp/ConnectionHandler.java b/router/java/src/net/i2p/router/transport/tcp/ConnectionHandler.java index 249a3265f7c10d52314846b01575e53553e92339..e12f45ad54c9654594ed4de02da35f7fea47b742 100644 --- a/router/java/src/net/i2p/router/transport/tcp/ConnectionHandler.java +++ b/router/java/src/net/i2p/router/transport/tcp/ConnectionHandler.java @@ -555,8 +555,12 @@ public class ConnectionHandler { long clockSkew = 0; boolean sigOk = false; + // our public == Y, since we are receiving the connection + byte X[] = builder.getPeerPublicValueBytes(); + byte Y[] = builder.getMyPublicValueBytes(); + // read: routerInfo + currentTime - // + S(routerInfo + currentTime + nonce + nextTag, routerIdent.signingKey) + // + S(routerInfo + currentTime + nonce + nextTag + X + Y, routerIdent.signingKey) try { RouterInfo info = new RouterInfo(); info.readBytes(_rawIn); @@ -569,6 +573,8 @@ public class ConnectionHandler { DataHelper.writeDate(baos, now); baos.write(_nonce.getData()); baos.write(_nextConnectionTag.getData()); + baos.write(X); + baos.write(Y); sigOk = _context.dsa().verifySignature(sig, baos.toByteArray(), info.getIdentity().getSigningPublicKey()); @@ -589,7 +595,7 @@ public class ConnectionHandler { boolean reachable = verifyReachability(); // send: routerInfo + status + properties - // + S(routerInfo + status + properties + nonce + nextTag, routerIdent.signingKey) + // + S(routerInfo + status + properties + nonce + nextTag + X + Y, routerIdent.signingKey) try { ByteArrayOutputStream baos = new ByteArrayOutputStream(512); _context.router().getRouterInfo().writeBytes(baos); @@ -629,6 +635,8 @@ public class ConnectionHandler { baos.write(_nonce.getData()); baos.write(_nextConnectionTag.getData()); + baos.write(X); + baos.write(Y); Signature sig = _context.dsa().sign(baos.toByteArray(), _context.keyManager().getSigningPrivateKey()); diff --git a/router/java/src/net/i2p/router/transport/tcp/TCPTransport.java b/router/java/src/net/i2p/router/transport/tcp/TCPTransport.java index d6052d0382be65c8842584cfc385480adac385cb..d2ca97c075ff892257764ba00c75d80c80888044 100644 --- a/router/java/src/net/i2p/router/transport/tcp/TCPTransport.java +++ b/router/java/src/net/i2p/router/transport/tcp/TCPTransport.java @@ -89,7 +89,7 @@ public class TCPTransport extends TransportImpl { public static final int DEFAULT_ESTABLISHERS = 3; /** Ordered list of supported I2NP protocols */ - public static final int[] SUPPORTED_PROTOCOLS = new int[] { 4 }; // drop <= 0.5.0.3 + public static final int[] SUPPORTED_PROTOCOLS = new int[] { 5 }; // drop < 0.6 /** blah, people shouldnt use defaults... */ public static final int DEFAULT_LISTEN_PORT = 8887; diff --git a/router/java/src/net/i2p/router/transport/udp/ACKSender.java b/router/java/src/net/i2p/router/transport/udp/ACKSender.java index e3d424ee2935d567a6959d99ba1f4748c6850fe2..e788213f9a471ed75a4b75515a05b092c792ed6d 100644 --- a/router/java/src/net/i2p/router/transport/udp/ACKSender.java +++ b/router/java/src/net/i2p/router/transport/udp/ACKSender.java @@ -98,7 +98,8 @@ public class ACKSender implements Runnable { if ( (ackBitfields != null) && (ackBitfields.size() > 0) ) { _context.statManager().addRateData("udp.sendACKCount", ackBitfields.size(), 0); - _context.statManager().addRateData("udp.sendACKRemaining", remaining, 0); + if (remaining > 0) + _context.statManager().addRateData("udp.sendACKRemaining", remaining, 0); now = _context.clock().now(); if (lastSend < 0) lastSend = now - 1; diff --git a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java index b464ff6d652e47275c624e12dd621a0820893e72..76cd9a488f3355cb14149e06b1e7cce3736d032c 100644 --- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java +++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java @@ -63,8 +63,7 @@ public class EstablishmentManager { /** * Grab the active establishing state */ - InboundEstablishState getInboundState(InetAddress fromHost, int fromPort) { - RemoteHostId from = new RemoteHostId(fromHost.getAddress(), fromPort); + InboundEstablishState getInboundState(RemoteHostId from) { synchronized (_inboundStates) { InboundEstablishState state = (InboundEstablishState)_inboundStates.get(from); if ( (state == null) && (_log.shouldLog(Log.DEBUG)) ) @@ -73,8 +72,7 @@ public class EstablishmentManager { } } - OutboundEstablishState getOutboundState(InetAddress fromHost, int fromPort) { - RemoteHostId from = new RemoteHostId(fromHost.getAddress(), fromPort); + OutboundEstablishState getOutboundState(RemoteHostId from) { synchronized (_outboundStates) { OutboundEstablishState state = (OutboundEstablishState)_outboundStates.get(from); if ( (state == null) && (_log.shouldLog(Log.DEBUG)) ) @@ -121,12 +119,12 @@ public class EstablishmentManager { * Got a SessionRequest (initiates an inbound establishment) * */ - void receiveSessionRequest(RemoteHostId from, InetAddress host, int port, UDPPacketReader reader) { + void receiveSessionRequest(RemoteHostId from, UDPPacketReader reader) { InboundEstablishState state = null; synchronized (_inboundStates) { state = (InboundEstablishState)_inboundStates.get(from); if (state == null) { - state = new InboundEstablishState(_context, host, port, _transport.getLocalPort()); + state = new InboundEstablishState(_context, from.getIP(), from.getPort(), _transport.getLocalPort()); _inboundStates.put(from, state); } } diff --git a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java index 8f426f442ba8e558af68074b5bf7edca27ea586d..f39f67d473d3d393008e55efc04b4908bcabd867 100644 --- a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java +++ b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java @@ -66,10 +66,10 @@ public class InboundEstablishState { /** we have completely received all of the confirmation packets */ public static final int STATE_CONFIRMED_COMPLETELY = 4; - public InboundEstablishState(RouterContext ctx, InetAddress remoteHost, int remotePort, int localPort) { + public InboundEstablishState(RouterContext ctx, byte remoteIP[], int remotePort, int localPort) { _context = ctx; _log = ctx.logManager().getLog(InboundEstablishState.class); - _aliceIP = remoteHost.getAddress(); + _aliceIP = remoteIP; _alicePort = remotePort; _remoteHostId = new RemoteHostId(_aliceIP, _alicePort); _bobPort = localPort; @@ -141,7 +141,8 @@ public class InboundEstablishState { * new relay tag + Bob's signed on time */ private void signSessionCreated() { - byte signed[] = new byte[_aliceIP.length + 2 + byte signed[] = new byte[256 + 256 // X + Y + + _aliceIP.length + 2 + _bobIP.length + 2 + 4 // sent relay tag + 4 // signed on time @@ -149,6 +150,12 @@ public class InboundEstablishState { _sentSignedOnTime = _context.clock().now() / 1000; int off = 0; + System.arraycopy(_receivedX, 0, signed, off, _receivedX.length); + off += _receivedX.length; + if (_sentY == null) + _sentY = getSentY(); + System.arraycopy(_sentY, 0, signed, off, _sentY.length); + off += _sentY.length; System.arraycopy(_aliceIP, 0, signed, off, _aliceIP.length); off += _aliceIP.length; DataHelper.toLong(signed, off, 2, _alicePort); @@ -166,6 +173,8 @@ public class InboundEstablishState { if (_log.shouldLog(Log.DEBUG)) { StringBuffer buf = new StringBuffer(128); buf.append("Signing sessionCreated:"); + buf.append(" ReceivedX: ").append(Base64.encode(_receivedX)); + buf.append(" SentY: ").append(Base64.encode(_sentY)); buf.append(" AliceIP: ").append(Base64.encode(_aliceIP)); buf.append(" AlicePort: ").append(_alicePort); buf.append(" BobIP: ").append(Base64.encode(_bobIP)); @@ -266,13 +275,18 @@ public class InboundEstablishState { try { peer.readBytes(in); - byte signed[] = new byte[_aliceIP.length + 2 + byte signed[] = new byte[256+256 // X + Y + + _aliceIP.length + 2 + _bobIP.length + 2 + 4 // Alice's relay key + 4 // signed on time ]; off = 0; + System.arraycopy(_receivedX, 0, signed, off, _receivedX.length); + off += _receivedX.length; + System.arraycopy(_sentY, 0, signed, off, _sentY.length); + off += _sentY.length; System.arraycopy(_aliceIP, 0, signed, off, _aliceIP.length); off += _aliceIP.length; DataHelper.toLong(signed, off, 2, _alicePort); diff --git a/router/java/src/net/i2p/router/transport/udp/InboundMessageFragments.java b/router/java/src/net/i2p/router/transport/udp/InboundMessageFragments.java index 91d181b695d2d60d088689045b10838449f1f435..d5e534f37426ade3d8395988cfe51bd56c4ea86a 100644 --- a/router/java/src/net/i2p/router/transport/udp/InboundMessageFragments.java +++ b/router/java/src/net/i2p/router/transport/udp/InboundMessageFragments.java @@ -152,7 +152,8 @@ public class InboundMessageFragments /*implements UDPTransport.PartialACKSource _log.info("Message received completely! " + state); _context.statManager().addRateData("udp.receivedCompleteTime", state.getLifetime(), state.getLifetime()); - _context.statManager().addRateData("udp.receivedCompleteFragments", state.getFragmentCount(), state.getLifetime()); + if (state.getFragmentCount() > 0) + _context.statManager().addRateData("udp.receivedCompleteFragments", state.getFragmentCount(), state.getLifetime()); } else if (messageExpired) { state.releaseResources(); if (_log.shouldLog(Log.WARN)) diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java index f976973933838ec4c9772cb13eed28fe66863108..b64b796174ef5100c5071493d38327b58cfd1431 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java @@ -234,13 +234,18 @@ public class OutboundEstablishState { * new relay tag + Bob's signed on time */ private boolean verifySessionCreated() { - byte signed[] = new byte[_aliceIP.length + 2 + byte signed[] = new byte[256+256 // X + Y + + _aliceIP.length + 2 + _bobIP.length + 2 + 4 // sent relay tag + 4 // signed on time ]; int off = 0; + System.arraycopy(_sentX, 0, signed, off, _sentX.length); + off += _sentX.length; + System.arraycopy(_receivedY, 0, signed, off, _receivedY.length); + off += _receivedY.length; System.arraycopy(_aliceIP, 0, signed, off, _aliceIP.length); off += _aliceIP.length; DataHelper.toLong(signed, off, 2, _alicePort); @@ -287,7 +292,8 @@ public class OutboundEstablishState { public synchronized void prepareSessionConfirmed() { if (_sentSignedOnTime > 0) return; - byte signed[] = new byte[_aliceIP.length + 2 + byte signed[] = new byte[256+256 // X + Y + + _aliceIP.length + 2 + _bobIP.length + 2 + 4 // Alice's relay key + 4 // signed on time @@ -296,6 +302,10 @@ public class OutboundEstablishState { _sentSignedOnTime = _context.clock().now() / 1000; int off = 0; + System.arraycopy(_sentX, 0, signed, off, _sentX.length); + off += _sentX.length; + System.arraycopy(_receivedY, 0, signed, off, _receivedY.length); + off += _receivedY.length; System.arraycopy(_aliceIP, 0, signed, off, _aliceIP.length); off += _aliceIP.length; DataHelper.toLong(signed, off, 2, _alicePort); diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java b/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java index da8f28af66c08dbb1f8e265624619583c2994ec5..b20fccd5f3ac121908e5fa48067cf1e79295d6d1 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java @@ -35,7 +35,7 @@ public class OutboundMessageFragments { /** if we can handle more messages explicitly, set this to true */ private boolean _allowExcess; - private static final int MAX_ACTIVE = 16; + private static final int MAX_ACTIVE = 32; // don't send a packet more than 10 times static final int MAX_VOLLEYS = 10; @@ -414,8 +414,10 @@ public class OutboundMessageFragments { _log.info("Received ack of " + messageId + " by " + ackedBy.toBase64() + " after " + state.getLifetime() + " and " + numSends + " sends"); _context.statManager().addRateData("udp.sendConfirmTime", state.getLifetime(), state.getLifetime()); - _context.statManager().addRateData("udp.sendConfirmFragments", state.getFragmentCount(), state.getLifetime()); - _context.statManager().addRateData("udp.sendConfirmVolley", numSends, state.getFragmentCount()); + if (state.getFragmentCount() > 1) + _context.statManager().addRateData("udp.sendConfirmFragments", state.getFragmentCount(), state.getLifetime()); + if (numSends > 1) + _context.statManager().addRateData("udp.sendConfirmVolley", numSends, state.getFragmentCount()); _transport.succeeded(state.getMessage()); int numFragments = state.getFragmentCount(); if (state.getPeer() != null) { @@ -494,8 +496,10 @@ public class OutboundMessageFragments { if (isComplete) { _context.statManager().addRateData("udp.sendConfirmTime", state.getLifetime(), state.getLifetime()); - _context.statManager().addRateData("udp.sendConfirmFragments", state.getFragmentCount(), state.getLifetime()); - _context.statManager().addRateData("udp.sendConfirmVolley", numSends, state.getFragmentCount()); + if (state.getFragmentCount() > 1) + _context.statManager().addRateData("udp.sendConfirmFragments", state.getFragmentCount(), state.getLifetime()); + if (numSends > 1) + _context.statManager().addRateData("udp.sendConfirmVolley", numSends, state.getFragmentCount()); _transport.succeeded(state.getMessage()); if (state.getPeer() != null) { diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java b/router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java index 7ac9bf77d5f7a0751e311f92e4ebb29fa7a05a6e..b955904e0b8a2dff226fc1bb20547e63c6d5f68a 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java @@ -225,10 +225,15 @@ public class OutboundMessageState { public boolean shouldSend(int fragmentNum) { return _fragmentSends[fragmentNum] >= (short)0; } public int fragmentSize(int fragmentNum) { if (_messageBuf == null) return -1; - if (fragmentNum + 1 == _fragmentSends.length) - return _messageBuf.getValid() % _fragmentSize; - else + if (fragmentNum + 1 == _fragmentSends.length) { + int valid = _messageBuf.getValid(); + if (valid <= _fragmentSize) + return valid; + else + return valid % _fragmentSize; + } else { return _fragmentSize; + } } /** @@ -241,10 +246,8 @@ public class OutboundMessageState { */ public int writeFragment(byte out[], int outOffset, int fragmentNum) { int start = _fragmentSize * fragmentNum; - int end = start + _fragmentSize; + int end = start + fragmentSize(fragmentNum); if (_messageBuf == null) return -1; - if (end > _messageBuf.getValid()) - end = _messageBuf.getValid(); int toSend = end - start; System.arraycopy(_messageBuf.getData(), start, out, outOffset, toSend); if (_log.shouldLog(Log.DEBUG)) diff --git a/router/java/src/net/i2p/router/transport/udp/PacketHandler.java b/router/java/src/net/i2p/router/transport/udp/PacketHandler.java index 278762ee2998340f350311600ada0e0d0ee8c391..503b8d5995984a67f1577ae06eb8b5f5a69163ee 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketHandler.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketHandler.java @@ -100,13 +100,12 @@ public class PacketHandler { private void handlePacket(UDPPacketReader reader, UDPPacket packet) { if (packet == null) return; - InetAddress remAddr = packet.getPacket().getAddress(); - int remPort = packet.getPacket().getPort(); - PeerState state = _transport.getPeerState(remAddr, remPort); + RemoteHostId rem = packet.getRemoteHost(); + PeerState state = _transport.getPeerState(rem); if (state == null) { if (_log.shouldLog(Log.DEBUG)) _log.debug("Packet received is not for a connected peer"); - InboundEstablishState est = _establisher.getInboundState(remAddr, remPort); + InboundEstablishState est = _establisher.getInboundState(rem); if (est != null) { if (_log.shouldLog(Log.DEBUG)) _log.debug("Packet received IS for an inbound establishment"); @@ -114,7 +113,7 @@ public class PacketHandler { } else { if (_log.shouldLog(Log.DEBUG)) _log.debug("Packet received is not for an inbound establishment"); - OutboundEstablishState oest = _establisher.getOutboundState(remAddr, remPort); + OutboundEstablishState oest = _establisher.getOutboundState(rem); if (oest != null) { if (_log.shouldLog(Log.DEBUG)) _log.debug("Packet received IS for an outbound establishment"); @@ -152,9 +151,7 @@ public class PacketHandler { _log.info("Validation with existing con failed, but validation as reestablish/stray passed"); packet.decrypt(_transport.getIntroKey()); } else { - InetAddress remAddr = packet.getPacket().getAddress(); - int remPort = packet.getPacket().getPort(); - InboundEstablishState est = _establisher.getInboundState(remAddr, remPort); + InboundEstablishState est = _establisher.getInboundState(packet.getRemoteHost()); if (est != null) { if (_log.shouldLog(Log.DEBUG)) _log.debug("Packet from an existing peer IS for an inbound establishment"); @@ -304,13 +301,14 @@ public class PacketHandler { _context.statManager().addRateData("udp.receivePacketSkew", skew, packet.getLifetime()); - InetAddress fromHost = packet.getPacket().getAddress(); - int fromPort = packet.getPacket().getPort(); - RemoteHostId from = new RemoteHostId(fromHost.getAddress(), fromPort); + //InetAddress fromHost = packet.getPacket().getAddress(); + //int fromPort = packet.getPacket().getPort(); + //RemoteHostId from = new RemoteHostId(fromHost.getAddress(), fromPort); + RemoteHostId from = packet.getRemoteHost(); switch (reader.readPayloadType()) { case UDPPacket.PAYLOAD_TYPE_SESSION_REQUEST: - _establisher.receiveSessionRequest(from, fromHost, fromPort, reader); + _establisher.receiveSessionRequest(from, reader); break; case UDPPacket.PAYLOAD_TYPE_SESSION_CONFIRMED: _establisher.receiveSessionConfirmed(from, reader); diff --git a/router/java/src/net/i2p/router/transport/udp/PeerState.java b/router/java/src/net/i2p/router/transport/udp/PeerState.java index 2d8c82ce30fdf4e5e03ab49090e94fdd9156e201..0b36f8af8152ec6c1d5cf8ccb5f81671e7c86135 100644 --- a/router/java/src/net/i2p/router/transport/udp/PeerState.java +++ b/router/java/src/net/i2p/router/transport/udp/PeerState.java @@ -541,10 +541,11 @@ public class PeerState { } } - _context.statManager().addRateData("udp.sendACKPartial", partialIncluded, rv.size() - partialIncluded); _lastACKSend = _context.clock().now(); if (rv == null) rv = Collections.EMPTY_LIST; + if (partialIncluded > 0) + _context.statManager().addRateData("udp.sendACKPartial", partialIncluded, rv.size() - partialIncluded); return rv; } diff --git a/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java b/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java index df8b334c1879dcb8c3c41f2235c7935f1df776ef..21fe37b9d3aa954990f0b8f36d04bafb92d536ff 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java @@ -37,7 +37,7 @@ public class UDPEndpoint { _receiver.startup(); } catch (SocketException se) { if (_log.shouldLog(Log.ERROR)) - _log.error("Unable to bind on " + _listenPort); + _log.error("Unable to bind on " + _listenPort, se); } } @@ -45,11 +45,10 @@ public class UDPEndpoint { if (_sender != null) { _sender.shutdown(); _receiver.shutdown(); - _sender = null; - _receiver = null; } } + public void setListenPort(int newPort) { _listenPort = newPort; } public void updateListenPort(int newPort) { if (newPort == _listenPort) return; try { diff --git a/router/java/src/net/i2p/router/transport/udp/UDPPacket.java b/router/java/src/net/i2p/router/transport/udp/UDPPacket.java index ac7f600108ee74c194222795bab6f5ad4cf1f199..3443c502628b82dd0bc9fee382cf87bb47183488 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPPacket.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPPacket.java @@ -32,6 +32,7 @@ public class UDPPacket { private volatile byte[] _data; private volatile ByteArray _dataBuf; private volatile int _markedType; + private volatile RemoteHostId _remoteHost; private volatile boolean _released; private volatile Exception _releasedBy; private volatile Exception _acquiredBy; @@ -78,6 +79,7 @@ public class UDPPacket { _packet = new DatagramPacket(_data, MAX_PACKET_SIZE); _initializeTime = _context.clock().now(); _markedType = -1; + _remoteHost = null; } public void initialize(int priority, long expiration, InetAddress host, int port) { @@ -88,6 +90,7 @@ public class UDPPacket { //_packet.setLength(0); _packet.setAddress(host); _packet.setPort(port); + _remoteHost = null; _released = false; _releasedBy = null; } @@ -113,6 +116,12 @@ public class UDPPacket { */ public int getMarkedType() { verifyNotReleased(); return _markedType; } + public RemoteHostId getRemoteHost() { + if (_remoteHost == null) + _remoteHost = new RemoteHostId(_packet.getAddress().getAddress(), _packet.getPort()); + return _remoteHost; + } + /** * Validate the packet against the MAC specified, returning true if the * MAC matches, false otherwise. diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java index 63c8200139e2d6f4d7ad8f85de0349d8654b6ca3..4d00eb6fd3f82e091882d143811e67c11578dbb4 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -75,7 +75,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority /** shared slow bid for unconnected peers when we want to prefer UDP */ private TransportBid _slowPreferredBid; - public static final String STYLE = "SSUv1"; + public static final String STYLE = "SSU"; public static final String PROP_INTERNAL_PORT = "i2np.udp.internalPort"; /** define this to explicitly set an external IP address */ @@ -85,11 +85,12 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority /** * If i2np.udp.alwaysPreferred is set, the UDP bids will always be under * the bid from the TCP transport - even if a TCP connection already - * exists. The default is to prefer UDP unless no UDP session exists and - * a TCP connection already exists. + * exists. If this is true (the default), it will always prefer UDP, otherwise + * it will prefer UDP unless no UDP session exists and a TCP connection + * already exists. */ public static final String PROP_ALWAYS_PREFER_UDP = "i2np.udp.alwaysPreferred"; - + private static final String DEFAULT_ALWAYS_PREFER_UDP = "true"; /** how many relays offered to us will we use at a time? */ public static final int PUBLIC_RELAY_COUNT = 3; @@ -154,29 +155,35 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority rebuildExternalAddress(); - if (_endpoint == null) { - int port = -1; - if (_externalListenPort <= 0) { - // no explicit external port, so lets try an internal one - String portStr = _context.getProperty(PROP_INTERNAL_PORT); - if (portStr != null) { - try { - port = Integer.parseInt(portStr); - } catch (NumberFormatException nfe) { - if (_log.shouldLog(Log.ERROR)) - _log.error("Invalid port specified [" + portStr + "]"); - } - } - if (port <= 0) { - port = 1024 + _context.random().nextInt(31*1024); - if (_log.shouldLog(Log.INFO)) - _log.info("Selecting a random port to bind to: " + port); + int port = -1; + if (_externalListenPort <= 0) { + // no explicit external port, so lets try an internal one + String portStr = _context.getProperty(PROP_INTERNAL_PORT); + if (portStr != null) { + try { + port = Integer.parseInt(portStr); + } catch (NumberFormatException nfe) { + if (_log.shouldLog(Log.ERROR)) + _log.error("Invalid port specified [" + portStr + "]"); } - } else { - port = _externalListenPort; + } + if (port <= 0) { + port = 8887; + //port = 1024 + _context.random().nextInt(31*1024); if (_log.shouldLog(Log.INFO)) - _log.info("Binding to the explicitly specified external port: " + port); + _log.info("Selecting an arbitrary port to bind to: " + port); + _context.router().setConfigSetting(PROP_INTERNAL_PORT, port+""); + // attempt to use it as our external port - this will be overridden by + // externalAddressReceived(...) + _context.router().setConfigSetting(PROP_EXTERNAL_PORT, port+""); + _context.router().saveConfig(); } + } else { + port = _externalListenPort; + if (_log.shouldLog(Log.INFO)) + _log.info("Binding to the explicitly specified external port: " + port); + } + if (_endpoint == null) { try { _endpoint = new UDPEndpoint(_context, port); } catch (SocketException se) { @@ -184,6 +191,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority _log.log(Log.CRIT, "Unable to listen on the UDP port (" + port + ")", se); return; } + } else { + _endpoint.setListenPort(port); } if (_establisher == null) @@ -211,14 +220,14 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority } public void shutdown() { + if (_endpoint != null) + _endpoint.shutdown(); if (_flooder != null) _flooder.shutdown(); if (_refiller != null) _refiller.shutdown(); if (_handler != null) _handler.shutdown(); - if (_endpoint != null) - _endpoint.shutdown(); if (_fragments != null) _fragments.shutdown(); if (_pusher != null) @@ -268,6 +277,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority } } + _context.router().setConfigSetting(PROP_EXTERNAL_PORT, ourPort+""); + _context.router().saveConfig(); + if (updated) _context.router().rebuildRouterInfo(); } @@ -280,8 +292,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority * get the state for the peer at the given remote host/port, or null * if no state exists */ - public PeerState getPeerState(InetAddress remoteHost, int remotePort) { - RemoteHostId hostInfo = new RemoteHostId(remoteHost.getAddress(), remotePort); + public PeerState getPeerState(RemoteHostId hostInfo) { synchronized (_peersByRemoteHost) { return (PeerState)_peersByRemoteHost.get(hostInfo); } @@ -424,7 +435,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority } private boolean alwaysPreferUDP() { - String pref = _context.getProperty(PROP_ALWAYS_PREFER_UDP); + String pref = _context.getProperty(PROP_ALWAYS_PREFER_UDP, DEFAULT_ALWAYS_PREFER_UDP); return (pref != null) && "true".equals(pref); } diff --git a/router/java/src/net/i2p/router/tunnel/HopProcessor.java b/router/java/src/net/i2p/router/tunnel/HopProcessor.java index 5947fcc644251d38ad1872a9da357cb02daa27bd..6a3201e0ce57ef15a7d34829cf80697dcf921dcf 100644 --- a/router/java/src/net/i2p/router/tunnel/HopProcessor.java +++ b/router/java/src/net/i2p/router/tunnel/HopProcessor.java @@ -29,7 +29,7 @@ public class HopProcessor { * and after using it at each hop so as to prevent a certain type of replay/confirmation * attack. */ - static final boolean USE_DOUBLE_IV_ENCRYPTION = false; + static final boolean USE_DOUBLE_IV_ENCRYPTION = true; static final int IV_LENGTH = 16; private static final ByteCache _cache = ByteCache.getInstance(128, IV_LENGTH);