org.hd.d.pg2k.svrCore
Class AddrTools

java.lang.Object
  extended by org.hd.d.pg2k.svrCore.AddrTools

public final class AddrTools
extends java.lang.Object

This class has tools for IP-address and DNS manipulation.

Author:
Damon Hart-Davis

Nested Class Summary
static class AddrTools.AddrPrefix
          Immutable store of a non-null, non-zero-length unsigned-byte IP(v4) address prefix.
 
Field Summary
private static java.lang.ref.SoftReference<org.xbill.DNS.Cache> _cacheIN_SR
          SoftReference to our shared DNS cache (for IN records); never null though referent may be.
private static java.lang.Object _cacheIN_SR_lock
          Lock for get/set access to _cacheIN_SR SoftReference value.
private static int DEFAULT_DNS_CACHE_S
          Default maximum time to positively cache a record for (seconds); strictly positive.
private static int DEFAULT_DNS_NCACHE_S
          Default maximum time to negatively cache a record for (seconds); strictly positive.
private static org.xbill.DNS.Name[] EMPTY_SEARCH_PATH
          Fixed empty search path for lookups.
private static boolean RANDOMISE_RBL_LOOKUP_ORDER
          If true then we randomise the order in which we do RBL lookups.
private static org.xbill.DNS.ExtendedResolver RESOLVER_QUICK
          Our ExtendedResolver with the normal servers but a short timeout.
private static int RESOLVER_QUICK_RETRIES
          Maximum retries of resolution against each DNS server/resolver; strictly positive.
private static int RESOLVER_QUICK_TIMEOUT_S
          Approximate total maximum timeout for DNS resolution in seconds; strictly positive.
static boolean USE_DNSJAVA
          If true, use DNSJava to do DNS lookups where possible, else use Java's built-in DNS resolver.
 
Constructor Summary
private AddrTools()
          Prevent creation of instances of this class.
 
Method Summary
private static java.lang.String _checkOneAddrInDNSBL(java.lang.String prefix, java.lang.String server)
          Look up one address in DNSBL.
private static org.xbill.DNS.Cache _getDNSCache()
          Return access to the DNS cache, creating and initialising it if necessary; never null.
(package private) static org.xbill.DNS.Record[] doQuickLookupWithTunedCache(org.xbill.DNS.Lookup lookup)
          Do (quick) blocking lookup in our shared and tuned cache and resolver.
static java.lang.String doReverseLookup(java.net.InetAddress addr, boolean verify)
          Do reverse lookup on IP address to get the name, returns null if lookup fails.
static java.lang.String doReverseLookup(java.lang.String addr, boolean verify)
          Do reverse lookup on IP address to get the name, returns null if lookup fails.
static boolean hasARecordQuick(java.lang.String name)
          Return true if we can find an A record for the given name quickly.
static java.lang.String isAddrBlackholed(java.util.Collection<java.lang.String> extantRBLServers, java.net.InetAddress addr, boolean quick)
          Check an (IPv4) IP address with the RBL servers for being "blackholed".
static java.lang.String toStringDottedQuad(java.net.InetAddress addr)
          Convert an (IPv4) InetAddress to dotted-quad form.
static java.lang.String toStringReverseDottedQuad(java.net.InetAddress addr)
          Convert an (IPv4) InetAddress to reverse dotted-quad form with a trailing dot.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

USE_DNSJAVA

public static final boolean USE_DNSJAVA
If true, use DNSJava to do DNS lookups where possible, else use Java's built-in DNS resolver. DNSJava does not retain all results indefinitely unlike Java's DNS resolver, and allows us to use separate caches with different characteristics for different query types which can make it much more robust for our purposes.

See Also:
Constant Field Values

EMPTY_SEARCH_PATH

private static final org.xbill.DNS.Name[] EMPTY_SEARCH_PATH
Fixed empty search path for lookups.


RESOLVER_QUICK_TIMEOUT_S

private static final int RESOLVER_QUICK_TIMEOUT_S
Approximate total maximum timeout for DNS resolution in seconds; strictly positive. Quite short for the the geo-lookup (etc) as we usually only get limited value from a small number of lookups, and we do not want to block interactive activity for an extended period.

A value of a few seconds to a few tens of seconds should normally suffice, and puts a reasonable cap on the cost of a "full" lookup.


RESOLVER_QUICK_RETRIES

private static final int RESOLVER_QUICK_RETRIES
Maximum retries of resolution against each DNS server/resolver; strictly positive. A value greater than 1 is more robust, ie allows for the odd lost packet, and may get good results because the retry may gain the benefit of async cacheing upstream between calls on one particular resolver.

A value of 1 or 2 is typical.

See Also:
Constant Field Values

_cacheIN_SR

private static java.lang.ref.SoftReference<org.xbill.DNS.Cache> _cacheIN_SR
SoftReference to our shared DNS cache (for IN records); never null though referent may be. This may be created and set up on first use, and is tuned for our purposes (for example shorter timeouts and longer negative cacheing than default). It may be discarded and recreated if we are short of memory; hopefully caching by boundary DNS resolvers should minimise the impact if we do this.

We don't hand this out to other users, but they can give us a Lookup object and we will set the cache and other relevant parameters, and return the result to them.

This is intended to be highly threadable for many concurrent lookups.

Get/set access to this value is synchronised on the _cacheIN_SR_lock.


_cacheIN_SR_lock

private static final java.lang.Object _cacheIN_SR_lock
Lock for get/set access to _cacheIN_SR SoftReference value.


DEFAULT_DNS_CACHE_S

