1252265Sjimharris# Copyright (C) Internet Systems Consortium, Inc. ("ISC") 2252265Sjimharris# 3252265Sjimharris# SPDX-License-Identifier: MPL-2.0 4252265Sjimharris# 5252265Sjimharris# This Source Code Form is subject to the terms of the Mozilla Public 6252265Sjimharris# License, v. 2.0. If a copy of the MPL was not distributed with this 7252265Sjimharris# file, you can obtain one at https://mozilla.org/MPL/2.0/. 8252265Sjimharris# 9252265Sjimharris# See the COPYRIGHT file distributed with this work for additional 10252265Sjimharris# information regarding copyright ownership. 11252265Sjimharris 12252265Sjimharrisimport os 13252265Sjimharrisimport select 14252265Sjimharrisimport signal 15252265Sjimharrisimport socket 16252265Sjimharrisimport sys 17252265Sjimharrisimport time 18252265Sjimharris 19252265Sjimharrisimport dns.flags 20252265Sjimharrisimport dns.message 21252265Sjimharris 22252265Sjimharris 23252265Sjimharrisdef port(): 24252265Sjimharris env_port = os.getenv("PORT") 25252265Sjimharris if env_port is None: 26252265Sjimharris env_port = 5300 27252265Sjimharris else: 28252265Sjimharris env_port = int(env_port) 29252265Sjimharris 30252265Sjimharris return env_port 31252265Sjimharris 32252265Sjimharris 33252265Sjimharrisdef udp_listen(port): 34252265Sjimharris udp = socket.socket(type=socket.SOCK_DGRAM) 35252265Sjimharris udp.bind(("10.53.0.3", port)) 36252265Sjimharris 37252265Sjimharris return udp 38252265Sjimharris 39252265Sjimharris 40252265Sjimharrisdef tcp_listen(port): 41252265Sjimharris tcp = socket.socket(type=socket.SOCK_STREAM) 42252265Sjimharris tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 43252265Sjimharris tcp.bind(("10.53.0.3", port)) 44252265Sjimharris tcp.listen(100) 45252265Sjimharris 46252265Sjimharris return tcp 47252265Sjimharris 48252265Sjimharris 49252265Sjimharrisdef udp_tc_once(udp): 50252265Sjimharris qrybytes, clientaddr = udp.recvfrom(65535) 51252265Sjimharris qry = dns.message.from_wire(qrybytes) 52252265Sjimharris answ = dns.message.make_response(qry) 53252265Sjimharris answ.flags |= dns.flags.TC 54252265Sjimharris answbytes = answ.to_wire() 55252265Sjimharris udp.sendto(answbytes, clientaddr) 56252265Sjimharris 57252265Sjimharris 58252265Sjimharrisdef tcp_once(tcp): 59252265Sjimharris csock, _clientaddr = tcp.accept() 60252265Sjimharris time.sleep(5) 61252265Sjimharris csock.close() 62252265Sjimharris 63252265Sjimharris 64252265Sjimharrisdef sigterm(signum, frame): 65252265Sjimharris os.remove("ans.pid") 66252265Sjimharris sys.exit(0) 67252265Sjimharris 68252265Sjimharris 69252265Sjimharrisdef write_pid(): 70252265Sjimharris with open("ans.pid", "w") as f: 71252265Sjimharris pid = os.getpid() 72252265Sjimharris f.write("{}".format(pid)) 73252265Sjimharris 74252265Sjimharris 75252265Sjimharrissignal.signal(signal.SIGTERM, sigterm) 76252265Sjimharriswrite_pid() 77252265Sjimharris 78252265Sjimharrisudp = udp_listen(port()) 79252265Sjimharristcp = tcp_listen(port()) 80252265Sjimharris 81252270Sjimharrisinput = [udp, tcp] 82252265Sjimharris 83252265Sjimharriswhile True: 84252265Sjimharris try: 85252265Sjimharris inputready, outputready, exceptready = select.select(input, [], []) 86252265Sjimharris except select.error: 87252265Sjimharris break 88252265Sjimharris except socket.error: 89252265Sjimharris break 90252265Sjimharris except KeyboardInterrupt: 91252265Sjimharris break 92252265Sjimharris 93252265Sjimharris for s in inputready: 94252265Sjimharris if s == udp: 95252265Sjimharris udp_tc_once(udp) 96252265Sjimharris if s == tcp: 97252265Sjimharris tcp_once(tcp) 98252270Sjimharris 99252270Sjimharrissigterm(signal.SIGTERM, 0) 100252265Sjimharris