diff --git a/apps/sdlan/include/sdlan_pb.hrl b/apps/sdlan/include/sdlan_pb.hrl index d08a24e..2a1f09f 100644 --- a/apps/sdlan/include/sdlan_pb.hrl +++ b/apps/sdlan/include/sdlan_pb.hrl @@ -53,7 +53,7 @@ pub_key = <<>> :: unicode:chardata() | undefined, % = 5, optional token = <<>> :: unicode:chardata() | undefined, % = 6, optional network_code = <<>> :: unicode:chardata() | undefined, % = 7, optional - host_name = <<>> :: unicode:chardata() | undefined % = 8, optional + hostname = <<>> :: unicode:chardata() | undefined % = 8, optional }). -endif. diff --git a/apps/sdlan/src/dns_proxy/dns_handler.erl b/apps/sdlan/src/dns_proxy/dns_handler.erl index fa605d2..21c6893 100644 --- a/apps/sdlan/src/dns_proxy/dns_handler.erl +++ b/apps/sdlan/src/dns_proxy/dns_handler.erl @@ -150,33 +150,42 @@ resolver0(Packet, QueryMsg = #dns_message{qc = 1, questions = [Question = #dns_q lager:debug("[dns_handler] inbuilt qnanme: ~p, ip: ~p", [QName, Ip]), {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, Error} + %% 是否命中内部的域名后缀 + EmptyDnsResp = dns:encode_message(build_nxdomain_response(QueryMsg)), + case sdlan_domain_regedit:maybe_domain(QName) of + true -> + lager:debug("[dns_handler] inbuilt qnanme: ~p, domain not exits", [QName]), + {ok, EmptyDnsResp}; + false -> + 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]), + {ok, EmptyDnsResp} + end + after 5000 -> + lager:debug("[dns_handler] forward_to_upstream timeout"), + {ok, EmptyDnsResp} end - after 5000 -> - {error, timeout} end end end; resolver0(_, Error) -> - lager:warning("[dns_handler] decode dns query get error: ~p", [Error]), + lager:warning("[dns_handler] decode dns_query get error: ~p", [Error]), {error, Error}. -spec forward_to_upstream(Ref :: reference(), Request :: binary(), QueryMsg :: #dns_message{}) -> no_return(). @@ -212,6 +221,21 @@ adjust_ttl(RR = #dns_rr{}, RemainingTTL) -> adjust_ttl(RR, _RemainingTTL) -> RR. +-spec build_nxdomain_response(QueryMsg :: #dns_message{}) -> EmptyResp :: #dns_message{}. +build_nxdomain_response(QueryMsg) -> + QueryMsg#dns_message{ + qr = true, + aa = true, + ra = true, + rc = ?DNS_RCODE_NXDOMAIN, + anc = 0, + auc = 0, + adc = 0, + answers = [], + authority = [], + additional = [] + }. + -spec build_ip_packet(SAddr :: inet:ip4_address(), DAddr :: inet:ip4_address(), SPort :: integer(), DPort :: integer(), Payload :: binary()) -> IpPacket :: binary(). build_ip_packet(SAddr, DAddr, SPort, DPort, UdpPayload) when is_integer(SPort), is_integer(DPort), is_binary(UdpPayload) -> ULen = 8 + byte_size(UdpPayload), diff --git a/apps/sdlan/src/sdlan_app.erl b/apps/sdlan/src/sdlan_app.erl index acfc0cb..9122000 100644 --- a/apps/sdlan/src/sdlan_app.erl +++ b/apps/sdlan/src/sdlan_app.erl @@ -18,6 +18,7 @@ start(_StartType, _StartArgs) -> %% 启动注册表 sdlan_hostname_regedit:init(), + sdlan_domain_regedit:init(), start_http_server(), start_tcp_server(), diff --git a/apps/sdlan/src/sdlan_domain_regedit.erl b/apps/sdlan/src/sdlan_domain_regedit.erl new file mode 100644 index 0000000..7fe64df --- /dev/null +++ b/apps/sdlan/src/sdlan_domain_regedit.erl @@ -0,0 +1,36 @@ +%%%------------------------------------------------------------------- +%%% @author anlicheng +%%% @copyright (C) 2025, +%%% @doc +%%% 内部地址协议注册表 +%%% @end +%%% Created : 13. 12月 2025 21:09 +%%%------------------------------------------------------------------- +-module(sdlan_domain_regedit). +-author("anlicheng"). + +%% API +-export([init/0, insert/1, maybe_domain/1]). + +-define(TABLE, sdlan_domain_regedit). + +init() -> + ets:new(?TABLE, [named_table, ordered_set, public, {read_concurrency, true}, {write_concurrency, true}]). + +-spec maybe_domain(QName :: binary()) -> boolean(). +maybe_domain(QName) when is_binary(QName) -> + case binary:split(QName, <<".">>) of + [_, Domain] -> + case ets:lookup(?TABLE, Domain) of + [{Domain}] -> + true; + [] -> + false + end; + _ -> + false + end. + +-spec insert(Domain :: binary()) -> no_return(). +insert(Domain) when is_binary(Domain) -> + true = ets:insert(?TABLE, {Domain}). \ No newline at end of file diff --git a/apps/sdlan/src/sdlan_network.erl b/apps/sdlan/src/sdlan_network.erl index 3bdee21..5672296 100644 --- a/apps/sdlan/src/sdlan_network.erl +++ b/apps/sdlan/src/sdlan_network.erl @@ -175,6 +175,8 @@ init([Id]) when is_integer(Id) -> lager:debug("[sdlan_network] network: ~p, ips: ~p", [Id, lists:map(fun sdlan_ipaddr:int_to_ipv4/1, Ips)]), + sdlan_domain_regedit:insert(Domain), + {ok, #state{network_id = Id, name = Name, domain = Domain, ipaddr = IpAddr, owner_id = OwnerId, mask_len = MaskLen, ips = Ips, aes_key = AesKey, throttle_key = ThrottleKey}}; {error, Reason} -> lager:warning("[sdlan_network] load network: ~p, get error: ~p", [Id, Reason]), diff --git a/apps/sdlan/src/sdlan_pb.erl b/apps/sdlan/src/sdlan_pb.erl index eecf350..a7c4c8c 100644 --- a/apps/sdlan/src/sdlan_pb.erl +++ b/apps/sdlan/src/sdlan_pb.erl @@ -267,7 +267,7 @@ encode_msg_sdl_empty(_Msg, _TrUserData) -> <<>>. encode_msg_sdl_register_super(Msg, TrUserData) -> encode_msg_sdl_register_super(Msg, <<>>, TrUserData). -encode_msg_sdl_register_super(#sdl_register_super{version = F1, installed_channel = F2, client_id = F3, dev_addr = F4, pub_key = F5, token = F6, network_code = F7, host_name = F8}, Bin, TrUserData) -> +encode_msg_sdl_register_super(#sdl_register_super{version = F1, installed_channel = F2, client_id = F3, dev_addr = F4, pub_key = F5, token = F6, network_code = F7, hostname = F8}, Bin, TrUserData) -> B1 = if F1 == undefined -> Bin; true -> begin @@ -1296,9 +1296,9 @@ dfp_read_field_def_sdl_register_super(<<34, Rest/binary>>, Z1, Z2, F, F@_1, F@_2 dfp_read_field_def_sdl_register_super(<<42, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_sdl_register_super_pub_key(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); dfp_read_field_def_sdl_register_super(<<50, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_sdl_register_super_token(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); dfp_read_field_def_sdl_register_super(<<58, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_sdl_register_super_network_code(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -dfp_read_field_def_sdl_register_super(<<66, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_sdl_register_super_host_name(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +dfp_read_field_def_sdl_register_super(<<66, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> d_field_sdl_register_super_hostname(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); dfp_read_field_def_sdl_register_super(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, _) -> - #sdl_register_super{version = F@_1, installed_channel = F@_2, client_id = F@_3, dev_addr = F@_4, pub_key = F@_5, token = F@_6, network_code = F@_7, host_name = F@_8}; + #sdl_register_super{version = F@_1, installed_channel = F@_2, client_id = F@_3, dev_addr = F@_4, pub_key = F@_5, token = F@_6, network_code = F@_7, hostname = F@_8}; dfp_read_field_def_sdl_register_super(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> dg_read_field_def_sdl_register_super(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData). dg_read_field_def_sdl_register_super(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 32 - 7 -> @@ -1313,7 +1313,7 @@ dg_read_field_def_sdl_register_super(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, 42 -> d_field_sdl_register_super_pub_key(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); 50 -> d_field_sdl_register_super_token(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); 58 -> d_field_sdl_register_super_network_code(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); - 66 -> d_field_sdl_register_super_host_name(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); + 66 -> d_field_sdl_register_super_hostname(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); _ -> case Key band 7 of 0 -> skip_varint_sdl_register_super(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); @@ -1324,7 +1324,7 @@ dg_read_field_def_sdl_register_super(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, end end; dg_read_field_def_sdl_register_super(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, _) -> - #sdl_register_super{version = F@_1, installed_channel = F@_2, client_id = F@_3, dev_addr = F@_4, pub_key = F@_5, token = F@_6, network_code = F@_7, host_name = F@_8}. + #sdl_register_super{version = F@_1, installed_channel = F@_2, client_id = F@_3, dev_addr = F@_4, pub_key = F@_5, token = F@_6, network_code = F@_7, hostname = F@_8}. d_field_sdl_register_super_version(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> d_field_sdl_register_super_version(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); @@ -1382,9 +1382,9 @@ d_field_sdl_register_super_network_code(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@ {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, dfp_read_field_def_sdl_register_super(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, NewFValue, F@_8, TrUserData). -d_field_sdl_register_super_host_name(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> - d_field_sdl_register_super_host_name(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); -d_field_sdl_register_super_host_name(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, _, TrUserData) -> +d_field_sdl_register_super_hostname(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) when N < 57 -> + d_field_sdl_register_super_hostname(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData); +d_field_sdl_register_super_hostname(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, _, TrUserData) -> {NewFValue, RestF} = begin Len = X bsl N + Acc, <> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end, dfp_read_field_def_sdl_register_super(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, NewFValue, TrUserData). @@ -2613,8 +2613,8 @@ merge_msg_sdl_empty(_Prev, New, _TrUserData) -> New. -compile({nowarn_unused_function,merge_msg_sdl_register_super/3}). merge_msg_sdl_register_super(#sdl_register_super{version = PFversion, installed_channel = PFinstalled_channel, client_id = PFclient_id, dev_addr = PFdev_addr, pub_key = PFpub_key, token = PFtoken, network_code = PFnetwork_code, - host_name = PFhost_name}, - #sdl_register_super{version = NFversion, installed_channel = NFinstalled_channel, client_id = NFclient_id, dev_addr = NFdev_addr, pub_key = NFpub_key, token = NFtoken, network_code = NFnetwork_code, host_name = NFhost_name}, TrUserData) -> + hostname = PFhostname}, + #sdl_register_super{version = NFversion, installed_channel = NFinstalled_channel, client_id = NFclient_id, dev_addr = NFdev_addr, pub_key = NFpub_key, token = NFtoken, network_code = NFnetwork_code, hostname = NFhostname}, TrUserData) -> #sdl_register_super{version = if NFversion =:= undefined -> PFversion; true -> NFversion @@ -2644,9 +2644,9 @@ merge_msg_sdl_register_super(#sdl_register_super{version = PFversion, installed_ if NFnetwork_code =:= undefined -> PFnetwork_code; true -> NFnetwork_code end, - host_name = - if NFhost_name =:= undefined -> PFhost_name; - true -> NFhost_name + hostname = + if NFhostname =:= undefined -> PFhostname; + true -> NFhostname end}. -compile({nowarn_unused_function,merge_msg_sdl_register_super_ack/3}). @@ -3018,7 +3018,7 @@ v_msg_sdl_empty(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_empty} -compile({nowarn_unused_function,v_msg_sdl_register_super/3}). -dialyzer({nowarn_function,v_msg_sdl_register_super/3}). -v_msg_sdl_register_super(#sdl_register_super{version = F1, installed_channel = F2, client_id = F3, dev_addr = F4, pub_key = F5, token = F6, network_code = F7, host_name = F8}, Path, TrUserData) -> +v_msg_sdl_register_super(#sdl_register_super{version = F1, installed_channel = F2, client_id = F3, dev_addr = F4, pub_key = F5, token = F6, network_code = F7, hostname = F8}, Path, TrUserData) -> if F1 == undefined -> ok; true -> v_type_uint32(F1, [version | Path], TrUserData) end, @@ -3041,7 +3041,7 @@ v_msg_sdl_register_super(#sdl_register_super{version = F1, installed_channel = F true -> v_type_string(F7, [network_code | Path], TrUserData) end, if F8 == undefined -> ok; - true -> v_type_string(F8, [host_name | Path], TrUserData) + true -> v_type_string(F8, [hostname | Path], TrUserData) end, ok; v_msg_sdl_register_super(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_register_super}, X, Path). @@ -3390,7 +3390,7 @@ get_msg_defs() -> #field{name = pub_key, fnum = 5, rnum = 6, type = string, occurrence = defaulty, opts = []}, #field{name = token, fnum = 6, rnum = 7, type = string, occurrence = defaulty, opts = []}, #field{name = network_code, fnum = 7, rnum = 8, type = string, occurrence = defaulty, opts = []}, - #field{name = host_name, fnum = 8, rnum = 9, type = string, occurrence = defaulty, opts = []}]}, + #field{name = hostname, fnum = 8, rnum = 9, type = string, occurrence = defaulty, opts = []}]}, {{msg, sdl_register_super_ack}, [#field{name = dev_addr, fnum = 1, rnum = 2, type = {msg, sdl_dev_addr}, occurrence = defaulty, opts = []}, #field{name = aes_key, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, @@ -3535,7 +3535,7 @@ find_msg_def(sdl_register_super) -> #field{name = pub_key, fnum = 5, rnum = 6, type = string, occurrence = defaulty, opts = []}, #field{name = token, fnum = 6, rnum = 7, type = string, occurrence = defaulty, opts = []}, #field{name = network_code, fnum = 7, rnum = 8, type = string, occurrence = defaulty, opts = []}, - #field{name = host_name, fnum = 8, rnum = 9, type = string, occurrence = defaulty, opts = []}]; + #field{name = hostname, fnum = 8, rnum = 9, type = string, occurrence = defaulty, opts = []}]; find_msg_def(sdl_register_super_ack) -> [#field{name = dev_addr, fnum = 1, rnum = 2, type = {msg, sdl_dev_addr}, occurrence = defaulty, opts = []}, #field{name = aes_key, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []}, diff --git a/message.proto b/message.proto index 1ba9e75..96eb93c 100644 --- a/message.proto +++ b/message.proto @@ -35,7 +35,7 @@ message SDLRegisterSuper { string pub_key = 5; string token = 6; string network_code = 7; - string host_name = 8; + string hostname = 8; } message SDLRegisterSuperAck {