private static final int DEFAULT_DNS_CACHE_S
Default maximum time to positively cache a record for (seconds); strictly positive. Limiting this to a few hours at most can limit memory load when there are many users.


DEFAULT_DNS_NCACHE_S

private static final int DEFAULT_DNS_NCACHE_S
Default maximum time to negatively cache a record for (seconds); strictly positive. Setting this to a few tens of seconds (plus a few interleaved "failed lookup" intervals) can improve performance.


RESOLVER_QUICK

private static final org.xbill.DNS.ExtendedResolver RESOLVER_QUICK
Our ExtendedResolver with the normal servers but a short timeout. The DNS servers will be deduced once at initialisation.


RANDOMISE_RBL_LOOKUP_ORDER

private static final boolean RANDOMISE_RBL_LOOKUP_ORDER
If true then we randomise the order in which we do RBL lookups. We do this to better spread the load if several of them could answer the question.

This does not have to be "very" random, indeed, round-robin would probably do just as well.

See Also:
Constant Field Values
Constructor Detail

AddrTools

private AddrTools()
Prevent creation of instances of this class.

Method Detail

_getDNSCache

private static org.xbill.DNS.Cache _getDNSCache()
Return access to the DNS cache, creating and initialising it if necessary; never null. If we are short of memory we may automatically discard this entire cache.

This cache may have several parameters tuned for geo-lookup purposes, such as negative/positive cache time-limits.


doQuickLookupWithTunedCache

static org.xbill.DNS.Record[] doQuickLookupWithTunedCache(org.xbill.DNS.Lookup lookup)
Do (quick) blocking lookup in our shared and tuned cache and resolver. This should work better for us than the built-in Java implementation and we should build a useful but size-bounded cache unless the JVM gets very low on memory, in which case we may discard it and start again.

The caller should not extract/sequester/inspect the cache/resolver/etc properties that we set in the Lookup parameter, so this routine is only package-visible.

FIXME: As of 20060703: most expensive consumer of time for doHTML.jsp.


hasARecordQuick

public static boolean hasARecordQuick(java.lang.String name)
Return true if we can find an A record for the given name quickly. Uses our shared/tuned cache and does a quick lookup (ie times out quickly).

Throws:
java.lang.IllegalArgumentException - if argument is null or unparsable.

toStringDottedQuad

public static java.lang.String toStringDottedQuad(java.net.InetAddress addr)
                                           throws java.lang.IllegalArgumentException
Convert an (IPv4) InetAddress to dotted-quad form. Avoid doing any DNS lookup if at all possible.

Parameters:
addr - parameter to convert to dotted-quad; must be non-null IPv4 address
Throws:
java.lang.IllegalArgumentException - if addr is null or not an IPv4 address

toStringReverseDottedQuad

public static java.lang.String toStringReverseDottedQuad(java.net.InetAddress addr)
                                                  throws java.lang.IllegalArgumentException
Convert an (IPv4) InetAddress to reverse dotted-quad form with a trailing dot. This can be useful for RBL and reverse lookups.

Avoid doing any DNS lookup if at all possible.

Parameters:
addr - parameter to convert to reverse dotted-quad; must be non-null IPv4 address
Throws:
java.lang.IllegalArgumentException - if addr is null or not an IPv4 address

doReverseLookup

public static java.lang.String doReverseLookup(java.lang.String addr,
                                               boolean verify)
Do reverse lookup on IP address to get the name, returns null if lookup fails. This can optionally verify the name by trying to look up the name it found and making sure that at least one of the IPs returned matches.

This avoids the built-in JVM lookup routines to avoid the default infinite cacheing that it does for class-loading safety.

Blocks until it has an answer or times out.

Parameters:
addr - IP address to look up as numeric address; never null
verify - if true, attempt to verify with forward lookup of the putative result, returning null if no suitable match is found

doReverseLookup

public static java.lang.String doReverseLookup(java.net.InetAddress addr,
                                               boolean verify)
Do reverse lookup on IP address to get the name, returns null if lookup fails. This can optionally verify the name by trying to look up the name it found and making sure that at least one of the IPs returned matches.

This avoids the built-in JVM lookup routines to avoid the default infinite cacheing that it does for class-loading safety.

Blocks until it has an answer or times out.

Parameters:
addr - IP address to look up; never null
verify - if true, attempt to verify with forward lookup of the putative result, returning null if no suitable match is found

isAddrBlackholed

public static final java.lang.String isAddrBlackholed(java.util.Collection<java.lang.String> extantRBLServers,
                                                      java.net.InetAddress addr,
                                                      boolean quick)
                                               throws java.lang.IllegalArgumentException
Check an (IPv4) IP address with the RBL servers for being "blackholed". For an IPv4 address of the numerical form a.b.c.d, list does a lookup for an A record for d.c.b.a.RBL.domain, and if it finds one, the client address is "bad".

We may do these checks serially, or in parallel for speed. We may pick one RBL server at random each time for speed. The first suitable A record returned stops the search.

We may randomise the order in which we do lookup to spread the load amongst the RBL servers more fairly.

TODO: For now, always returns null for non-IPv4 addresses.

Parameters:
quick - if true, check just one of the BLs at random
Returns:
name of one BL server that blackholed address if so, null if address is OK
Throws:
java.lang.IllegalArgumentException - if given a null address

_checkOneAddrInDNSBL

private static java.lang.String _checkOneAddrInDNSBL(java.lang.String prefix,
                                                     java.lang.String server)
Look up one address in DNSBL.


DHD Multimedia Gallery V1.50.55

Copyright (c) 1996-2008, Damon Hart-Davis. All rights reserved.