]> git.ipfire.org Git - thirdparty/dnspython.git/commitdiff
Add support for DoH
authorFilip Š <filip.stamcar@hotmail.com>
Sat, 28 Sep 2019 15:43:48 +0000 (17:43 +0200)
committerFilip Š <filip.stamcar@hotmail.com>
Sat, 28 Sep 2019 15:43:48 +0000 (17:43 +0200)
dns/query.py
dns/query.pyi
dns/resolver.py

index 20c953cb328c78db3764539cee83c39807e84567..62b5014388fb3d2fe9fe2ad6f6274ca71426df60 100644 (file)
@@ -19,6 +19,7 @@
 
 from __future__ import generators
 
+import urllib.request
 import errno
 import select
 import socket
@@ -189,6 +190,27 @@ def _destination_and_source(af, where, port, source, source_port):
     return (af, destination, source)
 
 
+def doh(query, nameserver):
+    """Return the response obtained after sending a query via DoH.
+
+    *query*, a ``dns.message.Message`` containing the query to send
+
+    *nameserver*, a ``str`` containing the nameserver URL.
+
+    Returns a ``dns.message.Message``.
+    """
+
+    wirequery = query.to_wire()
+    headers = {
+        'Accept': 'application/dns-message',
+        'Content-Type': 'application/dns-message',
+    }
+
+    request = urllib.request.Request(nameserver, data=wirequery, headers=headers)
+    response = urllib.request.urlopen(request).read()
+
+    return dns.message.from_wire(response)
+
 def send_udp(sock, what, destination, expiration=None):
     """Send a DNS message to the specified UDP socket.
 
index fe5ef826a0a7c6be0637e9c9f3a1cb8549ef6130..ccd4b3fe6b485535efd0b4662770cf4543502989 100644 (file)
@@ -1,5 +1,8 @@
 from typing import Optional, Union, Dict, Generator, Any
 from . import message, tsig, rdatatype, rdataclass, name, message
+def doh(query : message.Message, nameserver : str) -> message.Message:
+    pass
+
 def tcp(q : message.Message, where : str, timeout : float = None, port=53, af : Optional[int] = None, source : Optional[str] = None, source_port : int = 0,
         one_rr_per_rrset=False) -> message.Message:
     pass
index cecc3749f0844975668575ca00e008f73f8fe754..04c6f6f10c92ea3168cd4b3c96ec341f64c09ec8 100644 (file)
@@ -17,6 +17,7 @@
 
 """DNS stub resolver."""
 
+from urllib.parse import urlparse
 import socket
 import sys
 import time
@@ -897,29 +898,34 @@ class Resolver(object):
                 for nameserver in nameservers[:]:
                     timeout = self._compute_timeout(start, lifetime)
                     port = self.nameserver_ports.get(nameserver, self.port)
+                    protocol = urlparse(nameserver).scheme
                     try:
-                        tcp_attempt = tcp
-                        if tcp:
-                            response = dns.query.tcp(request, nameserver,
-                                                     timeout, port,
-                                                     source=source,
-                                                     source_port=source_port)
+                        if protocol == 'https':
+                            tcp_attempt = True
+                            response = dns.query.doh(request, nameserver)
                         else:
-                            try:
-                                response = dns.query.udp(request, nameserver,
+                            tcp_attempt = tcp
+                            if tcp:
+                                response = dns.query.tcp(request, nameserver,
                                                          timeout, port,
                                                          source=source,
-                                                         source_port=\
-                                                         source_port)
-                            except dns.message.Truncated:
-                                # Response truncated; retry with TCP.
-                                tcp_attempt = True
-                                timeout = self._compute_timeout(start, lifetime)
-                                response = \
-                                    dns.query.tcp(request, nameserver,
-                                                  timeout, port,
-                                                  source=source,
-                                                  source_port=source_port)
+                                                         source_port=source_port)
+                            else:
+                                try:
+                                    response = dns.query.udp(request, nameserver,
+                                                             timeout, port,
+                                                             source=source,
+                                                             source_port=\
+                                                             source_port)
+                                except dns.message.Truncated:
+                                    # Response truncated; retry with TCP.
+                                    tcp_attempt = True
+                                    timeout = self._compute_timeout(start, lifetime)
+                                    response = \
+                                        dns.query.tcp(request, nameserver,
+                                                      timeout, port,
+                                                      source=source,
+                                                      source_port=source_port)
                     except (socket.error, dns.exception.Timeout) as ex:
                         #
                         # Communication failure or timeout.  Go to the