Mar 03 22:20:29 ~/gitrs/.../dns/client$ sudo ./test_autonomous_dnsmasq.py running: dnsmasq -C /dev/null -a 127.0.0.1 -p 553 -H dnsmasq_records dns query timed out killing: dnsmasq -C /dev/null -a 127.0.0.1 -p 553 -H dnsmasq_records Mar 03 22:20:46 ~/gitrs/.../dns/client$ cat dnsmasq_records 1.2.3.4 myhost5.tld Mar 03 22:21:21 ~/gitrs/.../dns/client$ cat test_autonomous_dnsmasq.py #!/usr/bin/env python3 ## ## Temporarily start a local dns server to resolve dns names ## provided by a records file, then kill the server. ## ## ~Johnny, 2023-03-03 ## import psutil, dns.resolver, subprocess, sys # specify constants/config dns_name_to_resolve = 'myhost5.tld' dns_record_type = 'A' dns_nameserver_cmd = 'dnsmasq' local_only_ipaddr = '127.0.0.1' local_only_port = 553 # arbitrary number, hoping for no port-# collision timeout_in_secs = 2.0 records_file_path = 'dnsmasq_records' dnsmasq_cmd_list = [dns_nameserver_cmd, '-C', '/dev/null', '-a', local_only_ipaddr, '-p', str(local_only_port), '-H', records_file_path] dnsmasq_cmd_string = ' '.join(dnsmasq_cmd_list) def kill_local_dns_nameserver(error_if_does_not_exist = False): # psutil: # https://stackoverflow.com/a/4230226/605356 for proc in psutil.process_iter(): if (proc.name() == dns_nameserver_cmd): if (proc.cmdline() == dnsmasq_cmd_list): print ('killing: ' + dnsmasq_cmd_string) try: proc.kill() except psutil.NoSuchProcess: if error_if_does_not_exist: print(dns_nameserver_cmd + ' kill: process not found') except psutil.AccessDenied: print(dns_nameserver_cmd + ' kill: permission denied') except psutil.TimeoutExpired: print(dns_nameserver_cmd + ' kill: timed out while waiting for process to terminate') except: print(dns_nameserver_cmd + ' kill: general failure') # start local-only dnsmasq kill_local_dns_nameserver() # first make sure it's not running print('running: ' + dnsmasq_cmd_string) try: dnsmasq = subprocess.Popen(dnsmasq_cmd_list) except: print('could not start: ' + dns_nameserver_cmd) sys.exit() dnsmasq.wait() # setup dns-client resolver resolver = dns.resolver.Resolver() resolver.port = local_only_port resolver.nameservers = [local_only_ipaddr] resolver.timeout = timeout_in_secs resolver.lifetime = timeout_in_secs # run dns_nameserver, print lookup/resolve, then kill dns_nameserver if not dnsmasq.returncode: # manage timeout/lifetime: # https://stackoverflow.com/a/8989817/605356 try: # resolve() replaces query(): # https://stackoverflow.com/a/64754367/605356 #response = resolver.query (qname=dns_name_to_resolve, rdtype=dns_record_type) response = resolver.resolve(qname=dns_name_to_resolve, rdtype=dns_record_type) for rdata in response: print(dns_name_to_resolve + ': ' + str(rdata)) except dns.resolver.Timeout: print('dns query timed out') # stop local-only dnsmasq kill_local_dns_nameserver(error_if_does_not_exist = True) Mar 03 22:21:56 ~/gitrs/.../dns/client$ Mar 03 22:22:02 ~/gitrs/.../dns/client$ sw_vers ProductName: macOS ProductVersion: 12.6.3 BuildVersion: 21G419 Mar 03 22:22:07 ~/gitrs/.../dns/client$ python3 --version Python 3.11.2 Mar 03 22:22:12 ~/gitrs/.../dns/client$ Mar 03 22:22:14 ~/gitrs/.../dns/client$ pip3 install dnspython Requirement already satisfied: dnspython in /opt/homebrew/lib/python3.11/site-packages (2.3.0) Mar 03 22:22:21 ~/gitrs/.../dns/client$