java.lang.Object
net.i2p.util.DNSOverHTTPS
- All Implemented Interfaces:
EepGet.StatusListener
Simple implementation of DNS over HTTPS. Also sets the local clock from the received date header.
Warning - not thread-safe. Create new instances as necessary.
As of 0.9.49, this supports the RFC 8484 (DNS) format only. Does NOT support the JSON format (used prior to 0.9.49) or RFC 7858 (DNS over TLS).
https://developers.google.com/speed/public-dns/docs/dns-over-https https://developers.cloudflare.com/1.1.1.1/dns-over-https/json-format/ https://github.com/curl/curl/wiki/DNS-over-HTTPS
Nested Class Summary
Modifier and TypeClassDescriptionprivate static classOne resolved IP with its expiry time.static enumDNS query type for IPv4/IPv6 preference.Field Summary
Modifier and TypeFieldDescriptionprivate final LogLogger for the DoH lookups.private final ByteArrayOutputStreamBuffer accumulating the DNS response.private final I2PAppContextThe app context, for the clock and stats.private static final booleanDeveloper switch for extra logging.private static final intDefault clock stratum when no date source answered.private static final ObjectCounter<String> Consecutive failures counted per URL.private longWhen the current fetch started.private intNonzero once a date source was seen.The local domains and top level domains never looked up.private static final intDate sources consulted per lookup.private static final intConsecutive failures after which a URL is skipped.private static final intDoH requests attempted per family.private static final intLargest DNS response accepted, in bytes.private static final intLongest TTL accepted for a result, in seconds.private static final longTotal timeout for the v4 and v6 fetches, in ms.private SSLEepGet.SSLStateSSL result of the last fetch.private static final longTimeout for one DoH fetch, in ms.static final StringESR version of Firefox, same as Tor Browser.private static final Map<String, DNSOverHTTPS.Result> Cached IPv4 lookup results, by host.DoH URLs to query for IPv4 results.private static final Map<String, DNSOverHTTPS.Result> Cached IPv6 lookup results, by host.DoH URLs to query for IPv6 results.Constructor Summary
ConstructorsConstructorDescriptionDNSOverHTTPS(I2PAppContext context) Create a DNSOverHTTPS instance.DNSOverHTTPS(I2PAppContext context, SSLEepGet.SSLState sslState) Create a DNSOverHTTPS instance.Method Summary
Modifier and TypeMethodDescriptionvoidattemptFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt, int numRetries, Exception cause) Attempt failed notification.voidattempting(String url) Called when a new attempt to fetch the URL is starting.voidbytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) Total length should be == alreadyTransferred + currentWrite + bytesRemaining for all calls.static voidClear DNS caches and fail counts.private static StringdecodeStamp(String sdns, boolean log) Decode sdns:// stamps e.g.private static voiddecodeStamps(String file) Decode sdns:// stamps found in file.private StringFetch one DNS answer over HTTPS.voidheaderReceived(String url, int attemptNum, String key, String val) Use the Date header as a backup time source.private static voidloadURLs()Load the DoH server URLs.private voidLogs a message when debug logging is on.private voidLogs a message with an exception when debug logging is on.V4_ONLY unless we have only IPv6 address, then V6_ONLY.private static Stringlookup(String host, Map<String, DNSOverHTTPS.Result> cache) Lookup in cache.lookup(String host, DNSOverHTTPS.Type type) Lookup in cache, then query servers.private Stringlookup(String host, DNSOverHTTPS.Type type, String url) Lookup in cache, then query servers.static voidMain entry point for command line usage.private StringQuery one host over DNS-over-HTTPS.private Stringquery(String host, DNSOverHTTPS.Type type, String url) Query servers.voidtransferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) Transfer complete notification.voidtransferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) Transfer failed notification.private static voidusage()Prints the command line usage text.
Field Details
ctx
The app context, for the clock and stats._log
Logger for the DoH lookups.baos
Buffer accumulating the DNS response.state
SSL result of the last fetch.fetchStart
private long fetchStartWhen the current fetch started.gotDate
private int gotDateNonzero once a date source was seen.v4Cache
Cached IPv4 lookup results, by host.v6Cache
Cached IPv6 lookup results, by host.v4urls
v6urls
fails
Consecutive failures counted per URL.UA_CLEARNET
ESR version of Firefox, same as Tor Browser.- See Also:
MAX_RESPONSE_SIZE
private static final int MAX_RESPONSE_SIZELargest DNS response accepted, in bytes.- See Also:
DEBUG
locals
The local domains and top level domains never looked up. See also: RFC 2606 (reserved top level domains) See also: RFC 3166 (reverse DNS labels) See also: RFC 6303 (domain namespace reservations) See also: RFC 7393 (dotless IPv4 hostnames) See also: IANA locally served zones See also: ICANN M332 study See also: private use TLD draftTIMEOUT
OVERALL_TIMEOUT
private static final long OVERALL_TIMEOUTTotal timeout for the v4 and v6 fetches, in ms.- See Also:
MAX_TTL
private static final int MAX_TTLLongest TTL accepted for a result, in seconds.- See Also:
MAX_FAILS
private static final int MAX_FAILSConsecutive failures after which a URL is skipped.- See Also:
MAX_REQUESTS
private static final int MAX_REQUESTSDoH requests attempted per family.- See Also:
MAX_DATE_SETS
private static final int MAX_DATE_SETSDate sources consulted per lookup.- See Also:
DEFAULT_STRATUM
private static final int DEFAULT_STRATUMDefault clock stratum when no date source answered.- See Also:
Constructor Details
DNSOverHTTPS
Create a DNSOverHTTPS instance.- Parameters:
context- the I2P app context
DNSOverHTTPS
Create a DNSOverHTTPS instance.- Parameters:
context- the I2P app contextsslState- the SSL state, or null
Method Details
lookup
lookup
Lookup in cache, then query servers.- Parameters:
host- the hostname to resolvetype- the query type- Returns:
- null if not found
lookup
Lookup in cache, then query servers.- Parameters:
host- the host name to resolvetype- the record type to return, A or AAAAurl- null to query several default servers, or specify single server- Returns:
- null if not found
clearCaches
public static void clearCaches()Clear DNS caches and fail counts.lookup
Lookup in cache.- Parameters:
host- the host name to look upcache- the cache to search, keyed by host name- Returns:
- null if not found or expired
query
Query servers.- Parameters:
host- the host name to resolvetype- the record type to return, A or AAAAurl- null to query several default servers, or specify single server- Returns:
- null if not found
query
Query one host over DNS-over-HTTPS.- Parameters:
host- the host name to resolveisv6- true to query AAAA for an IPv6 answer, false for AtoQuery- the DoH server URLs to trytimeout- the absolute deadline in ms, servers are tried until it passes- Returns:
- null if not found
fetch
Fetch one DNS answer over HTTPS.- Parameters:
eepget- the fetcher, already set up for the DoH server URLhost- the host name being resolved, used for the CNAME fallback questionisv6- true if the original question was AAAA, used to re-query after a CNAMEq- the DNS question whose answers are wanted- Returns:
- null if not found
attemptFailed
public void attemptFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt, int numRetries, Exception cause) Description copied from interface:EepGet.StatusListenerAttempt failed notification.- Specified by:
attemptFailedin interfaceEepGet.StatusListener- Parameters:
url- the address whose fetch attempt failedbytesTransferred- bytes received so far, counted across every attempt and including response headersbytesRemaining- bytes still owed, or -1 if unknowncurrentAttempt- zero-based index of the attempt that failednumRetries- total attempts this fetch is allowedcause- the exception that ended the attempt- See Also:
bytesTransferred
public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) Description copied from interface:EepGet.StatusListenerTotal length should be == alreadyTransferred + currentWrite + bytesRemaining for all calls.- Specified by:
bytesTransferredin interfaceEepGet.StatusListener- Parameters:
alreadyTransferred- total of all attempts, not including currentWrite If nonzero on the first call, a partial file of that length was found, _and_ the server supports resume. If zero on a subsequent call after some bytes are transferred (and presumably after an attemptFailed), the server does _not_ support resume and we had to start over. To track _actual_ transfer if the output file could already exist, the listener should keep its own counter, or subtract the initial alreadyTransferred value. And watch out for alreadyTransferred resetting if a resume failed...currentWrite- since last call to the listenerbytesTransferred- includes headers, retries, redirects, discarded partial downloads, ...bytesRemaining- on this attempt only, currentWrite already subtracted - or -1 if chunked encoding or server does not return a lengthurl- the URL being fetched
transferComplete
public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) Description copied from interface:EepGet.StatusListenerTransfer complete notification.- Specified by:
transferCompletein interfaceEepGet.StatusListener- Parameters:
alreadyTransferred- total bytes transferredbytesTransferred- total incl headersbytesRemaining- bytes still owed by the server, or -1 if chunked encoding or no Content-Length was returnedurl- the address the transfer was readingoutputFile- null if unknown (output stream constructor)notModified- whether 304- See Also:
transferFailed
public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) Description copied from interface:EepGet.StatusListenerTransfer failed notification.- Specified by:
transferFailedin interfaceEepGet.StatusListener- Parameters:
url- the address whose transfer failedbytesTransferred- bytes received so far, counted across every attempt and including response headersbytesRemaining- bytes still owed, or -1 if unknowncurrentAttempt- zero-based index of the attempt that failed- See Also:
attempting
Description copied from interface:EepGet.StatusListenerCalled when a new attempt to fetch the URL is starting.- Specified by:
attemptingin interfaceEepGet.StatusListener- Parameters:
url- the URL being attempted
headerReceived
Use the Date header as a backup time source. Code from Reseeder. We set the stratum to a lower (better) value than in Reseeder, as Cloudflare and Google probably have a better idea than our reseeds.- Specified by:
headerReceivedin interfaceEepGet.StatusListener- Parameters:
url- the address the header arrived onattemptNum- zero-based index of the attempt the header arrived onkey- header keyval- header value
log
Logs a message when debug logging is on.- Parameters:
msg- the message to log
log
loadURLs
private static void loadURLs()Load the DoH server URLs.main
Main entry point for command line usage.- Parameters:
args- command line arguments
usage
private static void usage()Prints the command line usage text.decodeStamp
Decode sdns:// stamps e.g. sdns://AgMAAAAAAAAADjE2My40Ny4xMTcuMTc2oMwQYNOcgym2K2-8fQ1t-TCYabmB5-Y5LVzY-kCPTYDmIEROvWe7g_iAezkh6TiskXi4gr1QqtsRIx8ETPXwjffOEGFkbC5hZGZpbHRlci5uZXQKL2Rucy1xdWVyeQ Ref: https://dnscrypt.info/stamps-specifications/- Parameters:
sdns- the sdns:// stamp to decodelog- true to print decode errors to standard output- Returns:
- the URL, or null on error or if not a DoH (type 2) stamp
decodeStamps
Decode sdns:// stamps found in file. Stamps that are not DoH (type 2), or fail to decode, are skipped.- Parameters:
file- the file to scan line by line for sdns:// stamps- Throws:
IOException- if the file cannot be read