内部解析ip地址

This commit is contained in:
anlicheng 2025-12-05 18:32:06 +08:00
parent 7c3474afab
commit d33fe7e540
2 changed files with 87 additions and 23 deletions

View File

@ -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.
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.

View File

@ -0,0 +1,28 @@
%%%-------------------------------------------------------------------
%%% @author anlicheng
%%% @copyright (C) 2025, <COMPANY>
%%% @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)).