Commit b0cec718 authored by Alexandre's avatar Alexandre
Browse files

Merge branch 'rename-to-remoh'

Rename to Remoh

Closes #32
parents 0fe78e14 3d36b50a
......@@ -290,7 +290,7 @@ to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Homer
Remoh
Copyright (C) 2019 Stéphane Bortzmeyer and Alexandre Pion (AFNIC)
This program is free software; you can redistribute it and/or modify
......
# Homer
# Remoh
Homer is a DoH (DNS-over-HTTPS) and DoT (DNS-over-TLS) client. Its
main purpose is to test DoH and DoT resolvers.
Remoh (formerly Homer) is a DoH (DNS-over-HTTPS) and DoT (DNS-over-TLS) client.
Its main purpose is to test DoH and DoT resolvers.
With the proliferation of public DoH and DoT resolvers, and the implementation
of clients inside OS or applications such as web browsers, we wanted to have an
easy to use command line client to make DoT and DoH queries. Homer also aims to
easy to use command line client to make DoT and DoH queries. Remoh also aims to
assess if a DoT or DoH resolver is compliant with the RFCs (
[RFC 7858](https://www.rfc-editor.org/rfc/rfc7858) for DoT and
[RFC 8484](https://www.rfc-editor.org/rfc/rfc8484) for DoH).
Homer is a Python3 script using the [dnspython](http://www.dnspython.org/)
Remoh is a Python3 script using the [dnspython](http://www.dnspython.org/)
library to generate and parse DNS messages, [netaddr](https://github.com/netaddr/netaddr)
to manipulate IP addresses, [PycURL](http://pycurl.io/) to perform the HTTPs
transfers in DoH and [pyOpenSSL](https://www.pyopenssl.org/en/stable/) to
......@@ -35,13 +35,13 @@ establish TLS session in DoT.
## Usage
Two mandatory arguments, the URL of the DoH server (or name/address of
the DoT resolver), and a domain name to query. By default, Homer uses
the DoT resolver), and a domain name to query. By default, Remoh uses
DoH. Also by defaut, the type of data is AAAA (IP address). You can
add a third argument to use another type, as in the second example
below.
```
% homer https://doh.powerdns.org/ framagit.org
% remoh https://doh.powerdns.org/ framagit.org
id 0
opcode QUERY
rcode NOERROR
......@@ -54,7 +54,7 @@ framagit.org. 10800 IN AAAA 2a01:4f8:200:1302::42
;ADDITIONAL
Total elapsed time: 0.40 seconds (402.28 ms/request)
% homer --dot 9.9.9.9 cocca.fr A
% remoh --dot 9.9.9.9 cocca.fr A
id 42545
opcode QUERY
rcode NOERROR
......@@ -69,9 +69,9 @@ cocca.fr. 43200 IN A 185.17.236.69
Total elapsed time: 0.07 seconds (66.72 ms/request )
```
When using DoT, Homer first resolves the domain name of the resolver into a
When using DoT, Remoh first resolves the domain name of the resolver into a
list of IPv4 and IPv6 addresses (or only one subset when using `-4` or `-6`)
and will loop on each of them until a response is received. Hence if Homer gets
and will loop on each of them until a response is received. Hence if Remoh gets
an answer, this mean that at least one DoT resolver is up and running. To check
all the IPs, use `--check`.
......@@ -128,7 +128,7 @@ measurements. This is done with option `--repeat N` where N is the
number of repetitions.
```
% homer --repeat 3 https://doh.bortzmeyer.fr ça.fr SOA
% remoh --repeat 3 https://doh.bortzmeyer.fr ça.fr SOA
Test 0
...
Test 1
......@@ -138,11 +138,11 @@ Test 2
Total elapsed time: 0.10 seconds (33.56 ms/request , 7.88 ms/request if we ignore the first one)
```
Homer reuses the same connection for all requests, both for DoH and
Remoh reuses the same connection for all requests, both for DoH and
DoT, which explains why the first request is often longer.
Repetition is often combined with the use of an external file `-f FILE`, where
Homer reads the domain names (and types) to query. Here is a sample
Remoh reads the domain names (and types) to query. Here is a sample
file:
```
......@@ -157,7 +157,7 @@ tests, with the above names (and the query type `NS` for the last
one):
```
% homer --repeat 4 --file list.txt https://doh.42l.fr/dns-query
% remoh --repeat 4 --file list.txt https://doh.42l.fr/dns-query
```
When repeating tests, you can add a delay between tests, with `--delay
......@@ -171,20 +171,20 @@ connection. This can be used to test the compliance of the servers with the
RFCs. DoT is standardized in [RFC 7858](https://www.rfc-editor.org/rfc/rfc7858)
and DoH in [RFC 8484](https://www.rfc-editor.org/rfc/rfc8484).
If all the tests passed, Homer displays `OK`. Otherwise if at least
on test failed, Homer outputs `KO`. When a test fails, an error message
If all the tests passed, Remoh displays `OK`. Otherwise if at least
on test failed, Remoh outputs `KO`. When a test fails, an error message
is displayed.
```
% homer --check https://doh.bortzmeyer.fr framagit.org
% remoh --check https://doh.bortzmeyer.fr framagit.org
OK
% homer --dot --check dnsotls.lab.nic.cl wikipedia.org
% remoh --dot --check dnsotls.lab.nic.cl wikipedia.org
Could not connect to "dnsotls.lab.nic.cl" on 200.1.123.46
KO
```
When used with an URL for DoH or a domain name for DoT, Homer loops
When used with an URL for DoH or a domain name for DoT, Remoh loops
on all the resolved IPs. All the tests are then run for each connection.
Each test is marked with a level of compliance. There are three
......@@ -216,7 +216,7 @@ the choosen level is lower than the level of the test.
### Multistreams
When using Homer with DoH, the option `--multistreams` can be used
When using Remoh with DoH, the option `--multistreams` can be used
to specify that you want to take advantage of the HTTP/2 streams
when sending several requests.
......@@ -227,12 +227,12 @@ the file.
For example :
```
% homer --multistreams --file input_file --repeat 5 https://doh.powerdns.org
% remoh --multistreams --file input_file --repeat 5 https://doh.powerdns.org
...
Total elapsed time: 0.11 seconds (22.60 ms/request)
```
When dealing with multistreams, Homer relies on the multi interface
When dealing with multistreams, Remoh relies on the multi interface
from PycURL (and libcurl). By default all the queries are attached to
the multi object before performing the transfers. For a better use of
the multi interface, see the branch [homer-perf](-/tree/homer-perf).
......@@ -263,27 +263,27 @@ the root NS.
It is possible to pipeline multiple DoT queries with the option `--pipelining`.
The queries are created based on the provided input file. Up to `N` lines are
read from the file, with `N` defined by the option `--repeat N`. By default
Homer sends up to 20 requests in parallel before listening for responses.
Remoh sends up to 20 requests in parallel before listening for responses.
This value can be changed with `--max-in-flight`.
After sending the first query, Homer is configured to stop after 10 seconds
After sending the first query, Remoh is configured to stop after 10 seconds
has elapsed. This mean that if more queries need to be sent or received 10
seconds after the beginning of the first transfer, they will all be dropped.
To increase this value, update the variable `MAX_DURATION`.
Homer will display all the DNS response as they arrive. To suppress
Remoh will display all the DNS response as they arrive. To suppress
this output, use `--no-display-results`.
If not all the queries got a response in `MAX_DURATION` seconds, Homer
If not all the queries got a response in `MAX_DURATION` seconds, Remoh
outputs `KO` instead of `OK`.
```
% homer --dot --pipelining -f input_file -r 5 dns.switch.ch
% remoh --dot --pipelining -f input_file -r 5 dns.switch.ch
...
Total elapsed time: 0.56 seconds (111.67 ms/request)
OK
% homer --dot --pipelining -f huge_file -r 1000 127.0.0.1
% remoh --dot --pipelining -f huge_file -r 1000 127.0.0.1
...
Elapsed time too long, 42 requests never got a reply
Total elapsed time: 10.29 seconds (10.29 ms/request)
......@@ -292,7 +292,7 @@ KO
### A note on the SNI
By default, Homer sends a SNI when establishing the TLS session with DoT. The
By default, Remoh sends a SNI when establishing the TLS session with DoT. The
SNI value is extracted from the name or address of the DoT resolver. If a
literal IP address is used, the SNI will then be set with the IP address.
......@@ -396,7 +396,7 @@ You need Python 3, [DNSpython](http://www.dnspython.org/),
[netaddr](https://github.com/drkjam/netaddr/) and
[PycURL](http://pycurl.io/docs/latest). You can install them with pip
`pip3 install dnspython pyOpenSSL netaddr pycurl`. Then, just run the
script `homer` (or `homer.py`).
script `remoh` (or `remoh.py`).
On Debian, if you prefer regular operating system packages to pip,
`apt install python3 python3-dnspython python3-openssl python3-netaddr
......
......@@ -12,13 +12,13 @@ echo "DoT"
for server in $(cat dot-servers.txt); do
echo ""
echo $server
./homer.py --check --dot $server $domain $type
./remoh.py --check --dot $server $domain $type
done
echo ""
echo "DoH"
for url in $(cat doh-servers.txt); do
echo ""
echo $url
./homer.py --check $url $domain $type
./remoh.py --check $url $domain $type
done
#!/usr/bin/env python3
# Homer is a DoH (DNS-over-HTTPS) and DoT (DNS-over-TLS) client. Its
# Remoh is a DoH (DNS-over-HTTPS) and DoT (DNS-over-TLS) client. Its
# main purpose is to test DoH and DoT resolvers. Reference site is
# <https://framagit.org/bortzmeyer/homer/> See author, documentation,
# etc, there, or in the README.md included with the distribution.
......@@ -22,7 +22,7 @@ except ImportError as e:
print(e)
sys.exit(1)
import homer
import remoh
# Values that can be changed from the command line
# "H:n:p:V:t:e:Pih46k:x"
......@@ -170,10 +170,10 @@ def parse_opts_monitoring(me, opts):
def run_default(name, connection, opts):
if connection.dot:
request = homer.RequestDOT(name, qtype=opts.rtype, use_edns=opts.edns,
request = remoh.RequestDOT(name, qtype=opts.rtype, use_edns=opts.edns,
want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
else:
request = homer.RequestDOH(name, qtype=opts.rtype, use_edns=opts.edns,
request = remoh.RequestDOH(name, qtype=opts.rtype, use_edns=opts.edns,
want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
request.to_wire()
......@@ -184,7 +184,7 @@ def run_default(name, connection, opts):
try:
connection.do_test(request)
except (OpenSSL.SSL.Error, homer.DOHException) as e:
except (OpenSSL.SSL.Error, remoh.DOHException) as e:
error(e)
return False
......@@ -202,7 +202,7 @@ if __name__ == '__main__':
# The provided host is indeed a valid IP
# TODO catch ValueError exception if the host is an url as in :
# ./check_doh -H https://doh.bortzmeyer.fr -n afnic.fr
if homer.is_valid_ip_address(opts.host)[0]:
if remoh.is_valid_ip_address(opts.host)[0]:
opts.connectTo = opts.host
ok = True
......@@ -212,12 +212,12 @@ if __name__ == '__main__':
extracheck = None
try:
if opts.dot:
conn = homer.ConnectionDOT(url, servername=extracheck, connect_to=opts.connectTo,
conn = remoh.ConnectionDOT(url, servername=extracheck, connect_to=opts.connectTo,
forceIPv4=opts.forceIPv4, forceIPv6=opts.forceIPv6,
insecure=opts.insecure,
sni=opts.sni, key=opts.key)
else:
conn = homer.ConnectionDOH(url, servername=extracheck, connect_to=opts.connectTo,
conn = remoh.ConnectionDOH(url, servername=extracheck, connect_to=opts.connectTo,
forceIPv4=opts.forceIPv4, forceIPv6=opts.forceIPv6,
insecure=opts.insecure)
except TimeoutError:
......@@ -228,7 +228,7 @@ if __name__ == '__main__':
error("\"%s\" not a name or an IP address" % url)
except socket.gaierror:
error("Could not resolve \"%s\"" % url)
except (homer.ConnectionException, homer.DOHException) as e:
except (remoh.ConnectionException, remoh.DOHException) as e:
error(e)
if conn.dot and not conn.success:
ok = False
......
#!/usr/bin/env python3
# Homer is a DoH (DNS-over-HTTPS) and DoT (DNS-over-TLS) client. Its
# Remoh is a DoH (DNS-over-HTTPS) and DoT (DNS-over-TLS) client. Its
# main purpose is to test DoH and DoT resolvers. Reference site is
# <https://framagit.org/bortzmeyer/homer/> See author, documentation,
# etc, there, or in the README.md included with the distribution.
......@@ -24,7 +24,7 @@ except ImportError as e:
print(e)
sys.exit(1)
import homer
import remoh
# Values that can be changed from the command line
class opts:
......@@ -171,13 +171,13 @@ def check_dot_two_requests(connection, opts):
if not connection.dot:
return True
r1 = homer.RequestDOT('framagit.org', qtype=opts.rtype, use_edns=opts.edns, want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
r2 = homer.RequestDOT('afnic.fr', qtype=opts.rtype, use_edns=opts.edns, want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
r1 = remoh.RequestDOT('framagit.org', qtype=opts.rtype, use_edns=opts.edns, want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
r2 = remoh.RequestDOT('afnic.fr', qtype=opts.rtype, use_edns=opts.edns, want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
requests = []
requests.append(('Test 1', r1, homer.mandatory_levels["legal"]))
requests.append(('Test 1', r1, remoh.mandatory_levels["legal"]))
# RFC 7858 section 3.3, SHOULD accept several requests on one connection.
requests.append(('Test 2', r2, homer.mandatory_levels["necessary"]))
requests.append(('Test 2', r2, remoh.mandatory_levels["necessary"]))
return do_check(connection, requests, opts)
......@@ -186,21 +186,21 @@ def check_doh_methods(connection, opts):
if connection.dot:
return True
r1 = homer.RequestDOH('framagit.org', qtype=opts.rtype, use_edns=opts.edns, want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
r2 = homer.RequestDOH('afnic.fr', qtype=opts.rtype, use_edns=opts.edns, want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
r1 = remoh.RequestDOH('framagit.org', qtype=opts.rtype, use_edns=opts.edns, want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
r2 = remoh.RequestDOH('afnic.fr', qtype=opts.rtype, use_edns=opts.edns, want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
r2.post = True
r3 = homer.RequestDOH('www.rfc-editor.org', qtype=opts.rtype, use_edns=opts.edns, want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
r3 = remoh.RequestDOH('www.rfc-editor.org', qtype=opts.rtype, use_edns=opts.edns, want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
r3.head = True
requests = []
requests.append(('Test GET', r1, homer.mandatory_levels["legal"])) # RFC 8484, section 4.1
requests.append(('Test POST', r2, homer.mandatory_levels["legal"])) # RFC 8484, section 4.1
requests.append(('Test GET', r1, remoh.mandatory_levels["legal"])) # RFC 8484, section 4.1
requests.append(('Test POST', r2, remoh.mandatory_levels["legal"])) # RFC 8484, section 4.1
# HEAD method is not mentioned in RFC 8484 (see section 4.1), so just "nice to have".
requests.append(('Test HEAD', r3, homer.mandatory_levels["nicetohave"]))
requests.append(('Test HEAD', r3, remoh.mandatory_levels["nicetohave"]))
return do_check(connection, requests, opts)
def check_doh_header(connection, opts, level=homer.mandatory_levels["nicetohave"],
def check_doh_header(connection, opts, level=remoh.mandatory_levels["nicetohave"],
accept="application/dns-message", content_type="application/dns-message"):
# change the MIME value and see what happens
# based on the RFC only application/dns-message must be supported, any
......@@ -212,7 +212,7 @@ def check_doh_header(connection, opts, level=homer.mandatory_levels["nicetohave"
header = ["Accept: %s" % accept, "Content-type: %s" % content_type]
test_name = "Test Header MIME: %s " % ", ".join(h for h in header)
r1 = homer.RequestDOH('curl.haxx.se', qtype=opts.rtype, use_edns=opts.edns, want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
r1 = remoh.RequestDOH('curl.haxx.se', qtype=opts.rtype, use_edns=opts.edns, want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
r1.post = True
requests = []
......@@ -252,7 +252,7 @@ def do_check(connection, requests, opts):
try:
connection.send_and_receive(bundle)
except (homer.ConnectionException, homer.DOHException) as e:
except (remoh.ConnectionException, remoh.DOHException) as e:
ok = False
print_check_result(test_name, ok, verbose=connection.verbose)
print(e, file=sys.stderr)
......@@ -266,7 +266,7 @@ def do_check(connection, requests, opts):
break
return ok
def check_truncated_query(connection, opts, level=homer.mandatory_levels["nicetohave"]):
def check_truncated_query(connection, opts, level=remoh.mandatory_levels["nicetohave"]):
# send truncated DNS request to the server and expect a HTTP return code
# either equal to 200 or in the 400 range
# in case the server answers with 200, look for a FORMERR error in the DNS
......@@ -281,9 +281,9 @@ def check_truncated_query(connection, opts, level=homer.mandatory_levels["niceto
test_name = 'Test truncated data'
if connection.dot:
request = homer.RequestDOT('example.com', qtype=opts.rtype, use_edns=opts.edns, want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
request = remoh.RequestDOT('example.com', qtype=opts.rtype, use_edns=opts.edns, want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
else:
request = homer.RequestDOH('example.com', qtype=opts.rtype, use_edns=opts.edns, want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
request = remoh.RequestDOH('example.com', qtype=opts.rtype, use_edns=opts.edns, want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
request.post = True
request.trunc_data()
......@@ -307,7 +307,7 @@ def check_truncated_query(connection, opts, level=homer.mandatory_levels["niceto
# the RCODE set to FORMERR
# so response can not be parsed in this case
return True
except homer.DOHException as e:
except remoh.DOHException as e:
print(e, file=sys.stderr)
return False
......@@ -337,7 +337,7 @@ def run_check(connection):
ok = check_dot_two_requests(connection, opts)
else:
ok = check_doh_methods(connection, opts)
if not ok and opts.mandatory_level >= homer.mandatory_levels["nicetohave"]:
if not ok and opts.mandatory_level >= remoh.mandatory_levels["nicetohave"]:
return False
# TODO we miss the tests of pipelining and out-of-order for DoT and
......@@ -348,11 +348,11 @@ def run_check(connection):
# The DoH server is right to reject these (Example: 'HTTP
# error 415: only Content-Type: application/dns-message is
# supported')
ok = check_doh_header(connection, opts, level=homer.mandatory_levels["nocrash"], accept="text/html") and ok
ok = check_doh_header(connection, opts, level=homer.mandatory_levels["nocrash"], content_type="text/html") and ok
ok = check_doh_header(connection, opts, level=remoh.mandatory_levels["nocrash"], accept="text/html") and ok
ok = check_doh_header(connection, opts, level=remoh.mandatory_levels["nocrash"], content_type="text/html") and ok
# test if a truncated query breaks anything
ok = check_truncated_query(connection, opts, level=homer.mandatory_levels["nocrash"]) and ok
ok = check_truncated_query(connection, opts, level=remoh.mandatory_levels["nocrash"]) and ok
return ok
......@@ -472,13 +472,13 @@ def parse_opts(opts):
if not opts.edns and not opts.no_ecs:
error_and_exit("ECS requires EDNS")
if opts.mandatory_level is not None and \
opts.mandatory_level not in homer.mandatory_levels.keys():
opts.mandatory_level not in remoh.mandatory_levels.keys():
error_and_exit("Unknown mandatory level \"%s\"" % opts.mandatory_level)
if opts.mandatory_level is not None and not opts.check:
error_and_exit("--mandatory-level only makes sense with --check")
if opts.mandatory_level is None:
opts.mandatory_level = "necessary"
opts.mandatory_level = homer.mandatory_levels[opts.mandatory_level]
opts.mandatory_level = remoh.mandatory_levels[opts.mandatory_level]
if opts.ifile is None and (len(args) != 2 and len(args) != 3):
error_and_exit("Wrong number of arguments")
if opts.ifile is not None and len(args) != 1:
......@@ -508,10 +508,10 @@ def run_default(name, connection, opts):
name, opts.rtype = get_next_domain(input)
if connection.dot:
request = homer.RequestDOT(name, qtype=opts.rtype, use_edns=opts.edns,
request = remoh.RequestDOT(name, qtype=opts.rtype, use_edns=opts.edns,
want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
else:
request = homer.RequestDOH(name, qtype=opts.rtype, use_edns=opts.edns,
request = remoh.RequestDOH(name, qtype=opts.rtype, use_edns=opts.edns,
want_dnssec=opts.dnssec, no_ecs=opts.no_ecs)
request.to_wire()
......@@ -528,7 +528,7 @@ def run_default(name, connection, opts):
else:
try:
connection.do_test(request) # perform the query
except (OpenSSL.SSL.Error, homer.ConnectionDOTException, homer.DOHException) as e:
except (OpenSSL.SSL.Error, remoh.ConnectionDOTException, remoh.DOHException) as e:
ok = False
error(e)
break
......@@ -545,12 +545,12 @@ def run_default(name, connection, opts):
done = 0
try:
current = connection.pipelining_init_pending(opts.max_in_flight)
except homer.ConnectionDOTException as e:
except remoh.ConnectionDOTException as e:
ok = False
error("%s, %i/%i requests never got a reply" % (e, opts.tests - connection.nbr_finished_queries, opts.tests))
else:
while done < opts.tests:
if time.time() > start + homer.MAX_DURATION: # if we send thousands of requests
if time.time() > start + remoh.MAX_DURATION: # if we send thousands of requests
# MAX_DURATION will be reached
# need to increase MAX_DURATION based
# on the number of queries
......@@ -561,7 +561,7 @@ def run_default(name, connection, opts):
break
id = connection.read_result(connection, connection.pending, display_results=opts.display_results)
if id is None: # Probably a timeout
time.sleep(homer.SLEEP_TIMEOUT)
time.sleep(remoh.SLEEP_TIMEOUT)
continue
done += 1
over, rank, request = connection.pending[id]
......@@ -570,7 +570,7 @@ def run_default(name, connection, opts):
if current < len(connection.all_requests):
try:
connection.pipelining_fill_pending(current)
except homer.ConnectionDOTException as e:
except remoh.ConnectionDOTException as e:
ok = False
error("%s, %i/%i requests never got a reply" % (e, opts.tests - connection.nbr_finished_queries, opts.tests))
break
......@@ -607,13 +607,13 @@ if not opts.check or opts.connectTo is not None:
ip_set = {opts.connectTo, }
else:
if opts.dot:
port = homer.PORT_DOT
if not homer.is_valid_hostname(url):
port = remoh.PORT_DOT
if not remoh.is_valid_hostname(url):
error_and_exit("DoT requires a host name or IP address, not \"%s\"" % url)
netloc = url
else:
port = homer.PORT_DOH
if not homer.is_valid_url(url):
port = remoh.PORT_DOH
if not remoh.is_valid_url(url):
error_and_exit("DoH requires a valid HTTPS URL, not \"%s\"" % url)
try:
url_parts = urllib.parse.urlparse(url) # A very poor validation, many
......@@ -647,12 +647,12 @@ for ip in ip_set:
print("(%d/%d) checking IP : %s" % (i, len(ip_set), ip))
try:
if opts.dot:
conn = homer.ConnectionDOT(url, servername=extracheck, connect_to=ip,
conn = remoh.ConnectionDOT(url, servername=extracheck, connect_to=ip,
forceIPv4=opts.forceIPv4, forceIPv6=opts.forceIPv6,
insecure=opts.insecure, verbose=opts.verbose, debug=opts.debug,
sni=opts.sni, key=opts.key, pipelining=opts.pipelining)
else:
conn = homer.ConnectionDOH(url, servername=extracheck, connect_to=ip,
conn = remoh.ConnectionDOH(url, servername=extracheck, connect_to=ip,
forceIPv4=opts.forceIPv4, forceIPv6=opts.forceIPv6,
insecure=opts.insecure, verbose=opts.verbose, debug=opts.debug,
multistreams=opts.multistreams)
......@@ -672,7 +672,7 @@ for ip in ip_set:
error("Could not resolve \"%s\"" % url)
ok = False
continue
except homer.ConnectionDOTException as e:
except remoh.ConnectionDOTException as e:
print(e, file=sys.stderr)
err = "Could not connect to \"%s\"" % url
if opts.connectTo is not None:
......@@ -682,7 +682,7 @@ for ip in ip_set:
error(err)
ok = False
continue
except (homer.ConnectionException, homer.DOHException) as e:
except (remoh.ConnectionException, remoh.DOHException) as e:
error(e)
ok = False
continue
......
......@@ -21,8 +21,8 @@ except ImportError as e:
print(e)
sys.exit(1)
import homer.utils
import homer.exceptions
import remoh.utils
import remoh.exceptions
class Connection:
......@@ -30,14 +30,14 @@ class Connection:
forceIPv4=False, forceIPv6=False, insecure=False,
verbose=False, debug=False, dot=False):
if dot and not homer.is_valid_hostname(server):
raise homer.ConnectionDOTException("DoT requires a host name or IP address, not \"%s\"" % server)
if dot and not remoh.is_valid_hostname(server):
raise remoh.ConnectionDOTException("DoT requires a host name or IP address, not \"%s\"" % server)
if not dot and not homer.is_valid_url(server):
raise homer.ConnectionDOHException("DoH requires a valid HTTPS URL, not \"%s\"" % server)
if not dot and not remoh.is_valid_url(server):
raise remoh.ConnectionDOHException("DoH requires a valid HTTPS URL, not \"%s\"" % server)
if forceIPv4 and forceIPv6:
raise homer.ConnectionException("Force IPv4 *or* IPv6 but not both")
raise remoh.ConnectionException("Force IPv4 *or* IPv6 but not both")
self.dot = dot
self.server = server
......@@ -107,11 +107,11 @@ class ConnectionDOT(Connection):
else:
addr = self.server # otherwise keep the server name
family = homer.get_addrfamily(addr, forceIPv4=self.forceIPv4, forceIPv6=self.forceIPv6)
addrinfo_list = socket.getaddrinfo(addr, homer.PORT_DOT, family)
family = remoh.get_addrfamily(addr, forceIPv4=self.forceIPv4, forceIPv6=self.forceIPv6)
addrinfo_list = socket.getaddrinfo(addr, remoh.PORT_DOT, family)
addrinfo_set = { (addrinfo[4], addrinfo[0]) for addrinfo in addrinfo_list }
signal.signal(signal.SIGALRM, homer.exceptions.timeout_connection)
signal.signal(signal.SIGALRM, remoh.exceptions.timeout_connection)
# contains a set of tuples ('ip address', 'error message')
errors = set()
......@@ -124,7 +124,7 @@ class ConnectionDOT(Connection):
# a string with all the errors
try:
self.establish_session(addrinfo[0], addrinfo[1])
except homer.ConnectionDOTException as e:
except remoh.ConnectionDOTException as e:
errors.add((addrinfo[0][0], str(e)))
if self.verbose and self.connect_to is None:
print(e, file=sys.stderr)
......@@ -134,7 +134,7 @@ class ConnectionDOT(Connection):
print("No other IP address")
# join all the errors into a single string
err = ', '.join( "%s: %s" % (e[0], e[1]) for e in errors)
raise homer.ConnectionDOTException(err)
raise remoh.ConnectionDOTException(err)
if self.verbose and self.connect_to is None:
print("Could not connect to %s" % addrinfo[0][0])
print("Trying another IP address")
......@@ -149,7 +149,7 @@ class ConnectionDOT(Connection):
self.hasher = hashlib.sha256()
# start the timer
signal.alarm(homer.TIMEOUT_CONN)
signal.alarm(remoh.TIMEOUT_CONN)
self.sock = socket.socket(sock_family, socket.SOCK_STREAM)
......@@ -170,27 +170,27 @@ class ConnectionDOT(Connection):
lambda conn, cert, errno, depth, preverify_ok: preverify_ok)
self.session = OpenSSL.SSL.Connection(self.context, self.sock)
if self.sni:
self.session.set_tlsext_host_name(homer.canonicalize(self.check_name_cert).encode())
self.session.set_tlsext_host_name(remoh.canonicalize(self.check_name_cert).encode())
try:
self.session.connect((addr))
self.session.do_handshake()
except homer.exceptions.TimeoutConnectionError:
except remoh.exceptions.TimeoutConnectionError:
self.state = 'CONN_TIMEOUT'
raise homer.ConnectionDOTException("Timeout")
raise remoh.ConnectionDOTException("Timeout")
except OSError:
self.state = 'CONN_FAILED'
raise homer.ConnectionDOTException("Cannot connect")
raise remoh.ConnectionDOTException("Cannot connect")
except OpenSSL.SSL.SysCallError as e:
self.state = e.args[1]