内部解析ip地址
This commit is contained in:
parent
7c3474afab
commit
d33fe7e540
@ -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.
|
||||
28
apps/dns_proxy/src/dns_utils.erl
Normal file
28
apps/dns_proxy/src/dns_utils.erl
Normal 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)).
|
||||
Loading…
x
Reference in New Issue
Block a user