简化dns的查询逻辑
This commit is contained in:
parent
d33fe7e540
commit
a32f00a1d8
@ -73,64 +73,13 @@ handle_call(_Request, _From, State = #state{}) ->
|
||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||
{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 = #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};
|
||||
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 ->
|
||||
lager:warning("[dns_handler] decode dns query get error: ~p", [Other]),
|
||||
{stop, normal, State}
|
||||
end.
|
||||
case resolver(Packet) of
|
||||
{ok, Resp} ->
|
||||
gen_udp:send(Sock, SrcIp, SrcPort, Resp);
|
||||
{error, Reason} ->
|
||||
lager:debug("[dns_handler] resolver get error: ~p", [Reason])
|
||||
end,
|
||||
{stop, normal, State}.
|
||||
|
||||
%% @private
|
||||
%% @doc Handling all non call/cast messages
|
||||
@ -163,6 +112,63 @@ code_change(_OldVsn, State = #state{}, _Extra) ->
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
|
||||
-spec resolver(Packet :: binary()) -> {ok, Resp :: binary()} | {error, Reason :: any()}.
|
||||
resolver(Packet) when is_binary(Packet) ->
|
||||
resolver0(Packet, dns:decode_message(Packet)).
|
||||
resolver0(Packet, 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 = []
|
||||
},
|
||||
{ok, dns:encode_message(RespMsg)};
|
||||
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),
|
||||
{ok, dns:encode_message(RespMsg)};
|
||||
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),
|
||||
{ok, Resp};
|
||||
Error ->
|
||||
lager:debug("[dns_handler] parse reply get error: ~p", [Error]),
|
||||
Error
|
||||
end
|
||||
after 5000 ->
|
||||
{error, timeout}
|
||||
end
|
||||
end
|
||||
end;
|
||||
resolver0(_, Error) ->
|
||||
lager:warning("[dns_handler] decode dns query get error: ~p", [Error]),
|
||||
Error.
|
||||
|
||||
-spec forward_to_upstream(Ref :: reference(), Request :: binary(), QueryMsg :: #dns_message{}) -> no_return().
|
||||
forward_to_upstream(Ref, Request, QueryMsg) ->
|
||||
ReceiverPid = self(),
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
sync,
|
||||
lager,
|
||||
dns_erlang,
|
||||
pkt,
|
||||
poolboy,
|
||||
kernel,
|
||||
stdlib
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
{deps, [
|
||||
{dns_erlang, ".*", {git, "https://github.com/dnsimple/dns_erlang.git", {tag, "v4.4.0"}}},
|
||||
{poolboy, ".*", {git, "https://github.com/devinus/poolboy.git", {tag, "1.5.1"}}},
|
||||
{pkt, ".*", {git, "https://github.com/msantos/pkt.git", {tag, "0.6.0"}}},
|
||||
{sync, ".*", {git, "https://github.com/rustyio/sync.git", {branch, "master"}}},
|
||||
{parse_trans, ".*", {git, "https://github.com/uwiger/parse_trans", {tag, "3.0.0"}}},
|
||||
{lager, ".*", {git,"https://github.com/erlang-lager/lager.git", {tag, "3.9.2"}}}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user