001/*
002 * Copyright 2015-2024 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;
017import org.minidns.dnsqueryresult.DnsQueryResult;
018
019import java.io.IOException;
020import java.net.InetAddress;
021
022public abstract class AbstractDnsDataSource implements DnsDataSource {
023
024    @Override
025    public abstract DnsQueryResult query(DnsMessage message, InetAddress address, int port) throws IOException;
026
027    @Override
028    public MiniDnsFuture<DnsQueryResult, IOException> queryAsync(DnsMessage message, InetAddress address, int port, OnResponseCallback onResponseCallback) {
029        InternalMiniDnsFuture<DnsQueryResult, IOException> future = new InternalMiniDnsFuture<>();
030        DnsQueryResult result;
031        try {
032            result = query(message, address, port);
033        } catch (IOException e) {
034            future.setException(e);
035            return future;
036        }
037        future.setResult(result);
038        return future;
039    }
040
041    protected int udpPayloadSize = 1232;
042
043    /**
044     * DNS timeout.
045     */
046    protected int timeout = 5000;
047
048    @Override
049    public int getTimeout() {
050        return timeout;
051    }
052
053    @Override
054    public void setTimeout(int timeout) {
055        if (timeout <= 0) {
056            throw new IllegalArgumentException("Timeout must be greater than zero");
057        }
058        this.timeout = timeout;
059    }
060
061    @Override
062    public int getUdpPayloadSize() {
063        return udpPayloadSize;
064    }
065
066    public void setUdpPayloadSize(int udpPayloadSize) {
067        if (udpPayloadSize <= 0) {
068            throw new IllegalArgumentException("UDP payload size must be greater than zero");
069        }
070        this.udpPayloadSize = udpPayloadSize;
071    }
072
073    private DnsCache cache;
074
075    protected final void cacheResult(DnsMessage request, DnsQueryResult response) {
076        final DnsCache activeCache = cache;
077        if (activeCache == null) {
078            return;
079        }
080        activeCache.put(request, response);
081    }
082
083    public enum QueryMode {
084        /**
085         * Perform the query mode that is assumed "best" for that particular case.
086         */
087        dontCare,
088
089        /**
090         * Try UDP first, and if the result is bigger than the maximum UDP payload size, or if something else goes wrong, fallback to TCP.
091         */
092        udpTcp,
093
094        /**
095         * Always use only TCP when querying DNS servers.
096         */
097        tcp,
098    }
099
100    private QueryMode queryMode = QueryMode.dontCare;
101
102    public void setQueryMode(QueryMode queryMode) {
103        if (queryMode == null) {
104            throw new IllegalArgumentException();
105        }
106        this.queryMode = queryMode;
107    }
108
109    public QueryMode getQueryMode() {
110        return queryMode;
111    }
112
113}