From d33fe7e5403038ed67a60e62e6cbca21a3ab1dc0 Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Fri, 5 Dec 2025 18:32:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=85=E9=83=A8=E8=A7=A3=E6=9E=90ip=E5=9C=B0?= =?UTF-8?q?=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/dns_proxy/src/dns_handler.erl | 82 +++++++++++++++++++++--------- apps/dns_proxy/src/dns_utils.erl | 28 ++++++++++ 2 files changed, 87 insertions(+), 23 deletions(-) create mode 100644 apps/dns_proxy/src/dns_utils.erl diff --git a/apps/dns_proxy/src/dns_handler.erl b/apps/dns_proxy/src/dns_handler.erl index 90ca8e2..8c24d30 100644 --- a/apps/dns_proxy/src/dns_handler.erl +++ b/apps/dns_proxy/src/dns_handler.erl @@ -74,30 +74,57 @@ handle_call(_Request, _From, State = #state{}) -> {stop, Reason :: term(), NewState :: #state{}}). handle_cast(handle, State = #state{socket = Sock, src_ip = SrcIp, src_port = SrcPort, packet = Packet}) -> case dns:decode_message(Packet) of - QueryMsg = #dns_message{qc = 1, questions = [Question|_]} -> - case dns_cache:lookup(Question) of - {hit, Cache} -> - lager:debug("[dns_handler] question: ~p, hit cache: ~p", [Question, Cache]), - RespMsg = build_response(QueryMsg, Cache), + QueryMsg = #dns_message{qc = 1, questions = [Question = #dns_query{name = QName, type = QType, class = QClass}|_]} -> + %% 查找是否是内置的域名 + case search_inbuilt_domain(QName) of + {ok, Ip} -> + Answer = #dns_rr { + name = QName, + type = QType, + class = QClass, + ttl = 300, + data = #dns_rrdata_a { + ip = Ip + } + }, + RespMsg = QueryMsg#dns_message{ + qr = true, + ra = true, + anc = 1, + auc = 0, + adc = 0, + answers = [Answer], + authority = [], + additional = [] + }, gen_udp:send(Sock, SrcIp, SrcPort, dns:encode_message(RespMsg)), + {stop, normal, State}; - miss -> - lager:debug("[dns_handler] cache is miss"), - Ref = make_ref(), - forward_to_upstream(Ref, Packet, QueryMsg), - receive - {dns_resolver_reply, Ref, Resp} -> - case dns:decode_message(Resp) of - RespMsg = #dns_message{answers = Answers} -> - lager:debug("[dns_handler] get a response answers: ~p", [Answers]), - dns_cache:insert(Question, RespMsg), - gen_udp:send(Sock, SrcIp, SrcPort, Resp); - Other -> - lager:debug("[dns_handler] parse reply get error: ~p", [Other]) - end, - {stop, normal, State} - after 5000 -> - {stop, normal, State} + error -> + case dns_cache:lookup(Question) of + {hit, Cache} -> + lager:debug("[dns_handler] question: ~p, hit cache answers: ~p", [Question, Cache#dns_cache.answers]), + RespMsg = build_response(QueryMsg, Cache), + gen_udp:send(Sock, SrcIp, SrcPort, dns:encode_message(RespMsg)), + {stop, normal, State}; + miss -> + lager:debug("[dns_handler] cache is miss"), + Ref = make_ref(), + forward_to_upstream(Ref, Packet, QueryMsg), + receive + {dns_resolver_reply, Ref, Resp} -> + case dns:decode_message(Resp) of + RespMsg = #dns_message{answers = Answers} -> + lager:debug("[dns_handler] get a response answers: ~p", [Answers]), + dns_cache:insert(Question, RespMsg), + gen_udp:send(Sock, SrcIp, SrcPort, Resp); + Other -> + lager:debug("[dns_handler] parse reply get error: ~p", [Other]) + end, + {stop, normal, State} + after 5000 -> + {stop, normal, State} + end end end; Other -> @@ -167,4 +194,13 @@ build_response(QueryMsg, #dns_cache{expire_at = ExpireAt, answers = Answers, aut adjust_ttl(RR = #dns_rr{}, RemainingTTL) -> RR#dns_rr{ttl = max(0, RemainingTTL)}; adjust_ttl(RR, _RemainingTTL) -> - RR. \ No newline at end of file + RR. + +search_inbuilt_domain(QName) when is_binary(QName) -> + Suffix = <<".iot.cn">>, + case dns_utils:ends_with(QName, Suffix) of + true -> + {ok, {192, 168, 1, 101}}; + false -> + error + end. \ No newline at end of file diff --git a/apps/dns_proxy/src/dns_utils.erl b/apps/dns_proxy/src/dns_utils.erl new file mode 100644 index 0000000..7cef0ef --- /dev/null +++ b/apps/dns_proxy/src/dns_utils.erl @@ -0,0 +1,28 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2025, +%%% @doc +%%% +%%% @end +%%% Created : 05. 12月 2025 18:06 +%%%------------------------------------------------------------------- +-module(dns_utils). +-author("anlicheng"). + +%% API +-export([ends_with/2, parse_address/1]). + +-spec ends_with(Bin :: binary(), Suffix :: binary()) -> boolean(). +ends_with(Bin, Suffix) when is_binary(Bin), is_binary(Suffix) -> + case binary:match(Bin, Suffix) of + {Pos, Len} -> + Pos + Len =:= byte_size(Bin); + nomatch -> + false + end. + +-spec parse_address(Ip :: any()) -> {ok, IpAddress :: inet:ip4_address()} | {error, Reason :: any()}. +parse_address(Ip = {Ip0, Ip1, Ip2, Ip3}) when is_integer(Ip0), is_integer(Ip1), is_integer(Ip2), is_integer(Ip3) -> + {ok, Ip}; +parse_address(Bin) when is_binary(Bin) -> + inet:parse_address(binary_to_list(Bin)).