diff --git a/apps/sdlan/src/dns_proxy/dns_handler.erl b/apps/sdlan/src/dns_proxy/dns_handler.erl index 67d3f18..cdb3b62 100644 --- a/apps/sdlan/src/dns_proxy/dns_handler.erl +++ b/apps/sdlan/src/dns_proxy/dns_handler.erl @@ -90,7 +90,7 @@ resolver0(Packet, QueryMsg = #dns_message{qc = 1, questions = [Question = #dns_q RespMsg = build_response(QueryMsg, Cache), {ok, dns:encode_message(RespMsg)}; miss -> - case forward_to_upstream(Packet, QueryMsg) of + case forward_to_upstream(Packet) of {ok, Resp} -> case dns:decode_message(Resp) of RespMsg = #dns_message{answers = Answers} -> @@ -182,22 +182,21 @@ build_ip_packet(SAddr, DAddr, SPort, DPort, UdpPayload) when is_integer(SPort), <>. --spec forward_to_upstream(Request :: binary(), QueryMsg :: #dns_message{}) -> no_return(). -forward_to_upstream(Request, #dns_message{id = TxId, questions = [#dns_query{name = QName, type = QType, class = QClass}|_]}) -> - {ok, {DnsIp, DnsPort}} = application:get_env(sdlan, public_dns_server), +-spec forward_to_upstream(Request :: binary()) -> {ok, Resp :: binary()} | {error, Reason :: any()}. +forward_to_upstream(Request) -> + {DnsIp, DnsPort} = select_dns_server(), {ok, Socket} = gen_udp:open(0, [binary, {active, true}]), ok = gen_udp:send(Socket, DnsIp, DnsPort, Request), logger:debug("[dns_resolver] send to: ~p, packet: ~p", [{DnsIp, DnsPort}, Request]), receive {udp, Socket, DnsIp, DnsPort, Resp} -> - try dns:decode_message(Resp) of - #dns_message{id = TxId, questions = [#dns_query{name = QName, type = QType, class = QClass}|_]} -> - {ok, Resp}; - _ -> - {error, invalid_dns_response} - catch error:Err -> - {error, Err} - end + {ok, Resp} after 2000 -> {error, timeout} - end. \ No newline at end of file + end. + +-spec select_dns_server() -> {DnsIp :: inet:ip4_address(), DnsPort :: pos_integer()}. +select_dns_server() -> + {ok, DnsServers} = application:get_env(sdlan, public_dns_server), + Idx = rand:uniform(length(DnsServers)), + lists:nth(Idx, DnsServers). \ No newline at end of file