001/* 002 * Copyright 2015-2018 the original author or authors 003 * 004 * This software is licensed under the Apache License, Version 2.0, 005 * the GNU Lesser General Public License version 2 or later ("LGPL") 006 * and the WTFPL. 007 * You may choose either license to govern your use of this software only 008 * upon the condition that you accept all of the terms of either 009 * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 010 */ 011package org.minidns.source; 012 013import org.minidns.DnsCache; 014import org.minidns.MiniDnsFuture; 015import org.minidns.MiniDnsFuture.InternalMiniDnsFuture; 016import org.minidns.dnsmessage.DnsMessage; 017 018import java.io.IOException; 019import java.net.InetAddress; 020 021public abstract class DnsDataSource { 022 023 public abstract DnsMessage query(DnsMessage message, InetAddress address, int port) throws IOException; 024 025 public MiniDnsFuture<DnsMessage, IOException> queryAsync(DnsMessage message, InetAddress address, int port, OnResponseCallback onResponseCallback) { 026 InternalMiniDnsFuture<DnsMessage, IOException> future = new InternalMiniDnsFuture<>(); 027 DnsMessage result; 028 try { 029 result = query(message, address, port); 030 } catch (IOException e) { 031 future.setException(e); 032 return future; 033 } 034 future.setResult(result); 035 return future; 036 } 037 038 protected int udpPayloadSize = 1024; 039 040 /** 041 * DNS timeout. 042 */ 043 protected int timeout = 5000; 044 045 /** 046 * Retrieve the current dns query timeout, in milliseconds. 047 * 048 * @return the current dns query timeout in milliseconds. 049 */ 050 public int getTimeout() { 051 return timeout; 052 } 053 054 /** 055 * Change the dns query timeout for all future queries. The timeout 056 * must be specified in milliseconds. 057 * 058 * @param timeout new dns query timeout in milliseconds. 059 */ 060 public void setTimeout(int timeout) { 061 if (timeout <= 0) { 062 throw new IllegalArgumentException("Timeout must be greater than zero"); 063 } 064 this.timeout = timeout; 065 } 066 067 public int getUdpPayloadSize() { 068 return udpPayloadSize; 069 } 070 071 public void setUdpPayloadSize(int udpPayloadSize) { 072 if (udpPayloadSize <= 0) { 073 throw new IllegalArgumentException("UDP payload size must be greater than zero"); 074 } 075 this.udpPayloadSize = udpPayloadSize; 076 } 077 078 private DnsCache cache; 079 080 protected final void cacheResult(DnsMessage request, DnsMessage response) { 081 final DnsCache activeCache = cache; 082 if (activeCache == null) { 083 return; 084 } 085 activeCache.put(request, response); 086 } 087 088 public enum QueryMode { 089 /** 090 * Perform the query mode that is assumed "best" for that particular case. 091 */ 092 dontCare, 093 094 /** 095 * Try UDP first, and if the result is bigger than the maximum UDP payload size, or if something else goes wrong, fallback to TCP. 096 */ 097 udpTcp, 098 099 /** 100 * Always use only TCP when querying DNS servers. 101 */ 102 tcp, 103 } 104 105 private QueryMode queryMode = QueryMode.dontCare; 106 107 public void setQueryMode(QueryMode queryMode) { 108 if (queryMode == null) { 109 throw new IllegalArgumentException(); 110 } 111 this.queryMode = queryMode; 112 } 113 114 public QueryMode getQueryMode() { 115 return queryMode; 116 } 117 118 public interface OnResponseCallback { 119 void onResponse(DnsMessage request, DnsMessage response); 120 } 121}