Example #1
0
    def handle_query(self, transaction_id, query_data):
        try:
            query_parser = parse.ParseQuery(query_data)
            parse_result = query_parser.parse_plain()
            query_name_list = parse_result[1]['QNAME']
            query_type = parse_result[1]['QTYPE']
            query_name = utils.get_domain_name_string(query_name_list)

            if self.enable_log:
                self.logger.write_log('query_parse_result:' + str(parse_result))

            cache_query = None
            cached = False

            if self.enable_cache and query_name in self.cache and query_type in self.cache[query_name]:
                cache_query = self.cache[query_name][query_type]
                cache_time = cache_query[1]
                cache_ttl = cache_query[2]
                current_time = int(time.time())

                if current_time - cache_time > cache_ttl:
                    self.cache[query_name].pop(query_type)
                else:
                    cached = True

            if cached:
                cache_query_result = cache_query[0]

                cache_query_result = bytes.fromhex(transaction_id) + cache_query_result[2:]
                sendback_address = self.dns_map[transaction_id][0]
                self.server.sendto(cache_query_result, sendback_address)
                self.dns_map.pop(transaction_id)
            else:
                if query_name in self.dns_config['dns_bypass']:
                    upstream_object = self.bootstrap_dns_object
                    upstream_object.query(query_data)
                elif self.dns_bypass_china:
                    upstream_object = self.bootstrap_dns_object
                    upstream_object.query(query_data)
                    upstream_object = self.select_upstream()
                    upstream_object.query(query_data)
                else:
                    upstream_object = self.select_upstream()
                    upstream_object.query(query_data)

        except IndexError as exc:
            print('[Error]', str(exc))
        except KeyboardInterrupt:
            exit()
        except Exception as exc:
            print('[Error]', str(exc))
Example #2
0
    def start(self):
        try:
            while True:
                recv_data, recv_address = self.server.recvfrom(512)
                recv_header = parse.ParseHeader.parse_header(recv_data)
                if self.enable_log:
                    self.logger.write_log('recv_data:' + str(recv_data))

                transaction_id = recv_header['transaction_id']
                if self.enable_log:
                    self.logger.write_log('transaction_id:' + str(transaction_id))

                if recv_header['flags']['QR'] == '0':
                    self.dns_map[transaction_id] = [recv_address, 0]
                    query_thread = threading.Thread(target=self.handle_query, args=(transaction_id, recv_data,))
                    query_thread.daemon = True
                    query_thread.start()

                elif recv_header['flags']['QR'] == '1' and transaction_id in self.dns_map:
                    response = self.handle_response(recv_data)
                    sendback_address = self.dns_map[transaction_id][0]

                    if self.dns_bypass_china and response[2]:
                        if len(response[2]) > 1:
                            ip_address = response[2][-1]['record']
                        else:
                            ip_address = response[2][0]['record']

                        if self.dns_map[transaction_id][1] == 1 or (
                                utils.is_valid_ipv4_address(ip_address) and utils.is_subnet_address(
                                'filter_lists/chnroute.txt', ip_address)
                        ):
                            self.server.sendto(recv_data, sendback_address)
                            self.dns_map.pop(transaction_id)
                        elif self.dns_map[transaction_id][1] == 0:
                            self.dns_map[transaction_id][1] = 1
                            continue
                    else:
                        self.server.sendto(recv_data, sendback_address)
                        self.dns_map.pop(transaction_id)

                    if self.enable_cache and response[2]:
                        response_name = utils.get_domain_name_string(response[1]['QNAME'])
                        if response_name != '':
                            response_type = response[1]['QTYPE']
                            response_ttl = response[2][0]['ttl']
                            if response_name not in self.cache:
                                self.cache[response_name] = {}
                            self.cache[response_name][response_type] = [recv_data, int(time.time()), response_ttl]

        except socket.timeout as exc:
            print('[Error]', str(exc))
            self.start()

        except KeyboardInterrupt:
            print('Stop Encrypted-DNS Resolver')
            exit()

        except Exception as exc:
            print('[Error]', str(exc))
            self.start()
Example #3
0
    def handle_query(self, transaction_id, query_data):
        try:
            query_parser = parse.ParseQuery(query_data)
            parse_result = query_parser.parse_plain()
            query_name_list = parse_result[1]['QNAME']
            query_type = parse_result[1]['QTYPE']
            query_name = utils.get_domain_name_string(query_name_list)

            if self.enable_log:
                self.logger.write_log('query_parse_result:' + str(parse_result))

            cache_query = None
            cached = False

            for item in self.hosts.keys():
                if query_name == item or (item.startswith("include:") and item.lstrip("include:") in query_name):
                    response_data = utils.struct_response(query_name, str(transaction_id),
                                                          query_type, self.hosts[item][0],
                                                          self.hosts[item][1])
                    sendback_address = self.dns_map[transaction_id][0]
                    self.server.sendto(response_data, sendback_address)
                    self.dns_map.pop(transaction_id)
                    return

            if self.enable_cache and query_name in self.cache and query_type in self.cache[query_name]:
                cache_query = self.cache[query_name][query_type]
                cache_time = cache_query[1]
                cache_ttl = cache_query[2]
                current_time = int(time.time())

                if current_time - cache_time > cache_ttl:
                    self.cache[query_name].pop(query_type)
                else:
                    cached = True

            if cached:
                cache_query_result = cache_query[0]
                cache_query_result = bytes.fromhex(transaction_id) + cache_query_result[2:]
                sendback_address = self.dns_map[transaction_id][0]
                self.server.sendto(cache_query_result, sendback_address)
                self.dns_map.pop(transaction_id)
            else:
                if query_name in self.dns_config['dns_bypass']:
                    upstream_object = self.bootstrap_dns_object
                    upstream_object.query(query_data)
                elif self.dns_bypass_china:
                    upstream_object = self.bootstrap_dns_object
                    upstream_object.query(query_data)
                    upstream_object = self.select_upstream()
                    upstream_object.query(query_data)
                else:
                    upstream_object = self.select_upstream()
                    upstream_object.query(query_data)

        except IndexError as exc:
            print('[Error]', str(exc))

        except KeyboardInterrupt:
            print('Stop Encrypted-DNS Resolver')
            exit()

        except Exception as exc:
            print('[Error]', str(exc))
            raise exc