avoiding excessive DNS lookups to determine localhost

git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@6750 6c8d7289-2bf4-0310-a012-ef5d649a1542
pull/1/head
orbiter 15 years ago
parent 11983bc936
commit e820ed061a

@ -25,11 +25,11 @@
import java.util.Random;
import net.yacy.kelondro.data.meta.DigestURI;
import net.yacy.kelondro.util.Domains;
import de.anomic.crawler.ResultImages;
import de.anomic.http.server.RequestHeader;
import de.anomic.search.Switchboard;
import de.anomic.server.serverCore;
import de.anomic.server.serverObjects;
import de.anomic.server.serverSwitch;
@ -95,7 +95,7 @@ public class Collage {
// check if this loads a page from localhost, which must be prevented to protect the server
// against attacks to the administration interface when localhost access is granted
if ((serverCore.isLocalhost(baseURL.getHost()) || serverCore.isLocalhost(imageURL.getHost())) &&
if ((Domains.isLocal(baseURL.getHost()) || Domains.isLocal(imageURL.getHost())) &&
sb.getConfigBool("adminAccountForLocalhost", false)) continue;
final long z = imgZIndex[i];

@ -71,9 +71,7 @@ import java.io.UnsupportedEncodingException;
import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.URLDecoder;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
@ -90,6 +88,7 @@ import net.yacy.kelondro.data.meta.DigestURI;
import net.yacy.kelondro.logging.Log;
import net.yacy.kelondro.util.ByteBuffer;
import net.yacy.kelondro.util.DateFormatter;
import net.yacy.kelondro.util.Domains;
import net.yacy.kelondro.util.FileUtils;
import net.yacy.kelondro.util.MemoryControl;
import net.yacy.visualization.RasterPlotter;
@ -295,12 +294,7 @@ public final class HTTPDFileHandler {
final boolean adminAccountForLocalhost = sb.getConfigBool("adminAccountForLocalhost", false);
final String refererHost = requestHeader.refererHost();
boolean accessFromLocalhost = serverCore.isLocalhost(clientIP) && (refererHost.length() == 0 || serverCore.isLocalhost(refererHost));
if (!accessFromLocalhost) try {
// the access may also be from a different IP than localhost if it is the same as the YaCy instance is running on
InetAddress myaddress = InetAddress.getLocalHost();
accessFromLocalhost = myaddress.equals(InetAddress.getByName(clientIP)) && (refererHost.length() == 0 || myaddress.equals(InetAddress.getByName(refererHost)));
} catch (UnknownHostException e) {}
boolean accessFromLocalhost = Domains.isLocal(clientIP) && (refererHost.length() == 0 || Domains.isLocal(refererHost));
final boolean grantedForLocalhost = adminAccountForLocalhost && accessFromLocalhost;
final boolean protectedPage = path.indexOf("_p.") > 0;
final boolean accountEmpty = adminAccountBase64MD5.length() == 0;

@ -72,7 +72,7 @@ public class UPnP {
boolean init = true;
try {
if (IGDs == null) IGDs = InternetGatewayDevice.getDevices(discoveryTimeout);
localHostIP = Domains.localHostAddress.getHostAddress();
localHostIP = Domains.myPublicLocalIP().getHostAddress();
} catch (IOException e) {
init = false;
}

@ -41,9 +41,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
@ -1825,12 +1823,7 @@ public final class Switchboard extends serverSwitch {
// authorization for localhost, only if flag is set to grant localhost access as admin
final String clientIP = requestHeader.get(HeaderFramework.CONNECTION_PROP_CLIENTIP, "");
final String refererHost = requestHeader.refererHost();
boolean accessFromLocalhost = serverCore.isLocalhost(clientIP) && (refererHost.length() == 0 || serverCore.isLocalhost(refererHost));
if (!accessFromLocalhost) try {
// the access may also be from a different IP than localhost if it is the same as the YaCy instance is running on
InetAddress myaddress = InetAddress.getLocalHost();
accessFromLocalhost = myaddress.equals(InetAddress.getByName(clientIP)) && (refererHost.length() == 0 || myaddress.equals(InetAddress.getByName(refererHost)));
} catch (UnknownHostException e) {}
boolean accessFromLocalhost = Domains.isLocal(clientIP) && (refererHost.length() == 0 || Domains.isLocal(refererHost));
if (getConfigBool("adminAccountForLocalhost", false) && accessFromLocalhost) return 3; // soft-authenticated for localhost
// get the authorization string from the header

@ -169,13 +169,9 @@ public final class serverCore extends AbstractBusyThread implements BusyThread {
final InetAddress uAddr = s.getInetAddress();
if (uAddr.isAnyLocalAddress()) return "localhost";
String cIP = uAddr.getHostAddress();
if (isLocalhost(cIP)) cIP = "localhost";
if (Domains.isLocal(cIP)) cIP = "localhost";
return cIP;
}
public static final boolean isLocalhost(final String hostname) {
return hostname.equals("localhost") || hostname.startsWith("127.") || hostname.startsWith("0:0:0:0:0:0:0:1");
}
// class initializer
public serverCore(

@ -518,32 +518,27 @@ public class Domains {
if (nameCacheMiss.size() > maxNameCacheMissSize) nameCacheMiss.clear();
}
public static InetAddress localHostAddress;
public static String localHostName;
public static InetAddress[] localHostAddresses;
private static InetAddress localHostAddress;
private static final String localHostName = "127.0.0.1";
public static InetAddress[] localHostAddresses = new InetAddress[0];
static {
localHostName = "127.0.0.1";
try {
localHostAddress = InetAddress.getByName(localHostName);
} catch (UnknownHostException e1) {}
localHostAddress = InetAddress.getLocalHost();
} catch (UnknownHostException e) {}
try {
localHostAddresses = InetAddress.getAllByName(localHostName);
} catch (UnknownHostException e) {
localHostAddresses = new InetAddress[0];
}
} catch (UnknownHostException e) {}
new localHostAddressLookup().start();
}
public static class localHostAddressLookup extends Thread {
public void run() {
String lhn = localHostName;
try {
localHostAddress = InetAddress.getLocalHost();
localHostName = localHostAddress.getHostName();
} catch (UnknownHostException e) {
localHostName = "127.0.0.1";
}
lhn = InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {}
try {
localHostAddresses = InetAddress.getAllByName(localHostName);
localHostAddresses = InetAddress.getAllByName(lhn);
} catch (UnknownHostException e) {
localHostAddresses = new InetAddress[0];
}
@ -552,38 +547,37 @@ public class Domains {
public static InetAddress myPublicLocalIP() {
// list all addresses
final InetAddress[] ia = Domains.localHostAddresses;
// for (int i = 0; i < ia.length; i++) System.out.println("IP: " +
// ia[i].getHostAddress()); // DEBUG
if (ia.length == 0) {
return Domains.localHostAddress;
if (localHostAddresses.length == 0) {
return localHostAddress;
}
if (ia.length == 1) {
if (localHostAddresses.length == 1) {
// only one network connection available
return ia[0];
return localHostAddresses[0];
}
// we have more addresses, find an address that is not local
int b0, b1;
for (int i = 0; i < ia.length; i++) {
b0 = 0Xff & ia[i].getAddress()[0];
b1 = 0Xff & ia[i].getAddress()[1];
if ((b0 != 10) && // class A reserved
(b0 != 127) && // loopback
((b0 != 172) || (b1 < 16) || (b1 > 31)) && // class B reserved
((b0 != 192) || (b1 != 168)) && // class C reserved
(ia[i].getHostAddress().indexOf(":") < 0))
return ia[i];
for (int i = 0; i < localHostAddresses.length; i++) {
b0 = 0Xff & localHostAddresses[i].getAddress()[0];
b1 = 0Xff & localHostAddresses[i].getAddress()[1];
if (b0 != 10 && // class A reserved
b0 != 127 && // loopback
(b0 != 172 || b1 < 16 || b1 > 31) && // class B reserved
(b0 != 192 || b1 != 168) && // class C reserved
(localHostAddresses[i].getHostAddress().indexOf(":") < 0))
return localHostAddresses[i];
}
// there is only a local address, we filter out the possibly
// returned loopback address 127.0.0.1
for (int i = 0; i < ia.length; i++) {
if (((0Xff & ia[i].getAddress()[0]) != 127) && (ia[i].getHostAddress().indexOf(":") < 0)) return ia[i];
for (int i = 0; i < localHostAddresses.length; i++) {
if (((0Xff & localHostAddresses[i].getAddress()[0]) != 127) && (localHostAddresses[i].getHostAddress().indexOf(":") < 0)) return localHostAddresses[i];
}
// if all fails, give back whatever we have
for (int i = 0; i < ia.length; i++) {
if (ia[i].getHostAddress().indexOf(":") < 0) return ia[i];
for (int i = 0; i < localHostAddresses.length; i++) {
if (localHostAddresses[i].getHostAddress().indexOf(":") < 0) return localHostAddresses[i];
}
return ia[0];
return localHostAddresses[0];
}
public static int getDomainID(final String host) {
@ -601,35 +595,18 @@ public class Domains {
}
public static boolean isLocal(final String host) {
// attention! because this method does a dns resolve to look up an IP address,
// the result may be very slow. Consider 100 milliseconds per access
assert (host != null);
// FIXME IPv4 only
// check local ip addresses
if (matchesList(host, localhostPatterns)) return true;
if (host.startsWith("0:0:0:0:0:0:0:1")) return true;
// check the tld list
final int p = host.lastIndexOf('.');
String tld = "";
if (p > 0) {
tld = host.substring(p + 1);
}
if (TLDID.get(tld) == null) return true;
// make a dns resolve if a hostname is given and check again
final InetAddress clientAddress = dnsResolve(host);
if (clientAddress != null) {
if ((clientAddress.isAnyLocalAddress()) || (clientAddress.isLoopbackAddress())) return true;
// FIXME !!host is not read after this!!: if (host.charAt(0) > '9') host = clientAddress.getHostAddress();
}
// finally check if there are other local IP adresses that are not in
// the standard IP range
for (int i = 0; i < localHostAddresses.length; i++) {
if (localHostAddresses[i].equals(clientAddress)) return true;
if (localHostAddresses[i].getHostName().equals(host)) return true;
if (localHostAddresses[i].getHostAddress().equals(host)) return true;
}
// the address must be a global address

@ -45,6 +45,7 @@ import net.yacy.document.parser.html.ContentScraper;
import net.yacy.document.parser.html.TransformerWriter;
import net.yacy.kelondro.data.meta.DigestURI;
import net.yacy.kelondro.logging.Log;
import net.yacy.kelondro.util.Domains;
import net.yacy.kelondro.util.FileUtils;
import de.anomic.crawler.CrawlProfile;
@ -60,7 +61,6 @@ import de.anomic.http.server.RequestHeader;
import de.anomic.http.server.ResponseHeader;
import de.anomic.search.Segments;
import de.anomic.search.Switchboard;
import de.anomic.server.serverCore;
public final class LoaderDispatcher {
@ -174,7 +174,7 @@ public final class LoaderDispatcher {
// check if this loads a page from localhost, which must be prevented to protect the server
// against attacks to the administration interface when localhost access is granted
if (serverCore.isLocalhost(host) && sb.getConfigBool("adminAccountForLocalhost", false)) throw new IOException("access to localhost not granted for url " + request.url());
if (Domains.isLocal(host) && sb.getConfigBool("adminAccountForLocalhost", false)) throw new IOException("access to localhost not granted for url " + request.url());
// check if we have the page in the cache

Loading…
Cancel
Save