polycule-network/dns.py
2024-08-01 22:16:29 +02:00

54 lines
1.7 KiB
Python

import time
import socket
from ipaddress import IPv4Address, IPv4Network
from dnslib import DNSRecord,RCODE,QTYPE
from dnslib.server import DNSServer,DNSHandler,BaseResolver,DNSLogger
from dnslib.label import DNSLabel
from dnslib.ranges import IP4
class ProxyResolver(BaseResolver):
def __init__(self, config):
self.timeout = config.dns_timeout
self.config = config
def resolve(self, request, handler):
qname = DNSLabel(request.q.qname)
dns = self.config.dns_server(str(qname))
try:
proxy_r = request.send(dns.address, dns.port, timeout=self.timeout)
reply = DNSRecord.parse(proxy_r)
except socket.timeout:
reply = request.reply()
reply.header.rcode = getattr(RCODE, 'NXDOMAIN')
return reply
if dns.network != None and dns.network != config.local_network:
for rr in reply.rr:
rr.rdata.data = IPv4Address(config.translate(str(rr.rdata), network)).packed
reply.set_header_qa()
return reply
def translate(ip, untranslated_range, translated_range):
for (loc, trans) in zip(IPv4Network(untranslated_range), IPv4Network(translated_range)):
if str(loc) == ip:
return str(trans)
return ip
def run(config):
resolver = ProxyResolver(config)
handler = DNSHandler
logger = DNSLogger("+request,+reply,+truncated,+error,-recv,-send,-data")
udp_server = DNSServer(
resolver,
port=config.listen_port,
address=config.listen_address,
logger=logger,
handler=handler
)
udp_server.start_thread()
while udp_server.isAlive():
time.sleep(1)