From 0cfbe9c28bee462f0daf137cc262332c6c85a5d4 Mon Sep 17 00:00:00 2001 From: zzz Date: Wed, 8 Apr 2009 01:34:12 +0000 Subject: [PATCH] * IPV6/localhost: - Enable IPv6 stack in the JVM, hopefully won't break anything - Patch Jetty to support binding to IPv6 addresses - Allow multiple bind addresses for the router console in the clients.config file; for new installs the default is now "127.0.0.1,::1" - Change most instances of "localhost" to "127.0.0.1" throughout the code * Router: - Move some classes to private static inner --- .../java/src/addressbook/Daemon.java | 2 +- .../src/org/klomp/snark/SnarkManager.java | 4 +- .../src/net/i2p/i2ptunnel/web/EditBean.java | 2 +- .../src/org/mortbay/util/InetAddrPort.java | 253 ++++++++++++++++++ .../streaming/I2PSocketManagerFactory.java | 2 +- .../i2p/router/web/ConfigServiceHandler.java | 2 +- .../i2p/router/web/ConfigUpdateHandler.java | 2 +- .../i2p/router/web/RouterConsoleRunner.java | 35 ++- apps/routerconsole/jsp/configservice.jsp | 2 +- apps/routerconsole/jsp/nav.jsp | 2 +- .../src/src/i2p/susi/webmail/WebMail.java | 2 +- .../src/net/i2p/apps/systray/SysTray.java | 4 +- .../src/net/i2p/apps/systray/UrlLauncher.java | 2 +- .../src/net/i2p/client/I2PSessionImpl.java | 2 +- core/java/src/net/i2p/util/EepGet.java | 8 +- .../resources/ahelper-conflict-header.ht | 6 +- installer/resources/clients.config | 6 +- installer/resources/dnf-header.ht | 6 +- installer/resources/dnfb-header.ht | 6 +- installer/resources/dnfh-header.ht | 10 +- installer/resources/dnfp-header.ht | 10 +- installer/resources/eepsite_index.html | 20 +- installer/resources/startconsole.html | 4 +- router/java/src/net/i2p/router/Router.java | 20 +- 24 files changed, 349 insertions(+), 63 deletions(-) create mode 100644 apps/jetty/java/src/org/mortbay/util/InetAddrPort.java diff --git a/apps/addressbook/java/src/addressbook/Daemon.java b/apps/addressbook/java/src/addressbook/Daemon.java index 7b690eb17..a1b1ae18a 100644 --- a/apps/addressbook/java/src/addressbook/Daemon.java +++ b/apps/addressbook/java/src/addressbook/Daemon.java @@ -133,7 +133,7 @@ public class Daemon { } Map defaultSettings = new HashMap(); - defaultSettings.put("proxy_host", "localhost"); + defaultSettings.put("proxy_host", "127.0.0.1"); defaultSettings.put("proxy_port", "4444"); defaultSettings.put("master_addressbook", "../userhosts.txt"); defaultSettings.put("router_addressbook", "../hosts.txt"); diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index 01a93a58c..60c44f3d5 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -135,13 +135,13 @@ public class SnarkManager implements Snark.CompleteListener { } // now add sane defaults if (!_config.containsKey(PROP_I2CP_HOST)) - _config.setProperty(PROP_I2CP_HOST, "localhost"); + _config.setProperty(PROP_I2CP_HOST, "127.0.0.1"); if (!_config.containsKey(PROP_I2CP_PORT)) _config.setProperty(PROP_I2CP_PORT, "7654"); if (!_config.containsKey(PROP_I2CP_OPTS)) _config.setProperty(PROP_I2CP_OPTS, "inbound.length=2 inbound.lengthVariance=0 outbound.length=2 outbound.lengthVariance=0 inbound.quantity=3 outbound.quantity=3"); if (!_config.containsKey(PROP_EEP_HOST)) - _config.setProperty(PROP_EEP_HOST, "localhost"); + _config.setProperty(PROP_EEP_HOST, "127.0.0.1"); if (!_config.containsKey(PROP_EEP_PORT)) _config.setProperty(PROP_EEP_PORT, "4444"); if (!_config.containsKey(PROP_UPLOADERS_TOTAL)) diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java index 004114b56..0a909c62e 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java @@ -206,7 +206,7 @@ public class EditBean extends IndexBean { if (tun != null) return tun.getI2CPHost(); else - return "localhost"; + return "127.0.0.1"; } public String getI2CPPort(int tunnel) { diff --git a/apps/jetty/java/src/org/mortbay/util/InetAddrPort.java b/apps/jetty/java/src/org/mortbay/util/InetAddrPort.java new file mode 100644 index 000000000..7f0968798 --- /dev/null +++ b/apps/jetty/java/src/org/mortbay/util/InetAddrPort.java @@ -0,0 +1,253 @@ +// ======================================================================== +// $Id: InetAddrPort.java,v 1.7 2004/10/23 09:03:22 gregwilkins Exp $ +// Copyright 1996-2004 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ======================================================================== + +package org.mortbay.util; + +import java.io.Serializable; +import java.net.InetAddress; + +/* ======================================================================== */ +/** InetAddress and Port. + */ +public class InetAddrPort implements Serializable +{ + /* ------------------------------------------------------------ */ + public final static String __0_0_0_0 = "0.0.0.0"; + + /* ------------------------------------------------------------ */ + private InetAddress _addr=null; + private boolean _addrIsHost=false; + private int _port=0; + + /* ------------------------------------------------------------------- */ + public InetAddrPort() + {} + + /* ------------------------------------------------------------ */ + /** Constructor for a port on all local host address. + * @param port + */ + public InetAddrPort(int port) + { + _port=port; + } + + /* ------------------------------------------------------------ */ + /** Constructor. + * @param addr + * @param port + */ + public InetAddrPort(InetAddress addr, int port) + { + _addr=addr; + _port=port; + } + + /* ------------------------------------------------------------ */ + /** Constructor. + * @param host + * @param port + */ + public InetAddrPort(String host, int port) + throws java.net.UnknownHostException + { + setHost(host); + setPort(port); + } + + /* ------------------------------------------------------------ */ + /** Constructor. + * Patched to support [::1]:port for I2P + * + * @param inetAddrPort String of the form "addr:port" + */ + public InetAddrPort(String inetAddrPort) + throws java.net.UnknownHostException + { + int b = inetAddrPort.indexOf('['); + if (b>0) + throw new java.net.UnknownHostException("Bad [] syntax"); + if (b==0) // IPV6 + { + int b2 = inetAddrPort.indexOf(']'); + if (b2<2) + throw new java.net.UnknownHostException("Bad [] syntax"); + String addr=inetAddrPort.substring(1,b2); + if (addr.indexOf('/')>0) + addr=addr.substring(addr.indexOf('/')+1); + inetAddrPort=inetAddrPort.substring(b2+1); + int c = inetAddrPort.indexOf(':'); + if (c>0) + throw new java.net.UnknownHostException("Bad [] syntax"); + if (c==0) + inetAddrPort=inetAddrPort.substring(1); + + if (addr.length()>0 && ! __0_0_0_0.equals(addr)) + { + _addrIsHost=!Character.isDigit((addr.charAt(0))); + this._addr=InetAddress.getByName(addr); + } + } else { // IPV4 + int c = inetAddrPort.indexOf(':'); + if (c>=0) + { + String addr=inetAddrPort.substring(0,c); + if (addr.indexOf('/')>0) + addr=addr.substring(addr.indexOf('/')+1); + inetAddrPort=inetAddrPort.substring(c+1); + + if (addr.length()>0 && ! __0_0_0_0.equals(addr)) + { + _addrIsHost=!Character.isDigit((addr.charAt(0))); + this._addr=InetAddress.getByName(addr); + } + } + } + + _port = Integer.parseInt(inetAddrPort); + } + + /* ------------------------------------------------------------ */ + /** Constructor. + * @param address InetAddrPort top copy. + */ + public InetAddrPort(InetAddrPort address) + { + if (address!=null) + { + _addr=address._addr; + _port=address._port; + } + } + + /* ------------------------------------------------------------ */ + /** Get the Host. + * @return The IP address + */ + public String getHost() + { + if (_addr==null) + return __0_0_0_0; + + return _addrIsHost?_addr.getHostName():_addr.getHostAddress(); + } + + /* ------------------------------------------------------------ */ + /** Set the Host. + * @param host + * @exception java.net.UnknownHostException + */ + public void setHost(String host) + throws java.net.UnknownHostException + { + _addr=null; + if (host!=null) + { + if (host.indexOf('/')>0) + host=host.substring(0,host.indexOf('/')); + _addrIsHost=!Character.isDigit((host.charAt(0))); + _addr=InetAddress.getByName(host); + } + } + + /* ------------------------------------------------------------ */ + /** Get the IP address. + * @return The IP address + */ + public InetAddress getInetAddress() + { + return _addr; + } + + /* ------------------------------------------------------------ */ + /** Set the IP address. + * @param addr The IP address + */ + public void setInetAddress(InetAddress addr) + { + _addrIsHost=false; + _addr=addr; + } + + /* ------------------------------------------------------------ */ + /** Get the port. + * @return The port number + */ + public int getPort() + { + return _port; + } + + /* ------------------------------------------------------------ */ + /** Set the port. + * @param port The port number + */ + public void setPort(int port) + { + _port=port; + } + + + /* ------------------------------------------------------------------- */ + public String toString() + { + return getHost()+':'+_port; + } + + /* ------------------------------------------------------------ */ + /** Clone the InetAddrPort. + * @return A new instance. + */ + public Object clone() + { + return new InetAddrPort(this); + } + + /* ------------------------------------------------------------ */ + /** Hash Code. + * @return hash Code. + */ + public int hashCode() + { + return _port+((_addr==null)?0:_addr.hashCode()); + } + + /* ------------------------------------------------------------ */ + /** Equals. + * @param o + * @return True if is the same address and port. + */ + public boolean equals(Object o) + { + if (o==null) + return false; + if (o==this) + return true; + if (o instanceof InetAddrPort) + { + InetAddrPort addr=(InetAddrPort)o; + return addr._port==_port && + ( addr._addr==_addr || + addr._addr!=null && addr._addr.equals(_addr)); + } + return false; + } +} + + + + + + diff --git a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketManagerFactory.java b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketManagerFactory.java index 33477a4a8..0370ab16b 100644 --- a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketManagerFactory.java +++ b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketManagerFactory.java @@ -196,7 +196,7 @@ public class I2PSocketManagerFactory { } private static String getHost() { - return System.getProperty(I2PClient.PROP_TCP_HOST, "localhost"); + return System.getProperty(I2PClient.PROP_TCP_HOST, "127.0.0.1"); } private static int getPort() { int i2cpPort = 7654; diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java index 8d3e5725c..0dc4d1e62 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java @@ -155,7 +155,7 @@ public class ConfigServiceHandler extends FormHandler { } // releases <= 0.6.5 deleted the entry completely if (shouldLaunchBrowser && !found) { - ClientAppConfig ca = new ClientAppConfig(UrlLauncher.class.getName(), "consoleBrowser", "http://localhost:7657", 5, false); + ClientAppConfig ca = new ClientAppConfig(UrlLauncher.class.getName(), "consoleBrowser", "http://127.0.0.1:7657", 5, false); clients.add(ca); } ClientAppConfig.writeClientAppConfig(_context, clients); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java index 3c6e1692c..1729a209b 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java @@ -27,7 +27,7 @@ public class ConfigUpdateHandler extends FormHandler { public static final String PROP_SHOULD_PROXY = "router.updateThroughProxy"; public static final String DEFAULT_SHOULD_PROXY = Boolean.TRUE.toString(); public static final String PROP_PROXY_HOST = "router.updateProxyHost"; - public static final String DEFAULT_PROXY_HOST = "localhost"; + public static final String DEFAULT_PROXY_HOST = "127.0.0.1"; public static final String PROP_PROXY_PORT = "router.updateProxyPort"; public static final String DEFAULT_PROXY_PORT = "4444"; diff --git a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java index ae11e55fb..862902b1f 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java @@ -5,6 +5,7 @@ import java.io.FilenameFilter; import java.io.IOException; import java.util.List; import java.util.Properties; +import java.util.StringTokenizer; import net.i2p.I2PAppContext; import net.i2p.apps.systray.SysTray; @@ -36,6 +37,14 @@ public class RouterConsoleRunner { System.setProperty("java.awt.headless", "true"); } + /** + * @param args second arg may be a comma-separated list of bind addresses, + * for example ::1,127.0.0.1 + * On XP, the other order (127.0.0.1,::1) fails the IPV6 bind, + * because 127.0.0.1 will bind ::1 also. But even though it's bound + * to both, we can't connect to [::1]:7657 for some reason. + * So the wise choice is ::1,127.0.0.1 + */ public RouterConsoleRunner(String args[]) { if (args.length == 3) { _listenPort = args[0].trim(); @@ -66,7 +75,24 @@ public class RouterConsoleRunner { rewrite = true; } try { - _server.addListener(_listenHost + ':' + _listenPort); + StringTokenizer tok = new StringTokenizer(_listenHost, " ,"); + int boundAddresses = 0; + while (tok.hasMoreTokens()) { + String host = tok.nextToken().trim(); + try { + if (host.indexOf(":") >= 0) // IPV6 - requires patched Jetty 5 + _server.addListener('[' + host + "]:" + _listenPort); + else + _server.addListener(host + ':' + _listenPort); + boundAddresses++; + } catch (IOException ioe) { // this doesn't seem to work, exceptions don't happen until start() below + System.err.println("Unable to bind routerconsole to " + host + " port " + _listenPort + ' ' + ioe); + } + } + if (boundAddresses <= 0) { + System.err.println("Unable to bind routerconsole to any address on port " + _listenPort); + return; + } _server.setRootWebApp(ROUTERCONSOLE); WebApplicationContext wac = _server.addWebApplication("/", _webAppsDir + ROUTERCONSOLE + ".war"); initialize(wac); @@ -100,7 +126,12 @@ public class RouterConsoleRunner { try { _server.start(); } catch (Exception me) { - me.printStackTrace(); + System.err.println("WARNING: Error starting one or more listeners of the Router Console server.\n" + + "If your console is still accessible at http://127.0.0.1:7657/,\n" + + "this may be a problem only with binding to the IPV6 address ::1.\n" + + "If so, you may ignore this error, or remove the\n" + + "\"::1,\" in the \"clientApp.0.args\" line of the clients.config file.\n" + + "Exception: " + me); } try { SysTray tray = SysTray.getInstance(); diff --git a/apps/routerconsole/jsp/configservice.jsp b/apps/routerconsole/jsp/configservice.jsp index 59dfc3e75..4a720afee 100644 --- a/apps/routerconsole/jsp/configservice.jsp +++ b/apps/routerconsole/jsp/configservice.jsp @@ -71,7 +71,7 @@

Launch browser on router startup?

I2P's main configuration interface is this web console, so for your convenience I2P can launch a web browser pointing at - http://localhost:7657/index.jsp whenever + http://127.0.0.1:7657/index.jsp whenever the router starts up.

diff --git a/apps/routerconsole/jsp/nav.jsp b/apps/routerconsole/jsp/nav.jsp index 22bb8ec24..914371c78 100644 --- a/apps/routerconsole/jsp/nav.jsp +++ b/apps/routerconsole/jsp/nav.jsp @@ -25,7 +25,7 @@ SusiDNS | I2PSnark | - My Eepsite
+ My Eepsite
I2PTunnel | Tunnels | Profiles | diff --git a/apps/susimail/src/src/i2p/susi/webmail/WebMail.java b/apps/susimail/src/src/i2p/susi/webmail/WebMail.java index a80fdc591..6e9fad1c5 100644 --- a/apps/susimail/src/src/i2p/susi/webmail/WebMail.java +++ b/apps/susimail/src/src/i2p/susi/webmail/WebMail.java @@ -76,7 +76,7 @@ public class WebMail extends HttpServlet private static final int BUFSIZE = 4096; - private static final String DEFAULT_HOST = "localhost"; + private static final String DEFAULT_HOST = "127.0.0.1"; private static final int DEFAULT_POP3PORT = 7660; private static final int DEFAULT_SMTPPORT = 7659; diff --git a/apps/systray/java/src/net/i2p/apps/systray/SysTray.java b/apps/systray/java/src/net/i2p/apps/systray/SysTray.java index 4a635fd08..652ff6677 100644 --- a/apps/systray/java/src/net/i2p/apps/systray/SysTray.java +++ b/apps/systray/java/src/net/i2p/apps/systray/SysTray.java @@ -132,7 +132,7 @@ public class SysTray implements SysTrayMenuListener { public void iconLeftClicked(SysTrayMenuEvent e) {} public void iconLeftDoubleClicked(SysTrayMenuEvent e) { - openRouterConsole("http://localhost:" + _portString + "/index.jsp"); + openRouterConsole("http://127.0.0.1:" + _portString + "/index.jsp"); } public void menuItemSelected(SysTrayMenuEvent e) { @@ -153,7 +153,7 @@ public class SysTray implements SysTrayMenuListener { if (!(browser = promptForBrowser("Select browser")).equals("nullnull")) setBrowser(browser); } else if (e.getActionCommand().equals("openconsole")) { - openRouterConsole("http://localhost:" + _portString + "/index.jsp"); + openRouterConsole("http://127.0.0.1:" + _portString + "/index.jsp"); } } diff --git a/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java b/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java index 5487f5faf..c7524054e 100644 --- a/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java +++ b/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java @@ -163,7 +163,7 @@ public class UrlLauncher { if (args.length > 0) launcher.openUrl(args[0]); else - launcher.openUrl("http://localhost:7657/index.jsp"); + launcher.openUrl("http://127.0.0.1:7657/index.jsp"); } catch (Exception e) {} } } diff --git a/core/java/src/net/i2p/client/I2PSessionImpl.java b/core/java/src/net/i2p/client/I2PSessionImpl.java index 5b7603fdd..9e42eef5f 100644 --- a/core/java/src/net/i2p/client/I2PSessionImpl.java +++ b/core/java/src/net/i2p/client/I2PSessionImpl.java @@ -162,7 +162,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa protected void loadConfig(Properties options) { _options = new Properties(); _options.putAll(filter(options)); - _hostname = _options.getProperty(I2PClient.PROP_TCP_HOST, "localhost"); + _hostname = _options.getProperty(I2PClient.PROP_TCP_HOST, "127.0.0.1"); String portNum = _options.getProperty(I2PClient.PROP_TCP_PORT, LISTEN_PORT + ""); try { _portNum = Integer.parseInt(portNum); diff --git a/core/java/src/net/i2p/util/EepGet.java b/core/java/src/net/i2p/util/EepGet.java index 4abdc6fd4..5f0e8d5e9 100644 --- a/core/java/src/net/i2p/util/EepGet.java +++ b/core/java/src/net/i2p/util/EepGet.java @@ -18,7 +18,7 @@ import net.i2p.I2PAppContext; import net.i2p.data.DataHelper; /** - * EepGet [-p localhost:4444] + * EepGet [-p 127.0.0.1:4444] * [-n #retries] * [-o outputFile] * [-m markSize lineLen] @@ -123,11 +123,11 @@ public class EepGet { } /** - * EepGet [-p localhost:4444] [-n #retries] [-e etag] [-o outputFile] [-m markSize lineLen] url + * EepGet [-p 127.0.0.1:4444] [-n #retries] [-e etag] [-o outputFile] [-m markSize lineLen] url * */ public static void main(String args[]) { - String proxyHost = "localhost"; + String proxyHost = "127.0.0.1"; int proxyPort = 4444; int numRetries = 5; int markSize = 1024; @@ -212,7 +212,7 @@ public class EepGet { } private static void usage() { - System.err.println("EepGet [-p localhost:4444] [-n #retries] [-o outputFile] [-m markSize lineLen] [-t timeout] url"); + System.err.println("EepGet [-p 127.0.0.1:4444] [-n #retries] [-o outputFile] [-m markSize lineLen] [-t timeout] url"); } public static interface StatusListener { diff --git a/installer/resources/ahelper-conflict-header.ht b/installer/resources/ahelper-conflict-header.ht index 3b80e582f..7f34d21cc 100644 --- a/installer/resources/ahelper-conflict-header.ht +++ b/installer/resources/ahelper-conflict-header.ht @@ -6,7 +6,7 @@ Proxy-Connection: close Destination key conflict - +