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.Log;
|
||||
import net.i2p.util.PasswordManager;
|
||||
import net.i2p.util.PortMapper;
|
||||
import net.i2p.util.Translate;
|
||||
import net.i2p.util.TranslateReader;
|
||||
|
||||
@ -535,7 +536,24 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
|
||||
while((len = reader.read(buf)) > 0) {
|
||||
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 {
|
||||
try {
|
||||
if(reader != null)
|
||||
|
@ -1,14 +1,17 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -442,6 +445,7 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
System.err.println("Bad routerconsole port " + _listenPort);
|
||||
}
|
||||
if (lport > 0) {
|
||||
List<String> hosts = new ArrayList<String>(2);
|
||||
StringTokenizer tok = new StringTokenizer(_listenHost, " ,");
|
||||
while (tok.hasMoreTokens()) {
|
||||
String host = tok.nextToken().trim();
|
||||
@ -490,13 +494,20 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
//_server.addConnector(lsnr);
|
||||
connectors.add(lsnr);
|
||||
boundAddresses++;
|
||||
hosts.add(host);
|
||||
} catch (Exception 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);
|
||||
}
|
||||
}
|
||||
// XXX: what if listenhosts do not include 127.0.0.1? (Should that ever even happen?)
|
||||
_context.portMapper().register(PortMapper.SVC_CONSOLE,lport);
|
||||
if (hosts.isEmpty()) {
|
||||
_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
|
||||
@ -520,6 +531,7 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
new String[I2PSSLSocketFactory.EXCLUDE_PROTOCOLS.size()]));
|
||||
sslFactory.addExcludeCipherSuites(I2PSSLSocketFactory.EXCLUDE_CIPHERS.toArray(
|
||||
new String[I2PSSLSocketFactory.EXCLUDE_CIPHERS.size()]));
|
||||
List<String> hosts = new ArrayList<String>(2);
|
||||
StringTokenizer tok = new StringTokenizer(_sslListenHost, " ,");
|
||||
while (tok.hasMoreTokens()) {
|
||||
String host = tok.nextToken().trim();
|
||||
@ -561,6 +573,7 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
//_server.addConnector(ssll);
|
||||
connectors.add(ssll);
|
||||
boundAddresses++;
|
||||
hosts.add(host);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Unable to bind routerconsole to " + host + " port " + sslPort + " for SSL: " + e);
|
||||
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);
|
||||
}
|
||||
}
|
||||
_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 {
|
||||
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
|
||||
|
@ -6,6 +6,7 @@ import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
@ -110,6 +111,68 @@ public class PortMapper {
|
||||
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
|
||||
* @since 0.9.20
|
||||
@ -122,7 +185,7 @@ public class PortMapper {
|
||||
InetSocketAddress ia = _dir.get(s);
|
||||
if (ia == null)
|
||||
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");
|
||||
}
|
||||
|
Reference in New Issue
Block a user