/** * Copyright 2008 - CommonCrawl Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * **/ package org.commoncrawl.io; import java.io.IOException; import java.net.UnknownHostException; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import org.commoncrawl.io.NIODNSCache.Node; import org.commoncrawl.io.NIODNSQueryClient.Status; import org.commoncrawl.util.IPAddressUtils; import org.commoncrawl.util.IntrusiveList.IntrusiveListElement; /** * * @author rana * */ public abstract class NIODNSResolver extends IntrusiveListElement<NIODNSResolver> implements Comparable<NIODNSResolver> { /** cache **/ public static NIODNSCache _dnsCache = new NIODNSCache(); /** inverse cache **/ public static NIODNSCache _badHostCache = new NIODNSCache(); /** ttl override **/ public static final int MIN_TTL_VALUE = 60 * 20 * 1000; private static long TTL_DELTA_MIN = 1000 * 60 * 10; // min ttl lifetime is 10 minutes for us public static final int SERVER_FAIL_BAD_HOST_LIFETIME = 3600 * 1000; // ONE HOUR BY DEFAULT public static final int NXDOMAIN_FAIL_BAD_HOST_LIFETIME = 5 * 60 * 1000; // 5 minutes private int _queuedCount; static NIODNSQueryLogger _logger = null; AtomicLong _cacheHits = new AtomicLong(); /** * queue a DNS resolution request * * @param client * - the callback interface * @param theHost * - the host name to query for * @return * @throws IOException */ public abstract Future<NIODNSQueryResult> resolve(NIODNSQueryClient client, String theHost, boolean noCache,boolean highPriorityRequest, int timeoutValue) throws IOException; /** * stats * @return queued item count - if this is a queueing resolver */ public int getQueuedItemCount() { return _queuedCount; } /** * increment queued count */ public void incQueuedCount() { _queuedCount++; } /** * stats * @return cache hits if this resolver makes use of caching ... */ public long getCacheHitCount() { return 0; } public static NIODNSQueryResult checkCache(NIODNSQueryClient client, String hostName) throws UnknownHostException { NIODNSCache.DNSResult result = _dnsCache.getIPAddressForHost(hostName); if (result != null) { // get delta between time to live and now ... long ttlDelta = result.getTTL() - System.currentTimeMillis(); // if theoretically this ip address has expired if (ttlDelta < 0) { if (Math.abs(ttlDelta) > TTL_DELTA_MIN) { return null; } } /* * if (Environment.detailLogEnabled()) { * LOG.info("Cache HIT for host:"+hostName * +" ip:"+IPAddressUtils.IntegerToIPAddressString * (result.getIPAddress())); } */ NIODNSQueryResult queryResult = new NIODNSQueryResult(null, client, hostName); queryResult.setAddress(IPAddressUtils.IntegerToInetAddress(result .getIPAddress())); queryResult.setCName(result.getCannonicalName()); queryResult.setTTL(result.getTTL()); queryResult.setStatus(Status.SUCCESS); return queryResult; } // check bad host cache ... Node resolvedNode = _badHostCache.findNode(hostName); if (resolvedNode != null) { // LOG.info("Found in Bad Host Cache:" + hostName + " ttl:" + new // Date(resolvedNode.getTimeToLive())); } // IFF found and the bad node has not expired ... if (resolvedNode != null && resolvedNode.getTimeToLive() >= System.currentTimeMillis()) { // LOG.info("Host:" + hostName + " Identified as Bad Host via Cache"); NIODNSQueryResult queryResult = new NIODNSQueryResult(null, client, hostName); queryResult.setStatus(Status.SERVER_FAILURE); queryResult.setErrorDesc("Failed via Bad Host Cache"); return queryResult; } return null; } public int compareTo(NIODNSResolver o) { return (_queuedCount < o._queuedCount) ? -1 : (_queuedCount > o._queuedCount) ? 1 : 0; } public static NIODNSCache getDNSCache() { return _dnsCache; } public static NIODNSCache getBadHostCache() { return _badHostCache; } public static void setLogger(NIODNSQueryLogger logger) { _logger = logger; } public static NIODNSQueryLogger getLogger() { return _logger; } }