forked from I2P_Developers/i2p.i2p
Console: Properly register listen hosts with PortMapper
I2PTunnel: Fixup console links in error pages if console is on a non-standard host or port, or on https PortMapper: Add method to convert wildcard host to actual host
This commit is contained in:
@ -41,6 +41,7 @@ import net.i2p.util.EventDispatcher;
|
|||||||
import net.i2p.util.InternalSocket;
|
import net.i2p.util.InternalSocket;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
import net.i2p.util.PasswordManager;
|
import net.i2p.util.PasswordManager;
|
||||||
|
import net.i2p.util.PortMapper;
|
||||||
import net.i2p.util.Translate;
|
import net.i2p.util.Translate;
|
||||||
import net.i2p.util.TranslateReader;
|
import net.i2p.util.TranslateReader;
|
||||||
|
|
||||||
@ -535,7 +536,24 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
|
|||||||
while((len = reader.read(buf)) > 0) {
|
while((len = reader.read(buf)) > 0) {
|
||||||
out.append(buf, 0, len);
|
out.append(buf, 0, len);
|
||||||
}
|
}
|
||||||
return out.toString();
|
String rv = out.toString();
|
||||||
|
// Do we need to replace http://127.0.0.1:7657 console links in the error page?
|
||||||
|
// Get the registered host and port from the PortMapper.
|
||||||
|
final String unset = "*unset*";
|
||||||
|
final String httpHost = ctx.portMapper().getActualHost(PortMapper.SVC_CONSOLE, unset);
|
||||||
|
final String httpsHost = ctx.portMapper().getActualHost(PortMapper.SVC_HTTPS_CONSOLE, unset);
|
||||||
|
final int httpPort = ctx.portMapper().getPort(PortMapper.SVC_CONSOLE, 7657);
|
||||||
|
final int httpsPort = ctx.portMapper().getPort(PortMapper.SVC_HTTPS_CONSOLE, -1);
|
||||||
|
final boolean httpsOnly = httpsPort > 0 && httpHost.equals(unset) && !httpsHost.equals(unset);
|
||||||
|
final int port = httpsOnly ? httpsPort : httpPort;
|
||||||
|
String host = httpsOnly ? httpsHost : httpHost;
|
||||||
|
if (host.equals(unset))
|
||||||
|
host = "127.0.0.1";
|
||||||
|
if (httpsOnly || port != 7657 || !host.equals("127.0.0.1")) {
|
||||||
|
String url = (httpsOnly ? "https://" : "http://") + host + ':' + port;
|
||||||
|
rv = rv.replace("http://127.0.0.1:7657", url);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
if(reader != null)
|
if(reader != null)
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
package net.i2p.router.web;
|
package net.i2p.router.web;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.awt.GraphicsEnvironment;
|
import java.awt.GraphicsEnvironment;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FilenameFilter;
|
import java.io.FilenameFilter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -442,6 +445,7 @@ public class RouterConsoleRunner implements RouterApp {
|
|||||||
System.err.println("Bad routerconsole port " + _listenPort);
|
System.err.println("Bad routerconsole port " + _listenPort);
|
||||||
}
|
}
|
||||||
if (lport > 0) {
|
if (lport > 0) {
|
||||||
|
List<String> hosts = new ArrayList<String>(2);
|
||||||
StringTokenizer tok = new StringTokenizer(_listenHost, " ,");
|
StringTokenizer tok = new StringTokenizer(_listenHost, " ,");
|
||||||
while (tok.hasMoreTokens()) {
|
while (tok.hasMoreTokens()) {
|
||||||
String host = tok.nextToken().trim();
|
String host = tok.nextToken().trim();
|
||||||
@ -490,13 +494,20 @@ public class RouterConsoleRunner implements RouterApp {
|
|||||||
//_server.addConnector(lsnr);
|
//_server.addConnector(lsnr);
|
||||||
connectors.add(lsnr);
|
connectors.add(lsnr);
|
||||||
boundAddresses++;
|
boundAddresses++;
|
||||||
|
hosts.add(host);
|
||||||
} catch (Exception ioe) {
|
} catch (Exception ioe) {
|
||||||
System.err.println("Unable to bind routerconsole to " + host + " port " + _listenPort + ": " + ioe);
|
System.err.println("Unable to bind routerconsole to " + host + " port " + _listenPort + ": " + ioe);
|
||||||
System.err.println("You may ignore this warning if the console is still available at http://localhost:" + _listenPort);
|
System.err.println("You may ignore this warning if the console is still available at http://localhost:" + _listenPort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// XXX: what if listenhosts do not include 127.0.0.1? (Should that ever even happen?)
|
if (hosts.isEmpty()) {
|
||||||
_context.portMapper().register(PortMapper.SVC_CONSOLE,lport);
|
_context.portMapper().register(PortMapper.SVC_CONSOLE, lport);
|
||||||
|
} else {
|
||||||
|
// put IPv4 first
|
||||||
|
Collections.sort(hosts, new HostComparator());
|
||||||
|
_context.portMapper().register(PortMapper.SVC_CONSOLE, hosts.get(0), lport);
|
||||||
|
// note that we could still fail in connector.start() below
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add SSL listeners
|
// add SSL listeners
|
||||||
@ -520,6 +531,7 @@ public class RouterConsoleRunner implements RouterApp {
|
|||||||
new String[I2PSSLSocketFactory.EXCLUDE_PROTOCOLS.size()]));
|
new String[I2PSSLSocketFactory.EXCLUDE_PROTOCOLS.size()]));
|
||||||
sslFactory.addExcludeCipherSuites(I2PSSLSocketFactory.EXCLUDE_CIPHERS.toArray(
|
sslFactory.addExcludeCipherSuites(I2PSSLSocketFactory.EXCLUDE_CIPHERS.toArray(
|
||||||
new String[I2PSSLSocketFactory.EXCLUDE_CIPHERS.size()]));
|
new String[I2PSSLSocketFactory.EXCLUDE_CIPHERS.size()]));
|
||||||
|
List<String> hosts = new ArrayList<String>(2);
|
||||||
StringTokenizer tok = new StringTokenizer(_sslListenHost, " ,");
|
StringTokenizer tok = new StringTokenizer(_sslListenHost, " ,");
|
||||||
while (tok.hasMoreTokens()) {
|
while (tok.hasMoreTokens()) {
|
||||||
String host = tok.nextToken().trim();
|
String host = tok.nextToken().trim();
|
||||||
@ -561,6 +573,7 @@ public class RouterConsoleRunner implements RouterApp {
|
|||||||
//_server.addConnector(ssll);
|
//_server.addConnector(ssll);
|
||||||
connectors.add(ssll);
|
connectors.add(ssll);
|
||||||
boundAddresses++;
|
boundAddresses++;
|
||||||
|
hosts.add(host);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("Unable to bind routerconsole to " + host + " port " + sslPort + " for SSL: " + e);
|
System.err.println("Unable to bind routerconsole to " + host + " port " + sslPort + " for SSL: " + e);
|
||||||
if (SystemVersion.isGNU())
|
if (SystemVersion.isGNU())
|
||||||
@ -568,7 +581,14 @@ public class RouterConsoleRunner implements RouterApp {
|
|||||||
System.err.println("You may ignore this warning if the console is still available at https://localhost:" + sslPort);
|
System.err.println("You may ignore this warning if the console is still available at https://localhost:" + sslPort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_context.portMapper().register(PortMapper.SVC_HTTPS_CONSOLE,sslPort);
|
if (hosts.isEmpty()) {
|
||||||
|
_context.portMapper().register(PortMapper.SVC_HTTPS_CONSOLE, sslPort);
|
||||||
|
} else {
|
||||||
|
// put IPv4 first
|
||||||
|
Collections.sort(hosts, new HostComparator());
|
||||||
|
_context.portMapper().register(PortMapper.SVC_HTTPS_CONSOLE, hosts.get(0), sslPort);
|
||||||
|
// note that we could still fail in connector.start() below
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
System.err.println("Unable to create or access keystore for SSL: " + keyStore.getAbsolutePath());
|
System.err.println("Unable to create or access keystore for SSL: " + keyStore.getAbsolutePath());
|
||||||
}
|
}
|
||||||
@ -898,6 +918,21 @@ public class RouterConsoleRunner implements RouterApp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put IPv4 first
|
||||||
|
* @since 0.9.24
|
||||||
|
*/
|
||||||
|
private static class HostComparator implements Comparator<String>, Serializable {
|
||||||
|
public int compare(String l, String r) {
|
||||||
|
boolean l4 = l.contains(".");
|
||||||
|
boolean r4 = r.contains(".");
|
||||||
|
if (l4 && !r4)
|
||||||
|
return -1;
|
||||||
|
if (r4 && !l4)
|
||||||
|
return 1;
|
||||||
|
return l.compareTo(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just to set the name and set Daemon
|
* Just to set the name and set Daemon
|
||||||
|
@ -6,6 +6,7 @@ import java.net.InetSocketAddress;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
@ -110,6 +111,68 @@ public class PortMapper {
|
|||||||
return ia.getHostName();
|
return ia.getHostName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the actual host for a service.
|
||||||
|
* Will return "127.0.0.1" if the service was registered without a host.
|
||||||
|
* If the service was registered with the host "0.0.0.0", "::", or "0:0:0:0:0:0:0:0",
|
||||||
|
* it will return a public IP if we have one,
|
||||||
|
* else a local IP if we have one, else def.
|
||||||
|
* If it was not registered with a wildcard address, it will return the registered host.
|
||||||
|
*
|
||||||
|
* @param def default
|
||||||
|
* @return def if not registered
|
||||||
|
* @since 0.9.24
|
||||||
|
*/
|
||||||
|
public String getActualHost(String service, String def) {
|
||||||
|
InetSocketAddress ia = _dir.get(service);
|
||||||
|
if (ia == null)
|
||||||
|
return def;
|
||||||
|
return convertWildcard(ia.getHostName(), def);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See above
|
||||||
|
* @param def default
|
||||||
|
* @return def if no ips
|
||||||
|
* @since 0.9.24
|
||||||
|
*/
|
||||||
|
private static String convertWildcard(String ip, String def) {
|
||||||
|
String rv = ip;
|
||||||
|
if (rv.equals("0.0.0.0")) {
|
||||||
|
// public
|
||||||
|
rv = Addresses.getAnyAddress();
|
||||||
|
if (rv == null) {
|
||||||
|
rv = def;
|
||||||
|
// local
|
||||||
|
Set<String> addrs = Addresses.getAddresses(true, false);
|
||||||
|
for (String addr : addrs) {
|
||||||
|
if (!addr.startsWith("127.") && !addr.equals("0.0.0.0")) {
|
||||||
|
rv = addr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (rv.equals("::") || rv.equals("0:0:0:0:0:0:0:0")) {
|
||||||
|
rv = def;
|
||||||
|
// public
|
||||||
|
Set<String> addrs = Addresses.getAddresses(false, true);
|
||||||
|
for (String addr : addrs) {
|
||||||
|
if (!addr.contains(".")) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// local
|
||||||
|
addrs = Addresses.getAddresses(true, true);
|
||||||
|
for (String addr : addrs) {
|
||||||
|
if (!addr.contains(".") && !addr.equals("::") && !addr.equals("0:0:0:0:0:0:0:0")) {
|
||||||
|
rv = addr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For debugging only
|
* For debugging only
|
||||||
* @since 0.9.20
|
* @since 0.9.20
|
||||||
@ -122,7 +185,7 @@ public class PortMapper {
|
|||||||
InetSocketAddress ia = _dir.get(s);
|
InetSocketAddress ia = _dir.get(s);
|
||||||
if (ia == null)
|
if (ia == null)
|
||||||
continue;
|
continue;
|
||||||
out.write("<tr><td>" + s + "<td>" + ia.getHostName() + "<td>" + ia.getPort() + '\n');
|
out.write("<tr><td>" + s + "<td>" + convertWildcard(ia.getHostName(), "127.0.0.1") + "<td>" + ia.getPort() + '\n');
|
||||||
}
|
}
|
||||||
out.write("</table>\n");
|
out.write("</table>\n");
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user