merge network code
This commit is contained in:
parent
d5b49d2b55
commit
217674b3dd
26
API.md
26
API.md
@ -45,6 +45,7 @@ return:
|
||||
"id": 1,
|
||||
"name": "网络1",
|
||||
"ipaddr": "192.168.0.1/24",
|
||||
"domain": "punchnet.cn",
|
||||
"owner_id": 1234,
|
||||
"disabled_clients": ["client_id_xyz", "client_id_xyz1"]
|
||||
}
|
||||
@ -78,6 +79,31 @@ return:
|
||||
code = 2, Client Connection Disable
|
||||
```
|
||||
|
||||
### 3.网络校验
|
||||
```text
|
||||
url: /api/check_network
|
||||
method: post
|
||||
params:
|
||||
client_id: string
|
||||
code: string,
|
||||
version: int // 当前客户端版本
|
||||
return:
|
||||
|
||||
{"result":
|
||||
{
|
||||
"network_id": 8,
|
||||
"upgrade_type": 0, // 升级类型,0: 不升级,1: 普通升级,2: 强制升级
|
||||
"upgrade_prompt": "升级提升语"
|
||||
"upgrade_address": "升级提升语"
|
||||
}
|
||||
}
|
||||
|
||||
{"error": {"code": 1, "message": "错误描述"}}
|
||||
code = 1, Token does not exists
|
||||
code = 2, Client Connection Disable
|
||||
```
|
||||
|
||||
|
||||
### 4.设置节点的状态
|
||||
```text
|
||||
url: /api/set_node_status
|
||||
|
||||
24
apps/sdlan/include/dns_proxy.hrl
Normal file
24
apps/sdlan/include/dns_proxy.hrl
Normal file
@ -0,0 +1,24 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author anlicheng
|
||||
%%% @copyright (C) 2025, <COMPANY>
|
||||
%%% @doc
|
||||
%%%
|
||||
%%% @end
|
||||
%%% Created : 04. 12月 2025 11:41
|
||||
%%%-------------------------------------------------------------------
|
||||
-author("anlicheng").
|
||||
|
||||
-define(PENDING_TAB, ets_dns_pending_queries).
|
||||
-define(PENDING_INDEX_TAB, ets_dns_expire_index).
|
||||
|
||||
-record(dns_cache, {
|
||||
%% {Qname, QType, QClass}
|
||||
key,
|
||||
answers = [],
|
||||
authority = [],
|
||||
additional = [],
|
||||
rc :: integer(),
|
||||
flags = #{},
|
||||
% unix time
|
||||
expire_at :: integer()
|
||||
}).
|
||||
@ -31,7 +31,8 @@
|
||||
{network_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits
|
||||
mac = <<>> :: iodata() | undefined, % = 2, optional
|
||||
net_addr = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits
|
||||
net_bit_len = 0 :: non_neg_integer() | undefined % = 4, optional, 32 bits
|
||||
net_bit_len = 0 :: non_neg_integer() | undefined, % = 4, optional, 32 bits
|
||||
network_domain = <<>> :: unicode:chardata() | undefined % = 5, optional
|
||||
}).
|
||||
-endif.
|
||||
|
||||
@ -50,7 +51,9 @@
|
||||
client_id = <<>> :: unicode:chardata() | undefined, % = 3, optional
|
||||
dev_addr = undefined :: sdlan_pb:sdl_dev_addr() | undefined, % = 4, optional
|
||||
pub_key = <<>> :: unicode:chardata() | undefined, % = 5, optional
|
||||
token = <<>> :: unicode:chardata() | undefined % = 6, optional
|
||||
token = <<>> :: unicode:chardata() | undefined, % = 6, optional
|
||||
network_code = <<>> :: unicode:chardata() | undefined, % = 7, optional
|
||||
hostname = <<>> :: unicode:chardata() | undefined % = 8, optional
|
||||
}).
|
||||
-endif.
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
client_id :: binary(),
|
||||
mac :: binary(),
|
||||
ip :: integer(),
|
||||
host_name :: binary(),
|
||||
%% 当前状态
|
||||
status = normal :: normal | disabled
|
||||
}).
|
||||
59
apps/sdlan/src/dns_proxy/dns_cache.erl
Normal file
59
apps/sdlan/src/dns_proxy/dns_cache.erl
Normal file
@ -0,0 +1,59 @@
|
||||
-module(dns_cache).
|
||||
-include_lib("dns_proxy.hrl").
|
||||
-include_lib("dns_erlang/include/dns.hrl").
|
||||
-include_lib("dns_erlang/include/dns_records.hrl").
|
||||
-include_lib("dns_erlang/include/dns_terms.hrl").
|
||||
|
||||
-export([init/0, lookup/1, insert/2]).
|
||||
|
||||
-define(TABLE, dns_cache).
|
||||
|
||||
init() ->
|
||||
ets:new(?TABLE, [named_table, set, public, {keypos, 2}, {read_concurrency, true}]).
|
||||
|
||||
lookup(#dns_query{name = Qname, type = QType, class = QClass}) ->
|
||||
Key = {Qname, QType, QClass},
|
||||
case ets:lookup(?TABLE, Key) of
|
||||
[Cache = #dns_cache{expire_at = ExpireAt}] ->
|
||||
Now = os:system_time(second),
|
||||
case ExpireAt > Now of
|
||||
true ->
|
||||
{hit, Cache};
|
||||
false ->
|
||||
true = ets:delete(?TABLE, Key),
|
||||
miss
|
||||
end;
|
||||
[] ->
|
||||
miss
|
||||
end.
|
||||
|
||||
insert(#dns_query{name = Qname, type = QType, class = QClass},
|
||||
#dns_message{answers = Answers, authority = Authority, additional = Additional, rc = RCode, aa = AA}) ->
|
||||
TTLs = lists:foldl(fun(Term, Acc) ->
|
||||
case Term of
|
||||
#dns_rr{ttl = TTL} ->
|
||||
[TTL|Acc];
|
||||
_ ->
|
||||
Acc
|
||||
end
|
||||
end, [], Answers ++ Authority ++ Additional),
|
||||
case length(TTLs) > 0 of
|
||||
true ->
|
||||
TTL = lists:min(TTLs),
|
||||
ExpireAt = os:system_time(second) + TTL,
|
||||
lager:debug("min ttl is: ~p, expire_at: ~p", [TTL, ExpireAt]),
|
||||
Key = {Qname, QType, QClass},
|
||||
Cache = #dns_cache{
|
||||
key = Key,
|
||||
answers = Answers,
|
||||
authority = Authority,
|
||||
additional = Additional,
|
||||
rc = RCode,
|
||||
flags = #{aa => AA},
|
||||
% unix time
|
||||
expire_at = ExpireAt
|
||||
},
|
||||
true = ets:insert(?TABLE, Cache);
|
||||
false ->
|
||||
ok
|
||||
end.
|
||||
263
apps/sdlan/src/dns_proxy/dns_handler.erl
Normal file
263
apps/sdlan/src/dns_proxy/dns_handler.erl
Normal file
@ -0,0 +1,263 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author anlicheng
|
||||
%%% @copyright (C) 2025, <COMPANY>
|
||||
%%% @doc
|
||||
%%%
|
||||
%%% @end
|
||||
%%% Created : 03. 12月 2025 23:00
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(dns_handler).
|
||||
-author("anlicheng").
|
||||
|
||||
-behaviour(gen_server).
|
||||
|
||||
-include_lib("dns_erlang/include/dns.hrl").
|
||||
-include_lib("pkt/include/pkt.hrl").
|
||||
-include("dns_proxy.hrl").
|
||||
|
||||
%% API
|
||||
-export([start_link/0]).
|
||||
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
|
||||
-export([handle_ip_packet/5]).
|
||||
|
||||
-define(SERVER, ?MODULE).
|
||||
-define(RESOLVER_POOL, dns_resolver_pool).
|
||||
|
||||
%% 协议部分
|
||||
-define(TCP_PROTOCOL, 6).
|
||||
-define(UDP_PROTOCOL, 17).
|
||||
|
||||
-record(state, {}).
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
|
||||
start_link() ->
|
||||
gen_server:start_link(?MODULE, [], []).
|
||||
|
||||
handle_ip_packet(Pid, Sock, SrcIp, SrcPort, Packet) when is_pid(Pid) ->
|
||||
gen_server:cast(Pid, {handle_ip_packet, Sock, SrcIp, SrcPort, Packet}).
|
||||
|
||||
%%%===================================================================
|
||||
%%% gen_server callbacks
|
||||
%%%===================================================================
|
||||
|
||||
%% @private
|
||||
%% @doc Initializes the server
|
||||
-spec(init(Args :: term()) ->
|
||||
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term()} | ignore).
|
||||
init([]) ->
|
||||
{ok, #state{}}.
|
||||
|
||||
%% @private
|
||||
%% @doc Handling call messages
|
||||
-spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()},
|
||||
State :: #state{}) ->
|
||||
{reply, Reply :: term(), NewState :: #state{}} |
|
||||
{reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} |
|
||||
{noreply, NewState :: #state{}} |
|
||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term(), Reply :: term(), NewState :: #state{}} |
|
||||
{stop, Reason :: term(), NewState :: #state{}}).
|
||||
handle_call(_Request, _From, State = #state{}) ->
|
||||
{reply, ok, State}.
|
||||
|
||||
%% @private
|
||||
%% @doc Handling cast messages
|
||||
-spec(handle_cast(Request :: term(), State :: #state{}) ->
|
||||
{noreply, NewState :: #state{}} |
|
||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term(), NewState :: #state{}}).
|
||||
handle_cast({handle_ip_packet, Sock, SrcIp, SrcPort, IpPacket}, State) ->
|
||||
{#ipv4{saddr = ReqSAddr, daddr = ReqDAddr, p = Protocol}, ReqIpPayload} = pkt:ipv4(IpPacket),
|
||||
case Protocol =:= ?UDP_PROTOCOL of
|
||||
true ->
|
||||
{#udp{sport = ReqSPort, dport = ReqDPort}, UdpPayload} = pkt:udp(ReqIpPayload),
|
||||
case resolver(UdpPayload) of
|
||||
{ok, DnsResp} ->
|
||||
RespIpPacket = build_ip_packet(ReqDAddr, ReqSAddr, ReqDPort, ReqSPort, DnsResp),
|
||||
gen_udp:send(Sock, SrcIp, SrcPort, RespIpPacket);
|
||||
{error, Reason} ->
|
||||
lager:notice("[dns_handler] resolver get error: ~p", [Reason])
|
||||
end;
|
||||
false ->
|
||||
lager:notice("[dns_handler] resolver invalid protocol: ~p", [Protocol])
|
||||
end,
|
||||
{stop, normal, State}.
|
||||
|
||||
%% @private
|
||||
%% @doc Handling all non call/cast messages
|
||||
-spec(handle_info(Info :: timeout() | term(), State :: #state{}) ->
|
||||
{noreply, NewState :: #state{}} |
|
||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term(), NewState :: #state{}}).
|
||||
handle_info(_Info, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
%% @private
|
||||
%% @doc This function is called by a gen_server when it is about to
|
||||
%% terminate. It should be the opposite of Module:init/1 and do any
|
||||
%% necessary cleaning up. When it returns, the gen_server terminates
|
||||
%% with Reason. The return value is ignored.
|
||||
-spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()),
|
||||
State :: #state{}) -> term()).
|
||||
terminate(_Reason, _State = #state{}) ->
|
||||
ok.
|
||||
|
||||
%% @private
|
||||
%% @doc Convert process state when code is changed
|
||||
-spec(code_change(OldVsn :: term() | {down, term()}, State :: #state{},
|
||||
Extra :: term()) ->
|
||||
{ok, NewState :: #state{}} | {error, Reason :: term()}).
|
||||
code_change(_OldVsn, State = #state{}, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
%%%===================================================================
|
||||
%%% 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 sdlan_hostname_regedit:lookup(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 = []
|
||||
},
|
||||
lager:debug("[dns_handler] punchnet inbuilt qnanme: ~p, ip: ~p", [QName, Ip]),
|
||||
{ok, dns:encode_message(RespMsg)};
|
||||
error ->
|
||||
%% 是否命中内部的域名后缀
|
||||
EmptyDnsResp = dns:encode_message(build_nxdomain_response(QueryMsg)),
|
||||
case sdlan_domain_regedit:maybe_domain(QName) of
|
||||
true ->
|
||||
lager:debug("[dns_handler] punchnet inbuilt qnanme: ~p, nxdomain", [QName]),
|
||||
{ok, EmptyDnsResp};
|
||||
false ->
|
||||
case dns_cache:lookup(Question) of
|
||||
{hit, Cache} ->
|
||||
lager:debug("[dns_handler] qname: ~p, hit cache answers: ~p", [QName, Cache#dns_cache.answers]),
|
||||
RespMsg = build_response(QueryMsg, Cache),
|
||||
{ok, dns:encode_message(RespMsg)};
|
||||
miss ->
|
||||
Ref = make_ref(),
|
||||
forward_to_upstream(Ref, Packet, QueryMsg),
|
||||
lager:debug("[dns_handler] cache is miss, forward_to_upstream"),
|
||||
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
|
||||
end
|
||||
end
|
||||
end;
|
||||
resolver0(_, 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().
|
||||
forward_to_upstream(Ref, Request, QueryMsg) ->
|
||||
ReceiverPid = self(),
|
||||
poolboy:transaction(?RESOLVER_POOL, fun(Pid) -> dns_resolver:forward(Pid, ReceiverPid, Ref, Request, QueryMsg) end).
|
||||
|
||||
-spec build_response(QueryMsg :: #dns_message{}, Dns_cache :: #dns_cache{}) -> RespMsg :: #dns_message{}.
|
||||
build_response(QueryMsg, #dns_cache{expire_at = ExpireAt, answers = Answers, authority = Authority, additional = Additional, rc = RCode, flags = #{aa := AA}}) ->
|
||||
Now = os:system_time(second),
|
||||
RemainingTTL = ExpireAt - Now,
|
||||
|
||||
Answers2 = [adjust_ttl(RR, RemainingTTL) || RR <- Answers],
|
||||
Authority2 = [adjust_ttl(RR, RemainingTTL) || RR <- Authority],
|
||||
Additional2 = [adjust_ttl(RR, RemainingTTL) || RR <- Additional],
|
||||
|
||||
QueryMsg#dns_message{
|
||||
qr = true,
|
||||
ra = true,
|
||||
aa = AA,
|
||||
rc = RCode,
|
||||
anc = length(Answers2),
|
||||
auc = length(Authority2),
|
||||
adc = length(Additional2),
|
||||
answers = Answers2,
|
||||
authority = Authority2,
|
||||
additional = Additional2
|
||||
}.
|
||||
|
||||
-spec adjust_ttl(RR :: any(), RemainingTTL :: integer()) -> any().
|
||||
adjust_ttl(RR = #dns_rr{}, RemainingTTL) ->
|
||||
RR#dns_rr{ttl = max(0, 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),
|
||||
RespUdpHeader = pkt:udp(#udp{
|
||||
sport = SPort,
|
||||
dport = DPort,
|
||||
ulen = ULen,
|
||||
sum = dns_utils:udp_checksum(SAddr, DAddr, SPort, DPort, UdpPayload)
|
||||
}),
|
||||
IpPayload = <<RespUdpHeader/binary, UdpPayload/binary>>,
|
||||
|
||||
IpPacket0 = #ipv4{
|
||||
len = 20 + ULen,
|
||||
ttl = 64,
|
||||
off = 0,
|
||||
mf = 0,
|
||||
sum = 0,
|
||||
p = ?UDP_PROTOCOL,
|
||||
saddr = SAddr,
|
||||
daddr = DAddr,
|
||||
opt = <<>>
|
||||
},
|
||||
IpCheckSum = dns_utils:ip_checksum(IpPacket0),
|
||||
IpHeader = pkt:ipv4(IpPacket0#ipv4{sum = IpCheckSum}),
|
||||
|
||||
<<IpHeader/binary, IpPayload/binary>>.
|
||||
66
apps/sdlan/src/dns_proxy/dns_handler_sup.erl
Normal file
66
apps/sdlan/src/dns_proxy/dns_handler_sup.erl
Normal file
@ -0,0 +1,66 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author anlicheng
|
||||
%%% @copyright (C) 2025, <COMPANY>
|
||||
%%% @doc
|
||||
%%%
|
||||
%%% @end
|
||||
%%% Created : 03. 12月 2025 17:29
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(dns_handler_sup).
|
||||
-author("anlicheng").
|
||||
|
||||
-behaviour(supervisor).
|
||||
|
||||
%% API
|
||||
-export([start_link/0]).
|
||||
|
||||
%% Supervisor callbacks
|
||||
-export([init/1]).
|
||||
-export([start_handler/0]).
|
||||
|
||||
-define(SERVER, ?MODULE).
|
||||
|
||||
%%%===================================================================
|
||||
%%% API functions
|
||||
%%%===================================================================
|
||||
|
||||
%% @doc Starts the supervisor
|
||||
-spec(start_link() -> {ok, Pid :: pid()} | ignore | {error, Reason :: term()}).
|
||||
start_link() ->
|
||||
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
|
||||
|
||||
%%%===================================================================
|
||||
%%% Supervisor callbacks
|
||||
%%%===================================================================
|
||||
|
||||
%% @private
|
||||
%% @doc Whenever a supervisor is started using supervisor:start_link/[2,3],
|
||||
%% this function is called by the new process to find out about
|
||||
%% restart strategy, maximum restart frequency and child
|
||||
%% specifications.
|
||||
init([]) ->
|
||||
SupFlags = #{strategy => simple_one_for_one, intensity => 0, period => 1},
|
||||
Spec = #{
|
||||
id => dns_handler,
|
||||
start => {'dns_handler', start_link, []},
|
||||
restart => temporary,
|
||||
shutdown => 2000,
|
||||
type => worker,
|
||||
modules => ['dns_handler']
|
||||
},
|
||||
|
||||
{ok, {SupFlags, [Spec]}}.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
|
||||
start_handler() ->
|
||||
case supervisor:start_child(?MODULE, []) of
|
||||
{ok, Pid} ->
|
||||
{ok, Pid};
|
||||
{error, {already_started, Pid}} ->
|
||||
{ok, Pid};
|
||||
StartError ->
|
||||
StartError
|
||||
end.
|
||||
64
apps/sdlan/src/dns_proxy/dns_pending_wheel.erl
Normal file
64
apps/sdlan/src/dns_proxy/dns_pending_wheel.erl
Normal file
@ -0,0 +1,64 @@
|
||||
-module(dns_pending_wheel).
|
||||
|
||||
-export([start/0, insert/2, lookup/1, delete/1]).
|
||||
|
||||
-define(TTL, 5).
|
||||
-define(TICK_MS, 1000).
|
||||
-define(WHEEL_SIZE, (?TTL + 1)).
|
||||
|
||||
%%% =====================================================
|
||||
%%% Public API
|
||||
%%% =====================================================
|
||||
|
||||
start() ->
|
||||
ets:new(dns_pending_data, [ordered_set, public, named_table, {read_concurrency, true}, {write_concurrency, true}]),
|
||||
ets:new(dns_pending_wheel, [bag, public, named_table, {read_concurrency, true}, {write_concurrency, true}]),
|
||||
start_scanner().
|
||||
|
||||
-spec insert(Key :: any(), Val :: any()) -> ok.
|
||||
insert(Key, Val) ->
|
||||
Tick = now_tick(),
|
||||
Slot = Tick rem ?WHEEL_SIZE,
|
||||
ets:insert(dns_pending_data, {Key, {Val, Tick}}),
|
||||
ets:insert(dns_pending_wheel, {Slot, {Key, Tick}}),
|
||||
ok.
|
||||
|
||||
-spec lookup(Key :: any()) -> [term()].
|
||||
lookup(Key) ->
|
||||
ets:lookup(dns_pending_data, Key).
|
||||
|
||||
-spec delete(Key :: any()) -> ok.
|
||||
delete(Key) ->
|
||||
ets:delete(dns_pending_data, Key),
|
||||
ok.
|
||||
|
||||
%%% =====================================================
|
||||
%%% Internal
|
||||
%%% =====================================================
|
||||
|
||||
start_scanner() ->
|
||||
{ok, spawn_link(fun tick_loop/0)}.
|
||||
|
||||
%% 当前插入数据是在Tick, 而清理是从 Tick + 1 开始的,没有问题
|
||||
tick_loop() ->
|
||||
Tick = now_tick(),
|
||||
CleanSlot = (Tick + 1) rem ?WHEEL_SIZE,
|
||||
spawn(fun() -> clean_slot(CleanSlot) end),
|
||||
timer:sleep(?TICK_MS),
|
||||
tick_loop().
|
||||
|
||||
clean_slot(Slot) ->
|
||||
Items = ets:lookup(dns_pending_wheel, Slot),
|
||||
true = ets:delete(dns_pending_wheel, Slot),
|
||||
lists:foreach(fun({_, {Key, InsertTick}}) ->
|
||||
case ets:lookup(dns_pending_data, Key) of
|
||||
[{Key, {_Val, InsertTick}}] ->
|
||||
ets:delete(dns_pending_data, Key);
|
||||
_ ->
|
||||
ok
|
||||
end
|
||||
end, Items).
|
||||
|
||||
-spec now_tick() -> integer().
|
||||
now_tick() ->
|
||||
erlang:system_time(second).
|
||||
50
apps/sdlan/src/dns_proxy/dns_proxy_sup.erl
Normal file
50
apps/sdlan/src/dns_proxy/dns_proxy_sup.erl
Normal file
@ -0,0 +1,50 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%% @doc dns_proxy top level supervisor.
|
||||
%% @end
|
||||
%%%-------------------------------------------------------------------
|
||||
|
||||
-module(dns_proxy_sup).
|
||||
|
||||
-behaviour(supervisor).
|
||||
|
||||
-export([start_link/0]).
|
||||
-export([init/1]).
|
||||
|
||||
-define(SERVER, ?MODULE).
|
||||
|
||||
start_link() ->
|
||||
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
|
||||
|
||||
%% sup_flags() = #{strategy => strategy(), % optional
|
||||
%% intensity => non_neg_integer(), % optional
|
||||
%% period => pos_integer()} % optional
|
||||
%% child_spec() = #{id => child_id(), % mandatory
|
||||
%% start => mfargs(), % mandatory
|
||||
%% restart => restart(), % optional
|
||||
%% shutdown => shutdown(), % optional
|
||||
%% type => worker(), % optional
|
||||
%% modules => modules()} % optional
|
||||
init([]) ->
|
||||
SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600},
|
||||
|
||||
Port = 15353,
|
||||
Specs = [
|
||||
#{
|
||||
id => dns_handler_sup,
|
||||
start => {dns_handler_sup, start_link, []},
|
||||
restart => permanent,
|
||||
shutdown => 2000,
|
||||
type => supervisor,
|
||||
modules => ['dns_handler_sup']
|
||||
},
|
||||
#{
|
||||
id => dns_server,
|
||||
start => {dns_server, start_link, [Port]},
|
||||
restart => permanent,
|
||||
shutdown => 2000,
|
||||
type => worker,
|
||||
modules => ['dns_server']
|
||||
}
|
||||
],
|
||||
|
||||
{ok, {SupFlags, Specs}}.
|
||||
141
apps/sdlan/src/dns_proxy/dns_resolver.erl
Normal file
141
apps/sdlan/src/dns_proxy/dns_resolver.erl
Normal file
@ -0,0 +1,141 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author anlicheng
|
||||
%%% @copyright (C) 2025, <COMPANY>
|
||||
%%% @doc
|
||||
%%%
|
||||
%%% @end
|
||||
%%% Created : 03. 12月 2025 18:26
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(dns_resolver).
|
||||
-author("anlicheng").
|
||||
-include_lib("dns_erlang/include/dns.hrl").
|
||||
|
||||
-behaviour(gen_server).
|
||||
|
||||
%% API
|
||||
-export([start_link/1]).
|
||||
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
|
||||
|
||||
-export([forward/5]).
|
||||
|
||||
-define(SERVER, ?MODULE).
|
||||
|
||||
-record(state, {
|
||||
socket,
|
||||
idx :: integer(),
|
||||
dns_servers = []
|
||||
}).
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
|
||||
forward(Pid, ReceiverPid, Ref, Request, QueryMsg) ->
|
||||
gen_server:cast(Pid, {forward, ReceiverPid, Ref, Request, QueryMsg}).
|
||||
|
||||
%% @doc Spawns the server and registers the local name (unique)
|
||||
-spec(start_link(Args :: list()) ->
|
||||
{ok, Pid :: pid()} | ignore | {error, Reason :: term()}).
|
||||
start_link(Args) when is_list(Args) ->
|
||||
gen_server:start_link(?MODULE, [], []).
|
||||
|
||||
%%%===================================================================
|
||||
%%% gen_server callbacks
|
||||
%%%===================================================================
|
||||
|
||||
%% @private
|
||||
%% @doc Initializes the server
|
||||
-spec(init(Args :: term()) ->
|
||||
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term()} | ignore).
|
||||
init([]) ->
|
||||
{ok, DnsServers} = application:get_env(sdlan, public_dns_servers),
|
||||
{ok, Sock} = gen_udp:open(0, [binary, {active, true}]),
|
||||
Idx = erlang:unique_integer([monotonic, positive]),
|
||||
{ok, #state{socket = Sock, idx = Idx, dns_servers = DnsServers}}.
|
||||
|
||||
%% @private
|
||||
%% @doc Handling call messages
|
||||
-spec(handle_call(Request :: term(), From :: {pid(), Tag :: term()},
|
||||
State :: #state{}) ->
|
||||
{reply, Reply :: term(), NewState :: #state{}} |
|
||||
{reply, Reply :: term(), NewState :: #state{}, timeout() | hibernate} |
|
||||
{noreply, NewState :: #state{}} |
|
||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term(), Reply :: term(), NewState :: #state{}} |
|
||||
{stop, Reason :: term(), NewState :: #state{}}).
|
||||
handle_call(_Request, _From, State = #state{}) ->
|
||||
{reply, ok, State}.
|
||||
|
||||
%% @private
|
||||
%% @doc Handling cast messages
|
||||
-spec(handle_cast(Request :: term(), State :: #state{}) ->
|
||||
{noreply, NewState :: #state{}} |
|
||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term(), NewState :: #state{}}).
|
||||
handle_cast({forward, ReceiverPid, Ref, Request, #dns_message{id = TxId, questions = [#dns_query{name = QName, type = QType, class = QClass}|_]}},
|
||||
State = #state{socket = Socket, idx = Idx, dns_servers = DnsServers}) ->
|
||||
|
||||
lists:foreach(fun({DnsIp, DnsPort}) ->
|
||||
ok = gen_udp:send(Socket, DnsIp, DnsPort, Request),
|
||||
Key = {Idx, TxId, DnsIp, DnsPort, QName, QType, QClass},
|
||||
lager:debug("[dns_resolver] key: ~p, send to: ~p, packet: ~p", [Key, {DnsIp, DnsPort}, Request]),
|
||||
dns_pending_wheel:insert(Key, {Ref, ReceiverPid})
|
||||
end, DnsServers),
|
||||
|
||||
{noreply, State}.
|
||||
|
||||
%% @private
|
||||
%% @doc Handling all non call/cast messages
|
||||
-spec(handle_info(Info :: timeout() | term(), State :: #state{}) ->
|
||||
{noreply, NewState :: #state{}} |
|
||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term(), NewState :: #state{}}).
|
||||
handle_info({udp, Socket, TargetIp, TargetPort, Resp}, State = #state{socket = Socket, idx = Idx}) ->
|
||||
try dns:decode_message(Resp) of
|
||||
#dns_message{id = TxId, questions = [#dns_query{name = QName, type = QType, class = QClass}|_]} ->
|
||||
Key = {Idx, TxId, TargetIp, TargetPort, QName, QType, QClass},
|
||||
Records = dns_pending_wheel:lookup(Key),
|
||||
dns_pending_wheel:delete(Key),
|
||||
resolver_reply(Records, Resp);
|
||||
_ ->
|
||||
ok
|
||||
catch error:_ ->
|
||||
ok
|
||||
end,
|
||||
{noreply, State}.
|
||||
|
||||
%% @private
|
||||
%% @doc This function is called by a gen_server when it is about to
|
||||
%% terminate. It should be the opposite of Module:init/1 and do any
|
||||
%% necessary cleaning up. When it returns, the gen_server terminates
|
||||
%% with Reason. The return value is ignored.
|
||||
-spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()),
|
||||
State :: #state{}) -> term()).
|
||||
terminate(_Reason, _State = #state{}) ->
|
||||
ok.
|
||||
|
||||
%% @private
|
||||
%% @doc Convert process state when code is changed
|
||||
-spec(code_change(OldVsn :: term() | {down, term()}, State :: #state{},
|
||||
Extra :: term()) ->
|
||||
{ok, NewState :: #state{}} | {error, Reason :: term()}).
|
||||
code_change(_OldVsn, State = #state{}, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
|
||||
-spec resolver_reply(list(), Resp :: binary()) -> no_return().
|
||||
resolver_reply(Records, Resp) when is_binary(Resp) ->
|
||||
lists:foreach(fun({_, {Ref, ReceiverPid}}) ->
|
||||
case is_process_alive(ReceiverPid) of
|
||||
true ->
|
||||
ReceiverPid ! {dns_resolver_reply, Ref, Resp};
|
||||
false ->
|
||||
ok
|
||||
end
|
||||
end, Records).
|
||||
24
apps/sdlan/src/dns_proxy/dns_server.erl
Normal file
24
apps/sdlan/src/dns_proxy/dns_server.erl
Normal file
@ -0,0 +1,24 @@
|
||||
-module(dns_server).
|
||||
-export([start_link/1, init/1]).
|
||||
|
||||
start_link(Port) when is_integer(Port) ->
|
||||
{ok, spawn_link(?MODULE, init, [Port])}.
|
||||
|
||||
init(Port) ->
|
||||
dns_cache:init(),
|
||||
{ok, Sock} = gen_udp:open(Port, [binary, {active, true}]),
|
||||
lager:debug("[dns_server] DNS Forwarder started on UDP port ~p~n", [Port]),
|
||||
loop(Sock).
|
||||
|
||||
loop(Sock) ->
|
||||
receive
|
||||
{udp, Sock, Ip, Port, Packet} ->
|
||||
lager:debug("[dns_server] ip: ~p, get a packet: ~p", [{Ip, Port}, Packet]),
|
||||
case dns_handler_sup:start_handler() of
|
||||
{ok, HandlerPid} ->
|
||||
dns_handler:handle_ip_packet(HandlerPid, Sock, Ip, Port, Packet);
|
||||
Error ->
|
||||
lager:debug("[dns_server] start handler get error: ~p", [Error])
|
||||
end,
|
||||
loop(Sock)
|
||||
end.
|
||||
131
apps/sdlan/src/dns_proxy/dns_utils.erl
Normal file
131
apps/sdlan/src/dns_proxy/dns_utils.erl
Normal file
@ -0,0 +1,131 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author anlicheng
|
||||
%%% @copyright (C) 2025, <COMPANY>
|
||||
%%% @doc
|
||||
%%%
|
||||
%%% @end
|
||||
%%% Created : 05. 12月 2025 18:06
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(dns_utils).
|
||||
-author("anlicheng").
|
||||
|
||||
-include_lib("pkt/include/pkt.hrl").
|
||||
|
||||
%% API
|
||||
-export([ends_with/2, parse_address/1, checksum/1, udp_checksum/5, ip_checksum/1]).
|
||||
-export([test/0]).
|
||||
|
||||
-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)).
|
||||
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% @doc
|
||||
%% Calculate 16-bit one's-complement checksum.
|
||||
%%
|
||||
%% Input:
|
||||
%% Bin :: binary()
|
||||
%%
|
||||
%% Output:
|
||||
%% Checksum :: 0..16#FFFF
|
||||
%%
|
||||
%% Usage:
|
||||
%% Checksum = checksum(Bin).
|
||||
%%
|
||||
%% Notes:
|
||||
%% - Bin is treated as big-endian 16-bit words
|
||||
%% - If Bin length is odd, a zero byte is padded
|
||||
%%--------------------------------------------------------------------
|
||||
-spec checksum(binary()) -> non_neg_integer().
|
||||
checksum(Bin) when is_binary(Bin) ->
|
||||
Sum = checksum_sum(Bin, 0),
|
||||
%% fold carry bits
|
||||
Folded = fold16(Sum),
|
||||
%% one's complement
|
||||
(bnot Folded) band 16#FFFF.
|
||||
checksum_sum(<<>>, Acc) ->
|
||||
Acc;
|
||||
checksum_sum(<<Word:16/big, Rest/binary>>, Acc) ->
|
||||
checksum_sum(Rest, Acc + Word);
|
||||
checksum_sum(<<Byte:8>>, Acc) ->
|
||||
%% odd length: pad low byte with zero
|
||||
checksum_sum(<<>>, Acc + (Byte bsl 8)).
|
||||
|
||||
fold16(S) when S > 16#FFFF ->
|
||||
fold16((S band 16#FFFF) + (S bsr 16));
|
||||
fold16(S) ->
|
||||
S.
|
||||
|
||||
-spec udp_checksum(SAddr :: inet:ip4_address(), DAddr :: inet:ip4_address(), SPort :: integer(), DPort :: integer(), UDPPayload :: binary()) -> non_neg_integer().
|
||||
udp_checksum({SA1, SA2, SA3, SA4}, {DA1, DA2, DA3, DA4}, SPort, DPort, UDPPayload) when is_integer(SPort), is_integer(DPort), is_binary(UDPPayload) ->
|
||||
ULen = 8 + byte_size(UDPPayload),
|
||||
PseudoHeader = <<SA1, SA2, SA3, SA4,
|
||||
DA1, DA2, DA3, DA4,
|
||||
0:8, 17:8,
|
||||
ULen:16>>,
|
||||
UDPHeader = <<SPort:16, DPort:16, ULen:16, 0:16>>,
|
||||
CheckSum = checksum(<<PseudoHeader/binary, UDPHeader/binary, UDPPayload/binary>>),
|
||||
case CheckSum of
|
||||
0 ->
|
||||
16#FFFF;
|
||||
_ ->
|
||||
CheckSum
|
||||
end.
|
||||
|
||||
-spec ip_checksum(Ipv4 :: #ipv4{}) -> non_neg_integer().
|
||||
ip_checksum(#ipv4{hl = HL, tos = ToS, len = Len,
|
||||
id = Id, df = DF, mf = MF,
|
||||
off = Off, ttl = TTL, p = P,
|
||||
saddr = {SA1, SA2, SA3, SA4},
|
||||
daddr = {DA1, DA2, DA3, DA4},
|
||||
opt = Opt}) ->
|
||||
|
||||
IPBinForChecksum =
|
||||
<<4:4, HL:4, %% Version=4 + IHL
|
||||
ToS:8, %% Type of Service
|
||||
Len:16/big, %% Total Length
|
||||
Id:16/big, %% Identification
|
||||
DF:1, MF:1, Off:14, %% Flags + Fragment offset
|
||||
TTL:8, %% TTL
|
||||
P:8, %% Protocol
|
||||
0:16, %% checksum field set to 0 for calculation
|
||||
SA1:8, SA2:8, SA3:8, SA4:8, %% Source IP
|
||||
DA1:8, DA2:8, DA3:8, DA4:8, %% Dest IP
|
||||
Opt/binary>>, %% Options (可选)
|
||||
CheckSum = checksum(IPBinForChecksum),
|
||||
case CheckSum of
|
||||
0 ->
|
||||
16#FFFF;
|
||||
_ ->
|
||||
CheckSum
|
||||
end.
|
||||
|
||||
test() ->
|
||||
%Bin = <<69,0,0,77,48,179,0,0,64,17,28,168,100,123,0,2,100,100,100,100,252,230,0,53,0,57,6,92,152,24,1,0,0,1,0,0,0,0,0,0,2,100,98,7,95,100,110,115,45,115,100,4,95,117,100,112,8,112,117,110,99,104,110,101,116,2,116,115,3,110,101,116,0,0,12,0,1>>,
|
||||
Bin = <<69,0,0,93,0,0,0,0,64,6,77,86,100,100,100,100,100,123,0,2,0,53,196,102,0,73,39,7,215,192,129,128,0,1,0,1,0,0,0,0,2,108,98,7,95,100,110,115,45,115,100,4,95,117,100,112,8,112,117,110,99,104,110,101,116,2,116,115,3,110,101,116,0,0,12,0,1,192,12,0,12,0,1,0,0,1,44,0,4,192,168,1,101>>,
|
||||
|
||||
{IPPacket = #ipv4{
|
||||
saddr = SAddr,
|
||||
daddr = DAddr,
|
||||
sum = IpSum
|
||||
}, UdpPacket} = pkt:ipv4(Bin),
|
||||
|
||||
{UDP = #udp{sport = SPort, dport = DPort, sum = CheckSum}, UDPPayload} = pkt:udp(UdpPacket),
|
||||
|
||||
X = udp_checksum(SAddr, DAddr, SPort, DPort, UDPPayload),
|
||||
|
||||
lager:debug("ip_sum: ~p, =: ~p, udp: ~p, checkSum: ~p, =: ~p", [IpSum, ip_checksum(IPPacket), UDP, CheckSum, X]),
|
||||
|
||||
dns:decode_message(UDPPayload).
|
||||
@ -45,8 +45,8 @@ handle_request("POST", "/node/move", _, #{<<"client_id">> := ClientId, <<"from_n
|
||||
case {sdlan_network:get_pid(FromNetworkId), sdlan_network:get_pid(ToNetworkId)} of
|
||||
{FromPid, ToPid} when is_pid(FromPid), is_pid(ToPid) ->
|
||||
case sdlan_network:dropout_client(FromPid, ClientId) of
|
||||
{ok, ChannelPid} ->
|
||||
Ref = sdlan_channel:move_network(ChannelPid, self(), ToPid),
|
||||
{ok, ChannelPid, HostName} ->
|
||||
Ref = sdlan_channel:move_network(ChannelPid, self(), ToPid, HostName),
|
||||
receive
|
||||
{command_reply, Ref, {error, Reason}} ->
|
||||
lager:warning("[node_handler] client_id: ~p, move network from: ~p, to: ~p, get error: ~p", [ClientId, FromPid, ToPid, Reason]),
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
%% API
|
||||
-export([create_table/1, get_table_name/1]).
|
||||
-export([get_clients/1, delete_clients/1, delete_client/2, disable_client/2, alloc_ip/5]).
|
||||
-export([get_clients/1, get_client/2, delete_clients/1, delete_client/2, disable_client/2, alloc_ip/6]).
|
||||
-export([debug/1]).
|
||||
|
||||
create_table(Tab) when is_atom(Tab) ->
|
||||
@ -28,6 +28,16 @@ create_table(Tab) when is_atom(Tab) ->
|
||||
get_table_name(NetworkId) when is_integer(NetworkId) ->
|
||||
list_to_atom("client_" ++ integer_to_list(NetworkId)).
|
||||
|
||||
-spec get_client(NetworkId :: integer(), ClientId :: binary()) -> error | {ok, Client :: #client{}} .
|
||||
get_client(NetworkId, ClientId) when is_integer(NetworkId), is_binary(ClientId) ->
|
||||
Tab = get_table_name(NetworkId),
|
||||
case mnesia:dirty_read(Tab, ClientId) of
|
||||
[] ->
|
||||
error;
|
||||
[Client|_] ->
|
||||
{ok, Client}
|
||||
end.
|
||||
|
||||
-spec get_clients(NetworkId :: integer()) -> [Client :: #client{}].
|
||||
get_clients(NetworkId) when is_integer(NetworkId) ->
|
||||
Tab = get_table_name(NetworkId),
|
||||
@ -48,12 +58,23 @@ delete_clients(NetworkId) when is_integer(NetworkId) ->
|
||||
{error, Reason}
|
||||
end.
|
||||
|
||||
-spec delete_client(NetworkId :: integer(), ClientId :: binary()) -> ok | {error, Reason :: any()}.
|
||||
-spec delete_client(NetworkId :: integer(), ClientId :: binary()) -> {ok, Client :: #client{}} | {error, Reason :: any()}.
|
||||
delete_client(NetworkId, ClientId) when is_integer(NetworkId), is_binary(ClientId) ->
|
||||
Tab = get_table_name(NetworkId),
|
||||
case mnesia:transaction(fun() -> mnesia:delete(Tab, ClientId, write) end) of
|
||||
{'atomic', ok} ->
|
||||
ok;
|
||||
|
||||
Fun = fun() ->
|
||||
case mnesia:read(Tab, ClientId, write) of
|
||||
[] ->
|
||||
mnesia:abort(not_found);
|
||||
[Record] ->
|
||||
mnesia:delete(Tab, ClientId, write),
|
||||
{ok, Record}
|
||||
end
|
||||
end,
|
||||
|
||||
case mnesia:transaction(Fun) of
|
||||
{'atomic', {ok, Client}} ->
|
||||
{ok, Client};
|
||||
{'aborted', Reason} ->
|
||||
{error, Reason}
|
||||
end.
|
||||
@ -78,16 +99,16 @@ disable_client(NetworkId, ClientId) when is_integer(NetworkId), is_binary(Client
|
||||
end.
|
||||
|
||||
%% 分配ip地址的时候,以mac地址为唯一基准
|
||||
-spec alloc_ip(NetworkId :: integer(), Ips :: list(), ClientId :: binary(), Mac :: binary(), NetAddr0 :: integer()) ->
|
||||
-spec alloc_ip(NetworkId :: integer(), Ips :: list(), ClientId :: binary(), Mac :: binary(), NetAddr0 :: integer(), HostName :: binary()) ->
|
||||
{ok, Ip :: integer()} | {error, Reason :: any()}.
|
||||
alloc_ip(NetworkId, Ips, ClientId, Mac, NetAddr0) when is_binary(ClientId), is_integer(NetAddr0), is_binary(Mac) ->
|
||||
case mnesia:transaction(fun() -> alloc_ip0(NetworkId, Ips, ClientId, Mac, NetAddr0) end) of
|
||||
alloc_ip(NetworkId, Ips, ClientId, Mac, NetAddr0, HostName) when is_binary(ClientId), is_integer(NetAddr0), is_binary(Mac), is_binary(HostName) ->
|
||||
case mnesia:transaction(fun() -> alloc_ip0(NetworkId, Ips, ClientId, Mac, NetAddr0, HostName) end) of
|
||||
{'atomic', Res} ->
|
||||
{ok, Res};
|
||||
{'aborted', Reason} ->
|
||||
{error, Reason}
|
||||
end.
|
||||
alloc_ip0(NetworkId, Ips, ClientId, Mac, NetAddr0) ->
|
||||
alloc_ip0(NetworkId, Ips, ClientId, Mac, NetAddr0, HostName) ->
|
||||
Tab = get_table_name(NetworkId),
|
||||
|
||||
case mnesia:read(Tab, ClientId) of
|
||||
@ -97,21 +118,28 @@ alloc_ip0(NetworkId, Ips, ClientId, Mac, NetAddr0) ->
|
||||
[#client{status = disabled}] ->
|
||||
mnesia:abort(client_disabled);
|
||||
[] ->
|
||||
UsedIps = mnesia:foldl(fun(#client{ip = Ip0}, Acc) -> [Ip0|Acc] end, [], Tab),
|
||||
case lists:member(NetAddr0, Ips) andalso not lists:member(NetAddr0, UsedIps) of
|
||||
{UsedIps, UsedHostNames} = mnesia:foldl(fun(#client{ip = Ip0, host_name = HostName0}, {IpAcc, HostNameAcc}) ->
|
||||
{[Ip0|IpAcc], [HostName0|HostNameAcc]}
|
||||
end, {[], []}, Tab),
|
||||
case HostName =/= <<>> andalso lists:member(HostName, UsedHostNames) of
|
||||
true ->
|
||||
%% 如果ip没有被占用,则分配給当前请求
|
||||
Client = #client{client_id = ClientId, mac = Mac, ip = NetAddr0},
|
||||
ok = mnesia:write(Tab, Client, write),
|
||||
NetAddr0;
|
||||
mnesia:abort(host_name_used);
|
||||
false ->
|
||||
case Ips -- UsedIps of
|
||||
[] ->
|
||||
mnesia:abort(no_ip);
|
||||
[Ip|_] ->
|
||||
Client = #client{client_id = ClientId, mac = Mac, ip = Ip, status = normal},
|
||||
case lists:member(NetAddr0, Ips) andalso not lists:member(NetAddr0, UsedIps) of
|
||||
true ->
|
||||
%% 如果ip没有被占用,则分配給当前请求
|
||||
Client = #client{client_id = ClientId, mac = Mac, ip = NetAddr0, host_name = HostName, status = normal},
|
||||
ok = mnesia:write(Tab, Client, write),
|
||||
Ip
|
||||
NetAddr0;
|
||||
false ->
|
||||
case Ips -- UsedIps of
|
||||
[] ->
|
||||
mnesia:abort(no_ip);
|
||||
[Ip|_] ->
|
||||
Client = #client{client_id = ClientId, mac = Mac, ip = Ip, host_name = HostName, status = normal},
|
||||
ok = mnesia:write(Tab, Client, write),
|
||||
Ip
|
||||
end
|
||||
end
|
||||
end
|
||||
end.
|
||||
|
||||
@ -11,11 +11,12 @@
|
||||
ranch,
|
||||
poolboy,
|
||||
mysql,
|
||||
esockd,
|
||||
jiffy,
|
||||
hackney,
|
||||
gpb,
|
||||
throttle,
|
||||
dns_erlang,
|
||||
pkt,
|
||||
parse_trans,
|
||||
mnesia,
|
||||
erts,
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
%% API
|
||||
-export([get_all_networks/0, get_network/1]).
|
||||
-export([auth_token/3, node_online/3, node_offline/2, flow_report/5, network_forward_report/2]).
|
||||
-export([auth_token/3, node_online/3, node_offline/2, flow_report/5, network_forward_report/2, auth_network_code/3]).
|
||||
|
||||
-spec get_all_networks() -> {ok, [NetworkId :: integer()]} | {error, Reason :: any()}.
|
||||
get_all_networks() ->
|
||||
@ -61,6 +61,20 @@ auth_token(ClientId, Token, Version) when is_binary(ClientId), is_binary(Token),
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec auth_network_code(ClientId :: binary(), NetworkCode :: binary(), Version :: integer()) -> {ok, Resp :: map()} | {error, Reason :: any()}.
|
||||
auth_network_code(ClientId, NetworkCode, Version) when is_binary(ClientId), is_binary(NetworkCode), is_integer(Version) ->
|
||||
case catch do_post("check_network", #{<<"client_id">> => ClientId, <<"code">> => NetworkCode, <<"version">> => Version}) of
|
||||
{ok, Resp} ->
|
||||
case catch jiffy:decode(Resp, [return_maps]) of
|
||||
Result when is_map(Result) ->
|
||||
{ok, Result};
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
end;
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec node_online(ClientId :: binary(), NetworkId :: integer(), IpAddr :: binary()) -> {ok, Resp :: map()} | {error, Reason :: any()}.
|
||||
node_online(ClientId, NetworkId, IpAddr) when is_binary(ClientId), is_integer(NetworkId), is_binary(IpAddr) ->
|
||||
case catch do_post("set_node_status", #{<<"client_id">> => ClientId, <<"network_id">> => NetworkId, <<"ip_addr">> => IpAddr, <<"status">> => 1}) of
|
||||
|
||||
@ -15,6 +15,12 @@ start(_StartType, _StartArgs) ->
|
||||
mnesia:start(),
|
||||
%% 加速内存的回收
|
||||
erlang:system_flag(fullsweep_after, 16),
|
||||
|
||||
%% 启动注册表
|
||||
sdlan_hostname_regedit:init(),
|
||||
sdlan_domain_regedit:init(),
|
||||
dns_pending_wheel:start(),
|
||||
|
||||
start_http_server(),
|
||||
start_tcp_server(),
|
||||
sdlan_sup:start_link().
|
||||
@ -61,18 +67,15 @@ start_tcp_server() ->
|
||||
Backlog = proplists:get_value(backlog, Props, 1024),
|
||||
Port = proplists:get_value(port, Props),
|
||||
|
||||
TransOpts = [
|
||||
{tcp_options, [
|
||||
binary,
|
||||
{reuseaddr, true},
|
||||
{active, false},
|
||||
{packet, 2},
|
||||
TransOpts = #{
|
||||
num_acceptors => Acceptors,
|
||||
max_connections => MaxConnections,
|
||||
socket_opts => [
|
||||
{port, Port},
|
||||
{nodelay, false},
|
||||
{backlog, Backlog}
|
||||
]},
|
||||
{acceptors, Acceptors},
|
||||
{max_connections, MaxConnections}
|
||||
],
|
||||
{ok, _} = esockd:open('sdlan/tcp_server', Port, TransOpts, {sdlan_channel, start_link, []}),
|
||||
]
|
||||
},
|
||||
{ok, _} = ranch:start_listener('sdlan/tcp_server', ranch_tcp, TransOpts, sdlan_channel, []),
|
||||
|
||||
lager:debug("[sdlan_app] the tcp server start at: ~p", [Port]).
|
||||
@ -28,6 +28,8 @@
|
||||
-define(NAK_NETWORK_FAULT, 4).
|
||||
%% 内部错误
|
||||
-define(NAK_INTERNAL_FAULT, 5).
|
||||
%% hostname被占用
|
||||
-define(NAK_HOSTNAME_USED, 6).
|
||||
|
||||
%% 升级策略
|
||||
-define(UPGRADE_NONE, 0).
|
||||
@ -35,8 +37,8 @@
|
||||
-define(UPGRADE_FORCE, 2).
|
||||
|
||||
%% API
|
||||
-export([start_link/2]).
|
||||
-export([publish_command/4, send_event/3, stop/2, move_network/3]).
|
||||
-export([start_link/4]).
|
||||
-export([publish_command/4, send_event/3, stop/2, move_network/4]).
|
||||
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
|
||||
|
||||
@ -75,10 +77,10 @@ publish_command(Pid, ReceiverPid, CommandType, Msg) when is_pid(Pid), is_pid(Rec
|
||||
Ref.
|
||||
|
||||
%% 网络迁移是一种特殊的指令信息,需要单独处理
|
||||
-spec move_network(Pid :: pid(), ReceiverPid :: pid(), NetworkPid :: pid()) -> Ref :: reference().
|
||||
move_network(Pid, ReceiverPid, NetworkPid) when is_pid(Pid), is_pid(ReceiverPid), is_pid(NetworkPid) ->
|
||||
-spec move_network(Pid :: pid(), ReceiverPid :: pid(), NetworkPid :: pid(), HostName :: binary()) -> Ref :: reference().
|
||||
move_network(Pid, ReceiverPid, NetworkPid, HostName) when is_pid(Pid), is_pid(ReceiverPid), is_pid(NetworkPid), is_binary(HostName) ->
|
||||
Ref = make_ref(),
|
||||
Pid ! {move_network, ReceiverPid, Ref, NetworkPid},
|
||||
Pid ! {move_network, ReceiverPid, Ref, NetworkPid, HostName},
|
||||
Ref.
|
||||
|
||||
%% 向通道中写入消息
|
||||
@ -97,19 +99,15 @@ stop(Pid, Reason) when is_pid(Pid) ->
|
||||
%% esockd callback
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
start_link(Transport, Sock) ->
|
||||
{ok, proc_lib:spawn_link(?MODULE, init, [[Transport, Sock]])}.
|
||||
start_link(Ref, _Socket, Transport, Opts) ->
|
||||
{ok, proc_lib:spawn_link(?MODULE, init, [[Ref, Transport, Opts]])}.
|
||||
|
||||
init([Transport, Sock]) ->
|
||||
lager:debug("[sdlan_channel] get a new connection: ~p", [Sock]),
|
||||
case Transport:wait(Sock) of
|
||||
{ok, NewSock} ->
|
||||
Transport:setopts(Sock, [{active, true}]),
|
||||
erlang:start_timer(?PING_TICKER, self(), ping_ticker),
|
||||
gen_server:enter_loop(?MODULE, [], #state{transport = Transport, socket = NewSock});
|
||||
{error, Reason} ->
|
||||
{stop, Reason}
|
||||
end.
|
||||
init([Ref, Transport, _Opts = []]) ->
|
||||
{ok, Socket} = ranch:handshake(Ref),
|
||||
lager:debug("[sdlan_channel] get a new connection: ~p", [Socket]),
|
||||
Transport:setopts(Socket, [{active, true}, {packet, 2}]),
|
||||
erlang:start_timer(?PING_TICKER, self(), ping_ticker),
|
||||
gen_server:enter_loop(?MODULE, [], #state{transport = Transport, socket = Socket}).
|
||||
|
||||
handle_call(_Request, _From, State) ->
|
||||
{reply, ok, State}.
|
||||
@ -117,23 +115,33 @@ handle_call(_Request, _From, State) ->
|
||||
handle_cast(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
%% 带上token或者网络id来注册
|
||||
handle_info({tcp, Sock, <<PacketId:32, ?PACKET_REGISTER_SUPER, Body/binary>>}, State=#state{transport = Transport, socket = Sock}) ->
|
||||
#sdl_register_super{version = Version, client_id = ClientId, dev_addr = #sdl_dev_addr{net_addr = NetAddr0, mac = Mac}, token = Token, pub_key = PubKey} = sdlan_pb:decode_msg(Body, sdl_register_super),
|
||||
#sdl_register_super{version = Version, client_id = ClientId, hostname = HostName, dev_addr = #sdl_dev_addr{net_addr = NetAddr0, mac = Mac}, network_code = NetworkCode, token = Token, pub_key = PubKey} = sdlan_pb:decode_msg(Body, sdl_register_super),
|
||||
|
||||
%% 参数检查
|
||||
lager:debug("[sdlan_channel] client_id: ~p, public_key: ~p", [ClientId, PubKey]),
|
||||
lager:debug("[sdlan_channel] client_id: ~p, public_key: ~p, token: ~p, network_code: ~p", [ClientId, PubKey, Token, NetworkCode]),
|
||||
true = (Mac =/= <<>> andalso PubKey =/= <<>> andalso ClientId =/= <<>>),
|
||||
%% Mac地址不能是广播地址
|
||||
true = not (sdlan_util:is_multicast_mac(Mac) orelse sdlan_util:is_broadcast_mac(Mac)),
|
||||
|
||||
case sdlan_api:auth_token(ClientId, Token, Version) of
|
||||
AuthResult = if
|
||||
Token /= <<>> ->
|
||||
lager:debug("[sdlan_channel] auth token: ~p", [Token]),
|
||||
sdlan_api:auth_token(ClientId, Token, Version);
|
||||
NetworkCode /= <<>> ->
|
||||
lager:debug("[sdlan_channel] auth network code: ~p", [NetworkCode]),
|
||||
sdlan_api:auth_network_code(ClientId, NetworkCode, Version)
|
||||
end,
|
||||
|
||||
case AuthResult of
|
||||
{ok, #{<<"result">> := #{<<"network_id">> := NetworkId, <<"upgrade_type">> := UpgradeType, <<"upgrade_prompt">> := UpgradePrompt, <<"upgrade_address">> := UpgradeAddress}}} when is_integer(NetworkId) ->
|
||||
lager:debug("[sdlan_channel] client_id: ~p, mac: ~p, token: ~p, version: ~p, registerd, alloc network_id: ~p", [ClientId, sdlan_util:format_mac(Mac), Token, Version, NetworkId]),
|
||||
%% 建立到network的对应关系
|
||||
case sdlan_network:get_pid(NetworkId) of
|
||||
NetworkPid when is_pid(NetworkPid) ->
|
||||
try sdlan_network:assign_ip_addr(NetworkPid, self(), ClientId, Mac, NetAddr0) of
|
||||
{ok, NetAddr, NetBitLen, AesKey} ->
|
||||
try sdlan_network:assign_ip_addr(NetworkPid, self(), ClientId, Mac, NetAddr0, HostName) of
|
||||
{ok, Domain, NetAddr, NetBitLen, AesKey} ->
|
||||
RsaPubKey = sdlan_cipher:rsa_pem_decode(PubKey),
|
||||
EncodedAesKey = rsa_encode(AesKey, RsaPubKey),
|
||||
|
||||
@ -142,7 +150,8 @@ handle_info({tcp, Sock, <<PacketId:32, ?PACKET_REGISTER_SUPER, Body/binary>>}, S
|
||||
network_id = NetworkId,
|
||||
net_addr = NetAddr,
|
||||
mac = Mac,
|
||||
net_bit_len = NetBitLen
|
||||
net_bit_len = NetBitLen,
|
||||
network_domain = Domain
|
||||
},
|
||||
aes_key = EncodedAesKey,
|
||||
upgrade_type = UpgradeType,
|
||||
@ -167,34 +176,38 @@ handle_info({tcp, Sock, <<PacketId:32, ?PACKET_REGISTER_SUPER, Body/binary>>}, S
|
||||
{noreply, State#state{client_id = ClientId, mac = Mac, assign_ip = NetAddr, network_pid = NetworkPid, pub_key = PubKey, is_registered = true}}
|
||||
end;
|
||||
{error, no_ip} ->
|
||||
lager:debug("[sdlan_channel] client_id: ~p, token: ~p, register get error: no_ip", [ClientId, Token]),
|
||||
lager:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: no_ip", [ClientId, Token]),
|
||||
Transport:send(Sock, register_nak_reply(PacketId, ?NAK_NO_IP, <<"No Ip address">>)),
|
||||
{stop, normal, State};
|
||||
{error, host_name_used} ->
|
||||
lager:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: host_name_used", [ClientId, Token]),
|
||||
Transport:send(Sock, register_nak_reply(PacketId, ?NAK_HOSTNAME_USED, <<"Host Name Used">>)),
|
||||
{stop, normal, State};
|
||||
{error, client_disabled} ->
|
||||
lager:debug("[sdlan_channel] client_id: ~p, token: ~p, register get error: client_disabled", [ClientId, Token]),
|
||||
lager:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: client_disabled", [ClientId, Token]),
|
||||
Transport:send(Sock, register_nak_reply(PacketId, ?NAK_NODE_DISABLE, <<"Client Connection Disable">>)),
|
||||
{stop, normal, State}
|
||||
catch _:Error:Stack ->
|
||||
lager:debug("[sdlan_channel] get error: ~p, stack: ~p", [Error, Stack])
|
||||
lager:warning("[sdlan_channel] get error: ~p, stack: ~p", [Error, Stack])
|
||||
end;
|
||||
undefined ->
|
||||
lager:debug("[sdlan_channel] client_id: ~p, token: ~p, register get error: network not found", [ClientId, Token]),
|
||||
lager:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: network not found", [ClientId, Token]),
|
||||
Transport:send(Sock, register_nak_reply(PacketId, ?NAK_INTERNAL_FAULT, <<"Internal Error">>)),
|
||||
|
||||
{stop, normal, State}
|
||||
end;
|
||||
{ok, #{<<"error">> := #{<<"code">> := 1, <<"message">> := Message}}} ->
|
||||
lager:debug("[sdlan_channel] client_id: ~p, token: ~p, register get error: ~p, error_code: 1", [ClientId, Token, Message]),
|
||||
lager:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: ~ts, error_code: 1", [ClientId, Token, Message]),
|
||||
Transport:send(Sock, register_nak_reply(PacketId, ?NAK_INVALID_TOKEN, Message)),
|
||||
{stop, normal, State};
|
||||
|
||||
{ok, #{<<"error">> := #{<<"code">> := 2, <<"message">> := Message}}} ->
|
||||
lager:debug("[sdlan_channel] client_id: ~p, token: ~p, register get error: ~p, error_code: 2", [ClientId, Token, Message]),
|
||||
lager:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: ~p, error_code: 2", [ClientId, Token, Message]),
|
||||
Transport:send(Sock, register_nak_reply(PacketId, ?NAK_NODE_DISABLE, Message)),
|
||||
{stop, normal, State};
|
||||
|
||||
{error, Reason} ->
|
||||
lager:debug("[sdlan_channel] client_id: ~p, token: ~p, register get error: ~p", [ClientId, Token, Reason]),
|
||||
lager:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: ~p", [ClientId, Token, Reason]),
|
||||
Transport:send(Sock, register_nak_reply(PacketId, ?NAK_NETWORK_FAULT, <<"Network Error">>)),
|
||||
{stop, normal, State}
|
||||
end;
|
||||
@ -225,8 +238,8 @@ handle_info({tcp, Sock, <<PacketId:32, ?PACKET_QUERY_INFO, Body/binary>>}, State
|
||||
{noreply, State}
|
||||
end;
|
||||
|
||||
handle_info({tcp, _Sock, <<0:32, ?PACKET_PING>>}, State = #state{transport = Transport, socket = Sock, client_id = ClientId, ping_counter = PingCounter}) ->
|
||||
lager:debug("[sdlan_channel] client_id: ~p, get ping", [ClientId]),
|
||||
handle_info({tcp, _Sock, <<0:32, ?PACKET_PING>>}, State = #state{transport = Transport, socket = Sock, ping_counter = PingCounter}) ->
|
||||
%lager:debug("[sdlan_channel] client_id: ~p, get ping", [ClientId]),
|
||||
Transport:send(Sock, <<0:32, ?PACKET_PONG>>),
|
||||
{noreply, State#state{ping_counter = PingCounter + 1}};
|
||||
|
||||
@ -242,12 +255,12 @@ handle_info({timeout, _, ping_ticker}, State = #state{client_id = ClientId, ping
|
||||
end;
|
||||
|
||||
%% 重新加入网络
|
||||
handle_info({move_network, ReceiverPid, Ref, NetworkPid},
|
||||
handle_info({move_network, ReceiverPid, Ref, NetworkPid, HostName},
|
||||
State = #state{transport = Transport, socket = Sock, client_id = ClientId, mac = Mac, pub_key = PubKey, packet_id = PacketId, inflight = Inflight, is_registered = true}) ->
|
||||
|
||||
%% 建立到network的对应关系
|
||||
case sdlan_network:assign_ip_addr(NetworkPid, self(), ClientId, Mac, 0) of
|
||||
{ok, NetAddr, NetBitLen, AesKey} ->
|
||||
case sdlan_network:assign_ip_addr(NetworkPid, self(), ClientId, Mac, 0, HostName) of
|
||||
{ok, Domain, NetAddr, NetBitLen, AesKey} ->
|
||||
RsaPubKey = sdlan_cipher:rsa_pem_decode(PubKey),
|
||||
EncodedAesKey = rsa_encode(AesKey, RsaPubKey),
|
||||
|
||||
@ -257,7 +270,8 @@ handle_info({move_network, ReceiverPid, Ref, NetworkPid},
|
||||
dev_addr = #sdl_dev_addr {
|
||||
network_id = NetworkId,
|
||||
net_addr = NetAddr,
|
||||
net_bit_len = NetBitLen
|
||||
net_bit_len = NetBitLen,
|
||||
network_domain = Domain
|
||||
},
|
||||
aes_key = EncodedAesKey
|
||||
}),
|
||||
|
||||
36
apps/sdlan/src/sdlan_domain_regedit.erl
Normal file
36
apps/sdlan/src/sdlan_domain_regedit.erl
Normal file
@ -0,0 +1,36 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author anlicheng
|
||||
%%% @copyright (C) 2025, <COMPANY>
|
||||
%%% @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}).
|
||||
32
apps/sdlan/src/sdlan_hostname_regedit.erl
Normal file
32
apps/sdlan/src/sdlan_hostname_regedit.erl
Normal file
@ -0,0 +1,32 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author anlicheng
|
||||
%%% @copyright (C) 2025, <COMPANY>
|
||||
%%% @doc
|
||||
%%% 内部地址协议注册表
|
||||
%%% @end
|
||||
%%% Created : 13. 12月 2025 21:09
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(sdlan_hostname_regedit).
|
||||
-author("anlicheng").
|
||||
|
||||
%% API
|
||||
-export([init/0, lookup/1, insert/2]).
|
||||
|
||||
-define(TABLE, sdlan_hostname_regedit).
|
||||
|
||||
init() ->
|
||||
ets:new(?TABLE, [named_table, set, public, {read_concurrency, true}, {write_concurrency, true}]).
|
||||
|
||||
-spec lookup(FullHostname :: binary()) -> error | {ok, Ip :: inet:ip4_address()}.
|
||||
lookup(FullHostname) when is_binary(FullHostname) ->
|
||||
case ets:lookup(?TABLE, FullHostname) of
|
||||
[{_, Ip}] ->
|
||||
{ok, Ip};
|
||||
[] ->
|
||||
error
|
||||
end.
|
||||
|
||||
-spec insert(FullHostname :: binary(), Ip :: integer()) -> no_return().
|
||||
insert(FullHostname, Ip) when is_binary(FullHostname), is_integer(Ip) ->
|
||||
<<Ip0, Ip1, Ip2, Ip3>> = <<Ip:32>>,
|
||||
true = ets:insert(?TABLE, {FullHostname, {Ip0, Ip1, Ip2, Ip3}}).
|
||||
@ -21,7 +21,7 @@
|
||||
|
||||
%% API
|
||||
-export([start_link/2]).
|
||||
-export([get_name/1, get_pid/1, assign_ip_addr/5, peer_info/3, unregister/3, debug_info/1, get_network_id/1, get_used_map/1]).
|
||||
-export([get_name/1, get_pid/1, assign_ip_addr/6, peer_info/3, unregister/3, debug_info/1, get_network_id/1, get_used_map/1]).
|
||||
-export([forward/5, update_hole/6, disable_client/2, get_channel/2, dropout_client/2, reload/1]).
|
||||
-export([test_event/1]).
|
||||
|
||||
@ -33,11 +33,9 @@
|
||||
nat_type :: integer()
|
||||
}).
|
||||
|
||||
%% ip的使用信息
|
||||
%% ip的使用信息, 记录主机的动态信息
|
||||
-record(host, {
|
||||
client_id :: binary(),
|
||||
mac :: binary(),
|
||||
ip :: integer(),
|
||||
channel_pid :: undefined | pid(),
|
||||
monitor_ref :: undefined | reference(),
|
||||
hole :: undefined | #hole{},
|
||||
@ -48,6 +46,7 @@
|
||||
-record(state, {
|
||||
network_id :: integer(),
|
||||
name :: binary(),
|
||||
domain :: binary(),
|
||||
ipaddr :: binary(),
|
||||
mask_len :: integer(),
|
||||
owner_id :: integer(),
|
||||
@ -89,10 +88,10 @@ get_name(Id) when is_integer(Id) ->
|
||||
reload(Pid) when is_pid(Pid) ->
|
||||
gen_server:call(Pid, reload).
|
||||
|
||||
-spec assign_ip_addr(Pid :: pid(), ChannelPid :: pid(), ClientId :: binary(), Mac :: binary(), NetAddr :: integer()) ->
|
||||
{ok, NetAddr :: integer(), MaskLen :: integer(), AesKey :: binary()} | {error, Reason :: any()}.
|
||||
assign_ip_addr(Pid, ChannelPid, ClientId, Mac, NetAddr) when is_pid(Pid), is_pid(ChannelPid), is_binary(ClientId), is_binary(Mac), is_integer(NetAddr) ->
|
||||
gen_server:call(Pid, {assign_ip_addr, ChannelPid, ClientId, Mac, NetAddr}).
|
||||
-spec assign_ip_addr(Pid :: pid(), ChannelPid :: pid(), ClientId :: binary(), Mac :: binary(), NetAddr :: integer(), HostName :: binary()) ->
|
||||
{ok, Domain :: binary(), NetAddr :: integer(), MaskLen :: integer(), AesKey :: binary()} | {error, Reason :: any()}.
|
||||
assign_ip_addr(Pid, ChannelPid, ClientId, Mac, NetAddr, HostName) when is_pid(Pid), is_pid(ChannelPid), is_binary(ClientId), is_binary(Mac), is_integer(NetAddr) ->
|
||||
gen_server:call(Pid, {assign_ip_addr, ChannelPid, ClientId, Mac, NetAddr, HostName}).
|
||||
|
||||
-spec get_network_id(Pid :: pid()) -> {ok, NetworkId :: integer()}.
|
||||
get_network_id(Pid) when is_pid(Pid) ->
|
||||
@ -125,7 +124,7 @@ get_channel(Pid, ClientId) when is_pid(Pid), is_binary(ClientId) ->
|
||||
gen_server:call(Pid, {get_channel, ClientId}).
|
||||
|
||||
%% 剔除client_id,channel不关闭; channel会被重新绑定到其他的network里面
|
||||
-spec dropout_client(Pid :: pid(), ClientId :: binary()) -> {ok, ChannelPid :: pid()} | error.
|
||||
-spec dropout_client(Pid :: pid(), ClientId :: binary()) -> {ok, ChannelPid :: pid(), HostName :: binary()} | error.
|
||||
dropout_client(Pid, ClientId) when is_pid(Pid), is_binary(ClientId) ->
|
||||
gen_server:call(Pid, {dropout_client, ClientId}).
|
||||
|
||||
@ -159,7 +158,7 @@ init([Id]) when is_integer(Id) ->
|
||||
case sdlan_api:get_network(Id) of
|
||||
{ok, #{<<"ipaddr">> := Null}} when Null == <<"null">>; Null == <<"NULL">> ->
|
||||
ignore;
|
||||
{ok, #{<<"id">> := Id, <<"name">> := Name, <<"ipaddr">> := IpAddr0, <<"owner_id">> := OwnerId}} ->
|
||||
{ok, #{<<"id">> := Id, <<"name">> := Name, <<"domain">> := Domain, <<"ipaddr">> := IpAddr0, <<"owner_id">> := OwnerId}} ->
|
||||
{IpAddr, MaskLen} = parse_ipaddr(IpAddr0),
|
||||
Ips = sdlan_ipaddr:ips(IpAddr, MaskLen),
|
||||
AesKey = sdlan_util:rand_byte(32),
|
||||
@ -176,7 +175,9 @@ 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)]),
|
||||
|
||||
{ok, #state{network_id = Id, name = Name, ipaddr = IpAddr, owner_id = OwnerId, mask_len = MaskLen, ips = Ips, aes_key = AesKey, throttle_key = ThrottleKey}};
|
||||
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]),
|
||||
ignore
|
||||
@ -220,23 +221,32 @@ handle_call(reload, _From, State = #state{network_id = Id, ipaddr = OldIpAddr, m
|
||||
end;
|
||||
|
||||
%% 给客户端分配ip地址
|
||||
handle_call({assign_ip_addr, ChannelPid, ClientId, Mac, NetAddr0}, _From,
|
||||
State = #state{network_id = NetworkId, ips = Ips, used_map = UsedMap, mask_len = MaskLen, aes_key = AesKey}) ->
|
||||
handle_call({assign_ip_addr, ChannelPid, ClientId, Mac, NetAddr0, HostName}, _From,
|
||||
State = #state{network_id = NetworkId, domain = Domain, ips = Ips, used_map = UsedMap, mask_len = MaskLen, aes_key = AesKey}) ->
|
||||
|
||||
%% 分配ip地址的时候,以mac地址为唯一基准
|
||||
lager:debug("[sdlan_network] alloc_ip, network_id: ~p, ips: ~p, client_id: ~p, mac: ~p, net_addr: ~p",
|
||||
[NetworkId, Ips, ClientId, sdlan_util:format_mac(Mac), sdlan_ipaddr:int_to_ipv4(NetAddr0)]),
|
||||
|
||||
case client_model:alloc_ip(NetworkId, Ips, ClientId, Mac, NetAddr0) of
|
||||
case client_model:alloc_ip(NetworkId, Ips, ClientId, Mac, NetAddr0, HostName) of
|
||||
{ok, Ip} ->
|
||||
%% 关闭之前的channel
|
||||
maybe_close_channel(maps:get(Mac, UsedMap, undefined)),
|
||||
|
||||
%% 添加域名->ip的映射关系
|
||||
case HostName =/= <<>> of
|
||||
true ->
|
||||
FullHostname = <<HostName/binary, ".", Domain/binary>>,
|
||||
sdlan_hostname_regedit:insert(FullHostname, Ip);
|
||||
false ->
|
||||
ok
|
||||
end,
|
||||
|
||||
%% 建立到新的channel之间的关系
|
||||
MRef = monitor(process, ChannelPid),
|
||||
NUsedMap = maps:put(Mac, #host{client_id = ClientId, mac = Mac, ip = Ip, channel_pid = ChannelPid, monitor_ref = MRef}, UsedMap),
|
||||
NUsedMap = maps:put(Mac, #host{client_id = ClientId, channel_pid = ChannelPid, monitor_ref = MRef}, UsedMap),
|
||||
|
||||
{reply, {ok, Ip, MaskLen, AesKey}, State#state{used_map = NUsedMap}};
|
||||
{reply, {ok, Domain, Ip, MaskLen, AesKey}, State#state{used_map = NUsedMap}};
|
||||
{error, Reason} ->
|
||||
{reply, {error, Reason}, State}
|
||||
end;
|
||||
@ -297,9 +307,12 @@ handle_call({dropout_client, ClientId}, _From, State = #state{network_id = Netwo
|
||||
is_reference(MRef) andalso demonitor(MRef),
|
||||
NUsedMap = maps:remove(Mac, UsedMap),
|
||||
%% 从数据库删除
|
||||
client_model:delete_client(NetworkId, ClientId),
|
||||
|
||||
{reply, {ok, ChannelPid}, State#state{used_map = NUsedMap}};
|
||||
case client_model:delete_client(NetworkId, ClientId) of
|
||||
{ok, #client{host_name = HostName}} ->
|
||||
{reply, {ok, ChannelPid, HostName}, State#state{used_map = NUsedMap}};
|
||||
{error, _} ->
|
||||
{reply, error, State}
|
||||
end;
|
||||
false ->
|
||||
{reply, error, State}
|
||||
end;
|
||||
@ -337,7 +350,14 @@ handle_call(debug_info, _From, State = #state{network_id = NetworkId, ipaddr = I
|
||||
<<"mask_len">> => MaskLen,
|
||||
<<"owner_id">> => OwnerId,
|
||||
<<"ips">> => lists:map(fun sdlan_ipaddr:int_to_ipv4/1, Ips),
|
||||
<<"used_ips">> => lists:map(fun({_, Host}) -> format_host(Host) end, maps:to_list(UsedMap))
|
||||
<<"used_ips">> => lists:map(fun({_, Host = #host{client_id = ClientId}}) ->
|
||||
case client_model:get_client(NetworkId, ClientId) of
|
||||
error ->
|
||||
#{};
|
||||
{ok, #client{mac = Mac, ip = Ip}} ->
|
||||
format_host(Host, Ip, Mac)
|
||||
end
|
||||
end, maps:to_list(UsedMap))
|
||||
},
|
||||
{reply, Reply, State}.
|
||||
|
||||
@ -434,12 +454,12 @@ handle_cast({unregister, _ClientId, Mac}, State = #state{network_id = NetworkId,
|
||||
end;
|
||||
|
||||
%% 需要判断,client是属于当前网络的
|
||||
handle_cast({update_hole, _ClientId, Mac, Peer, NatType, V6Info}, State = #state{used_map = UsedMap}) ->
|
||||
case maps:find(Mac, UsedMap) of
|
||||
{ok, Host0 = #host{hole = OldHole, ip = Ip}} ->
|
||||
handle_cast({update_hole, ClientId, Mac, Peer, NatType, V6Info}, State = #state{network_id = NetworkId, used_map = UsedMap}) ->
|
||||
case {maps:find(Mac, UsedMap), client_model:get_client(NetworkId, ClientId)} of
|
||||
{{ok, Host0 = #host{client_id = ClientId0, hole = OldHole}}, {ok, #client{ip = Ip}}} when ClientId =:= ClientId0 ->
|
||||
case OldHole =:= undefined orelse (OldHole#hole.peer =/= Peer orelse OldHole#hole.nat_type =/= NatType) of
|
||||
true ->
|
||||
NatChangedEvent = sdlan_pb:encode_msg(#sdl_nat_changed_event {
|
||||
NatChangedEvent = sdlan_pb:encode_msg(#sdl_nat_changed_event{
|
||||
mac = Mac,
|
||||
ip = Ip
|
||||
}),
|
||||
@ -450,7 +470,7 @@ handle_cast({update_hole, _ClientId, Mac, Peer, NatType, V6Info}, State = #state
|
||||
Host = Host0#host{hole = #hole{peer = Peer, nat_type = NatType}, v6_info = V6Info},
|
||||
|
||||
{noreply, State#state{used_map = maps:put(Mac, Host, UsedMap)}};
|
||||
error ->
|
||||
_ ->
|
||||
{noreply, State}
|
||||
end.
|
||||
|
||||
@ -560,8 +580,8 @@ parse_ipaddr(IpAddr0) when is_binary(IpAddr0) ->
|
||||
{IpAddr0, 24}
|
||||
end.
|
||||
|
||||
-spec format_host(Host :: #host{}) -> map().
|
||||
format_host(#host{client_id = ClientId, mac = Mac, ip = Ip, hole = Hole, v6_info = V6Info}) ->
|
||||
-spec format_host(Host :: #host{}, Ip :: integer(), Mac :: binary()) -> map().
|
||||
format_host(#host{client_id = ClientId, hole = Hole, v6_info = V6Info}, Ip, Mac) when is_integer(Ip), is_binary(Mac) ->
|
||||
HoleMap = case Hole of
|
||||
undefined ->
|
||||
#{};
|
||||
|
||||
@ -213,7 +213,7 @@ encode_msg_sdl_v6_info(#sdl_v6_info{port = F1, v6 = F2}, Bin, TrUserData) ->
|
||||
encode_msg_sdl_dev_addr(Msg, TrUserData) -> encode_msg_sdl_dev_addr(Msg, <<>>, TrUserData).
|
||||
|
||||
|
||||
encode_msg_sdl_dev_addr(#sdl_dev_addr{network_id = F1, mac = F2, net_addr = F3, net_bit_len = F4}, Bin, TrUserData) ->
|
||||
encode_msg_sdl_dev_addr(#sdl_dev_addr{network_id = F1, mac = F2, net_addr = F3, net_bit_len = F4, network_domain = F5}, Bin, TrUserData) ->
|
||||
B1 = if F1 == undefined -> Bin;
|
||||
true ->
|
||||
begin
|
||||
@ -242,12 +242,22 @@ encode_msg_sdl_dev_addr(#sdl_dev_addr{network_id = F1, mac = F2, net_addr = F3,
|
||||
end
|
||||
end
|
||||
end,
|
||||
if F4 == undefined -> B3;
|
||||
B4 = if F4 == undefined -> B3;
|
||||
true ->
|
||||
begin
|
||||
TrF4 = id(F4, TrUserData),
|
||||
if TrF4 =:= 0 -> B3;
|
||||
true -> e_varint(TrF4, <<B3/binary, 32>>, TrUserData)
|
||||
end
|
||||
end
|
||||
end,
|
||||
if F5 == undefined -> B4;
|
||||
true ->
|
||||
begin
|
||||
TrF4 = id(F4, TrUserData),
|
||||
if TrF4 =:= 0 -> B3;
|
||||
true -> e_varint(TrF4, <<B3/binary, 32>>, TrUserData)
|
||||
TrF5 = id(F5, TrUserData),
|
||||
case is_empty_string(TrF5) of
|
||||
true -> B4;
|
||||
false -> e_type_string(TrF5, <<B4/binary, 42>>, TrUserData)
|
||||
end
|
||||
end
|
||||
end.
|
||||
@ -257,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}, 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
|
||||
@ -306,13 +316,33 @@ encode_msg_sdl_register_super(#sdl_register_super{version = F1, installed_channe
|
||||
end
|
||||
end
|
||||
end,
|
||||
if F6 == undefined -> B5;
|
||||
B6 = if F6 == undefined -> B5;
|
||||
true ->
|
||||
begin
|
||||
TrF6 = id(F6, TrUserData),
|
||||
case is_empty_string(TrF6) of
|
||||
true -> B5;
|
||||
false -> e_type_string(TrF6, <<B5/binary, 50>>, TrUserData)
|
||||
end
|
||||
end
|
||||
end,
|
||||
B7 = if F7 == undefined -> B6;
|
||||
true ->
|
||||
begin
|
||||
TrF7 = id(F7, TrUserData),
|
||||
case is_empty_string(TrF7) of
|
||||
true -> B6;
|
||||
false -> e_type_string(TrF7, <<B6/binary, 58>>, TrUserData)
|
||||
end
|
||||
end
|
||||
end,
|
||||
if F8 == undefined -> B7;
|
||||
true ->
|
||||
begin
|
||||
TrF6 = id(F6, TrUserData),
|
||||
case is_empty_string(TrF6) of
|
||||
true -> B5;
|
||||
false -> e_type_string(TrF6, <<B5/binary, 50>>, TrUserData)
|
||||
TrF8 = id(F8, TrUserData),
|
||||
case is_empty_string(TrF8) of
|
||||
true -> B7;
|
||||
false -> e_type_string(TrF8, <<B7/binary, 66>>, TrUserData)
|
||||
end
|
||||
end
|
||||
end.
|
||||
@ -1149,70 +1179,77 @@ skip_32_sdl_v6_info(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) ->
|
||||
|
||||
skip_64_sdl_v6_info(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, TrUserData) -> dfp_read_field_def_sdl_v6_info(Rest, Z1, Z2, F, F@_1, F@_2, TrUserData).
|
||||
|
||||
decode_msg_sdl_dev_addr(Bin, TrUserData) -> dfp_read_field_def_sdl_dev_addr(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), id(0, TrUserData), id(0, TrUserData), TrUserData).
|
||||
decode_msg_sdl_dev_addr(Bin, TrUserData) -> dfp_read_field_def_sdl_dev_addr(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), id(0, TrUserData), id(0, TrUserData), id(<<>>, TrUserData), TrUserData).
|
||||
|
||||
dfp_read_field_def_sdl_dev_addr(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_sdl_dev_addr_network_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
dfp_read_field_def_sdl_dev_addr(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_sdl_dev_addr_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
dfp_read_field_def_sdl_dev_addr(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_sdl_dev_addr_net_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
dfp_read_field_def_sdl_dev_addr(<<32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> d_field_sdl_dev_addr_net_bit_len(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
dfp_read_field_def_sdl_dev_addr(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, _) -> #sdl_dev_addr{network_id = F@_1, mac = F@_2, net_addr = F@_3, net_bit_len = F@_4};
|
||||
dfp_read_field_def_sdl_dev_addr(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dg_read_field_def_sdl_dev_addr(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData).
|
||||
dfp_read_field_def_sdl_dev_addr(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_dev_addr_network_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
dfp_read_field_def_sdl_dev_addr(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_dev_addr_mac(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
dfp_read_field_def_sdl_dev_addr(<<24, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_dev_addr_net_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
dfp_read_field_def_sdl_dev_addr(<<32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_dev_addr_net_bit_len(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
dfp_read_field_def_sdl_dev_addr(<<42, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> d_field_sdl_dev_addr_network_domain(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
dfp_read_field_def_sdl_dev_addr(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, _) -> #sdl_dev_addr{network_id = F@_1, mac = F@_2, net_addr = F@_3, net_bit_len = F@_4, network_domain = F@_5};
|
||||
dfp_read_field_def_sdl_dev_addr(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dg_read_field_def_sdl_dev_addr(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData).
|
||||
|
||||
dg_read_field_def_sdl_dev_addr(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_dev_addr(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
dg_read_field_def_sdl_dev_addr(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, TrUserData) ->
|
||||
dg_read_field_def_sdl_dev_addr(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 32 - 7 -> dg_read_field_def_sdl_dev_addr(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
dg_read_field_def_sdl_dev_addr(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) ->
|
||||
Key = X bsl N + Acc,
|
||||
case Key of
|
||||
8 -> d_field_sdl_dev_addr_network_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
18 -> d_field_sdl_dev_addr_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
24 -> d_field_sdl_dev_addr_net_addr(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
32 -> d_field_sdl_dev_addr_net_bit_len(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
8 -> d_field_sdl_dev_addr_network_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
18 -> d_field_sdl_dev_addr_mac(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
24 -> d_field_sdl_dev_addr_net_addr(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
32 -> d_field_sdl_dev_addr_net_bit_len(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
42 -> d_field_sdl_dev_addr_network_domain(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
_ ->
|
||||
case Key band 7 of
|
||||
0 -> skip_varint_sdl_dev_addr(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
1 -> skip_64_sdl_dev_addr(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
2 -> skip_length_delimited_sdl_dev_addr(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
3 -> skip_group_sdl_dev_addr(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
5 -> skip_32_sdl_dev_addr(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, TrUserData)
|
||||
0 -> skip_varint_sdl_dev_addr(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
1 -> skip_64_sdl_dev_addr(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
2 -> skip_length_delimited_sdl_dev_addr(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
3 -> skip_group_sdl_dev_addr(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
5 -> skip_32_sdl_dev_addr(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData)
|
||||
end
|
||||
end;
|
||||
dg_read_field_def_sdl_dev_addr(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, _) -> #sdl_dev_addr{network_id = F@_1, mac = F@_2, net_addr = F@_3, net_bit_len = F@_4}.
|
||||
dg_read_field_def_sdl_dev_addr(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, _) -> #sdl_dev_addr{network_id = F@_1, mac = F@_2, net_addr = F@_3, net_bit_len = F@_4, network_domain = F@_5}.
|
||||
|
||||
d_field_sdl_dev_addr_network_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_sdl_dev_addr_network_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
d_field_sdl_dev_addr_network_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, TrUserData) ->
|
||||
d_field_sdl_dev_addr_network_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_dev_addr_network_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
d_field_sdl_dev_addr_network_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, F@_5, TrUserData) ->
|
||||
{NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest},
|
||||
dfp_read_field_def_sdl_dev_addr(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, TrUserData).
|
||||
dfp_read_field_def_sdl_dev_addr(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, F@_5, TrUserData).
|
||||
|
||||
d_field_sdl_dev_addr_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_sdl_dev_addr_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
d_field_sdl_dev_addr_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, TrUserData) ->
|
||||
d_field_sdl_dev_addr_mac(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_dev_addr_mac(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
d_field_sdl_dev_addr_mac(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, F@_5, TrUserData) ->
|
||||
{NewFValue, RestF} = begin Len = X bsl N + Acc, <<Bytes:Len/binary, Rest2/binary>> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end,
|
||||
dfp_read_field_def_sdl_dev_addr(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, TrUserData).
|
||||
dfp_read_field_def_sdl_dev_addr(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, F@_5, TrUserData).
|
||||
|
||||
d_field_sdl_dev_addr_net_addr(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_sdl_dev_addr_net_addr(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
d_field_sdl_dev_addr_net_addr(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, TrUserData) ->
|
||||
d_field_sdl_dev_addr_net_addr(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_dev_addr_net_addr(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
d_field_sdl_dev_addr_net_addr(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, F@_5, TrUserData) ->
|
||||
{NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest},
|
||||
dfp_read_field_def_sdl_dev_addr(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, TrUserData).
|
||||
dfp_read_field_def_sdl_dev_addr(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, F@_5, TrUserData).
|
||||
|
||||
d_field_sdl_dev_addr_net_bit_len(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> d_field_sdl_dev_addr_net_bit_len(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
d_field_sdl_dev_addr_net_bit_len(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, TrUserData) ->
|
||||
d_field_sdl_dev_addr_net_bit_len(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_dev_addr_net_bit_len(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
d_field_sdl_dev_addr_net_bit_len(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, _, F@_5, TrUserData) ->
|
||||
{NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest},
|
||||
dfp_read_field_def_sdl_dev_addr(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, TrUserData).
|
||||
dfp_read_field_def_sdl_dev_addr(RestF, 0, 0, F, F@_1, F@_2, F@_3, NewFValue, F@_5, TrUserData).
|
||||
|
||||
skip_varint_sdl_dev_addr(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> skip_varint_sdl_dev_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
skip_varint_sdl_dev_addr(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_sdl_dev_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData).
|
||||
d_field_sdl_dev_addr_network_domain(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> d_field_sdl_dev_addr_network_domain(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
d_field_sdl_dev_addr_network_domain(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, _, TrUserData) ->
|
||||
{NewFValue, RestF} = begin Len = X bsl N + Acc, <<Bytes:Len/binary, Rest2/binary>> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end,
|
||||
dfp_read_field_def_sdl_dev_addr(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, NewFValue, TrUserData).
|
||||
|
||||
skip_length_delimited_sdl_dev_addr(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) when N < 57 -> skip_length_delimited_sdl_dev_addr(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData);
|
||||
skip_length_delimited_sdl_dev_addr(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, TrUserData) ->
|
||||
skip_varint_sdl_dev_addr(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> skip_varint_sdl_dev_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
skip_varint_sdl_dev_addr(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dfp_read_field_def_sdl_dev_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData).
|
||||
|
||||
skip_length_delimited_sdl_dev_addr(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) when N < 57 -> skip_length_delimited_sdl_dev_addr(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData);
|
||||
skip_length_delimited_sdl_dev_addr(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) ->
|
||||
Length = X bsl N + Acc,
|
||||
<<_:Length/binary, Rest2/binary>> = Rest,
|
||||
dfp_read_field_def_sdl_dev_addr(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, TrUserData).
|
||||
dfp_read_field_def_sdl_dev_addr(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData).
|
||||
|
||||
skip_group_sdl_dev_addr(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, TrUserData) ->
|
||||
skip_group_sdl_dev_addr(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) ->
|
||||
{_, Rest} = read_group(Bin, FNum),
|
||||
dfp_read_field_def_sdl_dev_addr(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, TrUserData).
|
||||
dfp_read_field_def_sdl_dev_addr(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData).
|
||||
|
||||
skip_32_sdl_dev_addr(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_sdl_dev_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData).
|
||||
skip_32_sdl_dev_addr(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dfp_read_field_def_sdl_dev_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData).
|
||||
|
||||
skip_64_sdl_dev_addr(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData) -> dfp_read_field_def_sdl_dev_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, TrUserData).
|
||||
skip_64_sdl_dev_addr(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData) -> dfp_read_field_def_sdl_dev_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, TrUserData).
|
||||
|
||||
decode_msg_sdl_empty(Bin, TrUserData) -> dfp_read_field_def_sdl_empty(Bin, 0, 0, 0, TrUserData).
|
||||
|
||||
@ -1248,59 +1285,68 @@ skip_32_sdl_empty(<<_:32, Rest/binary>>, Z1, Z2, F, TrUserData) -> dfp_read_fiel
|
||||
|
||||
skip_64_sdl_empty(<<_:64, Rest/binary>>, Z1, Z2, F, TrUserData) -> dfp_read_field_def_sdl_empty(Rest, Z1, Z2, F, TrUserData).
|
||||
|
||||
decode_msg_sdl_register_super(Bin, TrUserData) -> dfp_read_field_def_sdl_register_super(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), id(undefined, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), TrUserData).
|
||||
decode_msg_sdl_register_super(Bin, TrUserData) ->
|
||||
dfp_read_field_def_sdl_register_super(Bin, 0, 0, 0, id(0, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), id(undefined, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), id(<<>>, TrUserData), TrUserData).
|
||||
|
||||
dfp_read_field_def_sdl_register_super(<<8, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> d_field_sdl_register_super_version(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
dfp_read_field_def_sdl_register_super(<<18, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> d_field_sdl_register_super_installed_channel(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
dfp_read_field_def_sdl_register_super(<<26, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> d_field_sdl_register_super_client_id(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
dfp_read_field_def_sdl_register_super(<<34, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> d_field_sdl_register_super_dev_addr(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
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, TrUserData) -> d_field_sdl_register_super_pub_key(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, 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, TrUserData) -> d_field_sdl_register_super_token(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
dfp_read_field_def_sdl_register_super(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, _) -> #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};
|
||||
dfp_read_field_def_sdl_register_super(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> dg_read_field_def_sdl_register_super(Other, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData).
|
||||
dfp_read_field_def_sdl_register_super(<<8, 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_version(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(<<18, 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_installed_channel(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(<<26, 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_client_id(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(<<34, 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_dev_addr(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(<<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_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, 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, TrUserData) when N < 32 - 7 ->
|
||||
dg_read_field_def_sdl_register_super(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
dg_read_field_def_sdl_register_super(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, 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 ->
|
||||
dg_read_field_def_sdl_register_super(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);
|
||||
dg_read_field_def_sdl_register_super(<<0:1, X:7, Rest/binary>>, N, Acc, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) ->
|
||||
Key = X bsl N + Acc,
|
||||
case Key of
|
||||
8 -> d_field_sdl_register_super_version(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
18 -> d_field_sdl_register_super_installed_channel(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
26 -> d_field_sdl_register_super_client_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
34 -> d_field_sdl_register_super_dev_addr(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
42 -> d_field_sdl_register_super_pub_key(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
50 -> d_field_sdl_register_super_token(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
8 -> d_field_sdl_register_super_version(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData);
|
||||
18 -> d_field_sdl_register_super_installed_channel(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData);
|
||||
26 -> d_field_sdl_register_super_client_id(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData);
|
||||
34 -> d_field_sdl_register_super_dev_addr(Rest, 0, 0, 0, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData);
|
||||
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_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, TrUserData);
|
||||
1 -> skip_64_sdl_register_super(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
2 -> skip_length_delimited_sdl_register_super(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
3 -> skip_group_sdl_register_super(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
5 -> skip_32_sdl_register_super(Rest, 0, 0, Key bsr 3, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData)
|
||||
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);
|
||||
1 -> skip_64_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);
|
||||
2 -> skip_length_delimited_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);
|
||||
3 -> skip_group_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);
|
||||
5 -> skip_32_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)
|
||||
end
|
||||
end;
|
||||
dg_read_field_def_sdl_register_super(<<>>, 0, 0, _, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, _) -> #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}.
|
||||
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, 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, 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, TrUserData);
|
||||
d_field_sdl_register_super_version(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) ->
|
||||
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);
|
||||
d_field_sdl_register_super_version(<<0:1, X:7, Rest/binary>>, N, Acc, F, _, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) ->
|
||||
{NewFValue, RestF} = {id((X bsl N + Acc) band 4294967295, TrUserData), Rest},
|
||||
dfp_read_field_def_sdl_register_super(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData).
|
||||
dfp_read_field_def_sdl_register_super(RestF, 0, 0, F, NewFValue, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData).
|
||||
|
||||
d_field_sdl_register_super_installed_channel(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) when N < 57 ->
|
||||
d_field_sdl_register_super_installed_channel(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
d_field_sdl_register_super_installed_channel(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, F@_5, F@_6, TrUserData) ->
|
||||
d_field_sdl_register_super_installed_channel(<<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_installed_channel(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_installed_channel(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, _, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) ->
|
||||
{NewFValue, RestF} = begin Len = X bsl N + Acc, <<Bytes:Len/binary, Rest2/binary>> = Rest, Bytes2 = binary:copy(Bytes), {id(Bytes2, TrUserData), Rest2} end,
|
||||
dfp_read_field_def_sdl_register_super(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, F@_5, F@_6, TrUserData).
|
||||
dfp_read_field_def_sdl_register_super(RestF, 0, 0, F, F@_1, NewFValue, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData).
|
||||
|
||||
d_field_sdl_register_super_client_id(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) when N < 57 ->
|
||||
d_field_sdl_register_super_client_id(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
d_field_sdl_register_super_client_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, F@_5, F@_6, TrUserData) ->
|
||||
d_field_sdl_register_super_client_id(<<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_client_id(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_client_id(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, _, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) ->
|
||||
{NewFValue, RestF} = begin Len = X bsl N + Acc, <<Bytes:Len/binary, Rest2/binary>> = 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, NewFValue, F@_4, F@_5, F@_6, TrUserData).
|
||||
dfp_read_field_def_sdl_register_super(RestF, 0, 0, F, F@_1, F@_2, NewFValue, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData).
|
||||
|
||||
d_field_sdl_register_super_dev_addr(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) when N < 57 ->
|
||||
d_field_sdl_register_super_dev_addr(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
d_field_sdl_register_super_dev_addr(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, Prev, F@_5, F@_6, TrUserData) ->
|
||||
d_field_sdl_register_super_dev_addr(<<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_dev_addr(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_dev_addr(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, Prev, F@_5, F@_6, F@_7, F@_8, TrUserData) ->
|
||||
{NewFValue, RestF} = begin Len = X bsl N + Acc, <<Bs:Len/binary, Rest2/binary>> = Rest, {id(decode_msg_sdl_dev_addr(Bs, TrUserData), TrUserData), Rest2} end,
|
||||
dfp_read_field_def_sdl_register_super(RestF,
|
||||
0,
|
||||
@ -1314,35 +1360,51 @@ d_field_sdl_register_super_dev_addr(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1,
|
||||
end,
|
||||
F@_5,
|
||||
F@_6,
|
||||
F@_7,
|
||||
F@_8,
|
||||
TrUserData).
|
||||
|
||||
d_field_sdl_register_super_pub_key(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) when N < 57 -> d_field_sdl_register_super_pub_key(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
d_field_sdl_register_super_pub_key(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, _, F@_6, TrUserData) ->
|
||||
d_field_sdl_register_super_pub_key(<<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_pub_key(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_pub_key(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, _, F@_6, F@_7, F@_8, TrUserData) ->
|
||||
{NewFValue, RestF} = begin Len = X bsl N + Acc, <<Bytes:Len/binary, Rest2/binary>> = 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, NewFValue, F@_6, TrUserData).
|
||||
dfp_read_field_def_sdl_register_super(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, NewFValue, F@_6, F@_7, F@_8, TrUserData).
|
||||
|
||||
d_field_sdl_register_super_token(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) when N < 57 -> d_field_sdl_register_super_token(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
d_field_sdl_register_super_token(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, _, TrUserData) ->
|
||||
d_field_sdl_register_super_token(<<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_token(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_token(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, _, F@_7, F@_8, TrUserData) ->
|
||||
{NewFValue, RestF} = begin Len = X bsl N + Acc, <<Bytes:Len/binary, Rest2/binary>> = 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, NewFValue, TrUserData).
|
||||
dfp_read_field_def_sdl_register_super(RestF, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, NewFValue, F@_7, F@_8, TrUserData).
|
||||
|
||||
skip_varint_sdl_register_super(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> skip_varint_sdl_register_super(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
skip_varint_sdl_register_super(<<0:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> dfp_read_field_def_sdl_register_super(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData).
|
||||
d_field_sdl_register_super_network_code(<<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_network_code(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_network_code(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, _, F@_8, TrUserData) ->
|
||||
{NewFValue, RestF} = begin Len = X bsl N + Acc, <<Bytes:Len/binary, Rest2/binary>> = 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).
|
||||
|
||||
skip_length_delimited_sdl_register_super(<<1:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) when N < 57 ->
|
||||
skip_length_delimited_sdl_register_super(Rest, N + 7, X bsl N + Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData);
|
||||
skip_length_delimited_sdl_register_super(<<0:1, X:7, Rest/binary>>, N, Acc, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, 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, <<Bytes:Len/binary, Rest2/binary>> = 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).
|
||||
|
||||
skip_varint_sdl_register_super(<<1:1, _:7, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) -> skip_varint_sdl_register_super(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData);
|
||||
skip_varint_sdl_register_super(<<0:1, _:7, Rest/binary>>, 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(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData).
|
||||
|
||||
skip_length_delimited_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 < 57 ->
|
||||
skip_length_delimited_sdl_register_super(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);
|
||||
skip_length_delimited_sdl_register_super(<<0: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) ->
|
||||
Length = X bsl N + Acc,
|
||||
<<_:Length/binary, Rest2/binary>> = Rest,
|
||||
dfp_read_field_def_sdl_register_super(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData).
|
||||
dfp_read_field_def_sdl_register_super(Rest2, 0, 0, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData).
|
||||
|
||||
skip_group_sdl_register_super(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) ->
|
||||
skip_group_sdl_register_super(Bin, _, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData) ->
|
||||
{_, Rest} = read_group(Bin, FNum),
|
||||
dfp_read_field_def_sdl_register_super(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData).
|
||||
dfp_read_field_def_sdl_register_super(Rest, 0, Z2, FNum, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData).
|
||||
|
||||
skip_32_sdl_register_super(<<_:32, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> dfp_read_field_def_sdl_register_super(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData).
|
||||
skip_32_sdl_register_super(<<_:32, Rest/binary>>, 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(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData).
|
||||
|
||||
skip_64_sdl_register_super(<<_:64, Rest/binary>>, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData) -> dfp_read_field_def_sdl_register_super(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, TrUserData).
|
||||
skip_64_sdl_register_super(<<_:64, Rest/binary>>, 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(Rest, Z1, Z2, F, F@_1, F@_2, F@_3, F@_4, F@_5, F@_6, F@_7, F@_8, TrUserData).
|
||||
|
||||
decode_msg_sdl_register_super_ack(Bin, TrUserData) -> dfp_read_field_def_sdl_register_super_ack(Bin, 0, 0, 0, id(undefined, TrUserData), id(<<>>, TrUserData), id(0, TrUserData), id(undefined, TrUserData), id(undefined, TrUserData), TrUserData).
|
||||
|
||||
@ -2523,7 +2585,8 @@ merge_msg_sdl_v6_info(#sdl_v6_info{port = PFport, v6 = PFv6}, #sdl_v6_info{port
|
||||
end}.
|
||||
|
||||
-compile({nowarn_unused_function,merge_msg_sdl_dev_addr/3}).
|
||||
merge_msg_sdl_dev_addr(#sdl_dev_addr{network_id = PFnetwork_id, mac = PFmac, net_addr = PFnet_addr, net_bit_len = PFnet_bit_len}, #sdl_dev_addr{network_id = NFnetwork_id, mac = NFmac, net_addr = NFnet_addr, net_bit_len = NFnet_bit_len}, _) ->
|
||||
merge_msg_sdl_dev_addr(#sdl_dev_addr{network_id = PFnetwork_id, mac = PFmac, net_addr = PFnet_addr, net_bit_len = PFnet_bit_len, network_domain = PFnetwork_domain},
|
||||
#sdl_dev_addr{network_id = NFnetwork_id, mac = NFmac, net_addr = NFnet_addr, net_bit_len = NFnet_bit_len, network_domain = NFnetwork_domain}, _) ->
|
||||
#sdl_dev_addr{network_id =
|
||||
if NFnetwork_id =:= undefined -> PFnetwork_id;
|
||||
true -> NFnetwork_id
|
||||
@ -2539,14 +2602,19 @@ merge_msg_sdl_dev_addr(#sdl_dev_addr{network_id = PFnetwork_id, mac = PFmac, net
|
||||
net_bit_len =
|
||||
if NFnet_bit_len =:= undefined -> PFnet_bit_len;
|
||||
true -> NFnet_bit_len
|
||||
end,
|
||||
network_domain =
|
||||
if NFnetwork_domain =:= undefined -> PFnetwork_domain;
|
||||
true -> NFnetwork_domain
|
||||
end}.
|
||||
|
||||
-compile({nowarn_unused_function,merge_msg_sdl_empty/3}).
|
||||
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},
|
||||
#sdl_register_super{version = NFversion, installed_channel = NFinstalled_channel, client_id = NFclient_id, dev_addr = NFdev_addr, pub_key = NFpub_key, token = NFtoken}, TrUserData) ->
|
||||
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,
|
||||
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
|
||||
@ -2571,6 +2639,14 @@ merge_msg_sdl_register_super(#sdl_register_super{version = PFversion, installed_
|
||||
token =
|
||||
if NFtoken =:= undefined -> PFtoken;
|
||||
true -> NFtoken
|
||||
end,
|
||||
network_code =
|
||||
if NFnetwork_code =:= undefined -> PFnetwork_code;
|
||||
true -> NFnetwork_code
|
||||
end,
|
||||
hostname =
|
||||
if NFhostname =:= undefined -> PFhostname;
|
||||
true -> NFhostname
|
||||
end}.
|
||||
|
||||
-compile({nowarn_unused_function,merge_msg_sdl_register_super_ack/3}).
|
||||
@ -2916,7 +2992,7 @@ v_submsg_sdl_dev_addr(Msg, Path, TrUserData) -> v_msg_sdl_dev_addr(Msg, Path, Tr
|
||||
|
||||
-compile({nowarn_unused_function,v_msg_sdl_dev_addr/3}).
|
||||
-dialyzer({nowarn_function,v_msg_sdl_dev_addr/3}).
|
||||
v_msg_sdl_dev_addr(#sdl_dev_addr{network_id = F1, mac = F2, net_addr = F3, net_bit_len = F4}, Path, TrUserData) ->
|
||||
v_msg_sdl_dev_addr(#sdl_dev_addr{network_id = F1, mac = F2, net_addr = F3, net_bit_len = F4, network_domain = F5}, Path, TrUserData) ->
|
||||
if F1 == undefined -> ok;
|
||||
true -> v_type_uint32(F1, [network_id | Path], TrUserData)
|
||||
end,
|
||||
@ -2929,6 +3005,9 @@ v_msg_sdl_dev_addr(#sdl_dev_addr{network_id = F1, mac = F2, net_addr = F3, net_b
|
||||
if F4 == undefined -> ok;
|
||||
true -> v_type_uint32(F4, [net_bit_len | Path], TrUserData)
|
||||
end,
|
||||
if F5 == undefined -> ok;
|
||||
true -> v_type_string(F5, [network_domain | Path], TrUserData)
|
||||
end,
|
||||
ok;
|
||||
v_msg_sdl_dev_addr(X, Path, _TrUserData) -> mk_type_error({expected_msg, sdl_dev_addr}, X, Path).
|
||||
|
||||
@ -2939,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}, 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,
|
||||
@ -2958,6 +3037,12 @@ v_msg_sdl_register_super(#sdl_register_super{version = F1, installed_channel = F
|
||||
if F6 == undefined -> ok;
|
||||
true -> v_type_string(F6, [token | Path], TrUserData)
|
||||
end,
|
||||
if F7 == undefined -> ok;
|
||||
true -> v_type_string(F7, [network_code | Path], TrUserData)
|
||||
end,
|
||||
if F8 == undefined -> ok;
|
||||
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).
|
||||
|
||||
@ -3294,7 +3379,8 @@ get_msg_defs() ->
|
||||
[#field{name = network_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []},
|
||||
#field{name = mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []},
|
||||
#field{name = net_addr, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []},
|
||||
#field{name = net_bit_len, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []}]},
|
||||
#field{name = net_bit_len, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []},
|
||||
#field{name = network_domain, fnum = 5, rnum = 6, type = string, occurrence = defaulty, opts = []}]},
|
||||
{{msg, sdl_empty}, []},
|
||||
{{msg, sdl_register_super},
|
||||
[#field{name = version, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []},
|
||||
@ -3302,7 +3388,9 @@ get_msg_defs() ->
|
||||
#field{name = client_id, fnum = 3, rnum = 4, type = string, occurrence = defaulty, opts = []},
|
||||
#field{name = dev_addr, fnum = 4, rnum = 5, type = {msg, sdl_dev_addr}, occurrence = defaulty, opts = []},
|
||||
#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 = 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 = 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 = []},
|
||||
@ -3436,7 +3524,8 @@ find_msg_def(sdl_dev_addr) ->
|
||||
[#field{name = network_id, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []},
|
||||
#field{name = mac, fnum = 2, rnum = 3, type = bytes, occurrence = defaulty, opts = []},
|
||||
#field{name = net_addr, fnum = 3, rnum = 4, type = uint32, occurrence = defaulty, opts = []},
|
||||
#field{name = net_bit_len, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []}];
|
||||
#field{name = net_bit_len, fnum = 4, rnum = 5, type = uint32, occurrence = defaulty, opts = []},
|
||||
#field{name = network_domain, fnum = 5, rnum = 6, type = string, occurrence = defaulty, opts = []}];
|
||||
find_msg_def(sdl_empty) -> [];
|
||||
find_msg_def(sdl_register_super) ->
|
||||
[#field{name = version, fnum = 1, rnum = 2, type = uint32, occurrence = defaulty, opts = []},
|
||||
@ -3444,7 +3533,9 @@ find_msg_def(sdl_register_super) ->
|
||||
#field{name = client_id, fnum = 3, rnum = 4, type = string, occurrence = defaulty, opts = []},
|
||||
#field{name = dev_addr, fnum = 4, rnum = 5, type = {msg, sdl_dev_addr}, occurrence = defaulty, opts = []},
|
||||
#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 = 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 = 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 = []},
|
||||
|
||||
@ -103,7 +103,7 @@ handle_info({udp, Sock, Ip, Port, <<?PACKET_STUN_REQUEST:8, Body/binary>>}, Stat
|
||||
|
||||
case sdlan_network:get_pid(NetworkId) of
|
||||
undefined ->
|
||||
lager:debug("call me here stun request 11: ~p", [NetworkId]),
|
||||
lager:debug("[sdlan_stun] stun_request network_id: ~p, client_id: ~p, not found", [NetworkId, ClientId]),
|
||||
{noreply, State};
|
||||
NetworkPid when is_pid(NetworkPid) ->
|
||||
sdlan_network:update_hole(NetworkPid, ClientId, Mac, {Ip, Port}, NatType, V6Info),
|
||||
@ -111,7 +111,7 @@ handle_info({udp, Sock, Ip, Port, <<?PACKET_STUN_REQUEST:8, Body/binary>>}, Stat
|
||||
cookie = Cookie
|
||||
}),
|
||||
ok = gen_udp:send(Sock, Ip, Port, <<?PACKET_STUN_REPLY, StunReply/binary>>),
|
||||
lager:debug("call me here stun request 12"),
|
||||
lager:debug("[sdlan_stun] stun_request network_id: ~p, client_id: ~p, hole: ~p", [NetworkId, ClientId, {Ip, Port}]),
|
||||
{noreply, State}
|
||||
end;
|
||||
|
||||
|
||||
@ -29,6 +29,14 @@ init([]) ->
|
||||
SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600},
|
||||
|
||||
Specs = [
|
||||
#{
|
||||
id => dns_proxy_sup,
|
||||
start => {dns_proxy_sup, start_link, []},
|
||||
restart => permanent,
|
||||
shutdown => 2000,
|
||||
type => supervisor,
|
||||
modules => ['dns_proxy_sup']
|
||||
},
|
||||
#{
|
||||
id => sdlan_network_coordinator,
|
||||
start => {sdlan_network_coordinator, start_link, []},
|
||||
|
||||
@ -23,6 +23,12 @@
|
||||
|
||||
% {stun_servers, [{'sdlan_stun:2:1', 1265}, {'sdlan_stun:2:2', 1266}]},
|
||||
|
||||
%% 公共的dns域名解析服务
|
||||
{public_dns_servers, [
|
||||
{{114, 114, 114, 114}, 53},
|
||||
{{8,8,8,8}, 53}
|
||||
]},
|
||||
|
||||
{pools, [
|
||||
%% mysql连接池配置
|
||||
{mysql_sdlan,
|
||||
@ -37,6 +43,11 @@
|
||||
{database, "sdlan"},
|
||||
{queries, [<<"set names utf8">>]}
|
||||
]
|
||||
},
|
||||
|
||||
{dns_resolver_pool,
|
||||
[{size, 20}, {max_overflow, 100}, {worker_module, dns_resolver}],
|
||||
[]
|
||||
}
|
||||
]},
|
||||
|
||||
|
||||
@ -23,6 +23,12 @@
|
||||
|
||||
% {stun_servers, [{'sdlan_stun:2:1', 1265}, {'sdlan_stun:2:2', 1266}]},
|
||||
|
||||
%% 公共的dns域名解析服务
|
||||
{public_dns_servers, [
|
||||
{{114, 114, 114, 114}, 53},
|
||||
{{8,8,8,8}, 53}
|
||||
]},
|
||||
|
||||
{pools, [
|
||||
%% mysql连接池配置
|
||||
{mysql_sdlan,
|
||||
@ -37,7 +43,13 @@
|
||||
{database, "sdlan"},
|
||||
{queries, [<<"set names utf8">>]}
|
||||
]
|
||||
},
|
||||
|
||||
{dns_resolver_pool,
|
||||
[{size, 20}, {max_overflow, 100}, {worker_module, dns_resolver}],
|
||||
[]
|
||||
}
|
||||
|
||||
]},
|
||||
|
||||
{api_url, "https://punchnet.aioe.tech/api/"}
|
||||
|
||||
@ -19,6 +19,7 @@ message SDLDevAddr {
|
||||
bytes mac = 2;
|
||||
uint32 net_addr = 3;
|
||||
uint32 net_bit_len = 4;
|
||||
string network_domain = 5;
|
||||
}
|
||||
|
||||
// tcp通讯消息
|
||||
@ -33,6 +34,8 @@ message SDLRegisterSuper {
|
||||
SDLDevAddr dev_addr = 4;
|
||||
string pub_key = 5;
|
||||
string token = 6;
|
||||
string network_code = 7;
|
||||
string hostname = 8;
|
||||
}
|
||||
|
||||
message SDLRegisterSuperAck {
|
||||
|
||||
@ -2,13 +2,14 @@
|
||||
{deps, [
|
||||
{poolboy, ".*", {git, "https://github.com/devinus/poolboy.git", {tag, "1.5.1"}}},
|
||||
{hackney, ".*", {git, "https://github.com/benoitc/hackney.git", {tag, "1.16.0"}}},
|
||||
{sync, ".*", {git, "https://github.com/rustyio/sync.git", {branch, "master"}}},
|
||||
{esockd, ".*", {git, "https://github.com/emqx/esockd.git", {tag, "v5.7.3"}}},
|
||||
{jiffy, ".*", {git, "https://github.com/davisp/jiffy.git", {tag, "1.1.1"}}},
|
||||
{cowboy, ".*", {git, "https://github.com/ninenines/cowboy.git", {tag, "2.12.0"}}},
|
||||
{mysql, ".*", {git, "https://github.com/mysql-otp/mysql-otp", {tag, "1.8.0"}}},
|
||||
{gpb, ".*", {git, "https://github.com/tomas-abrahamsson/gpb.git", {tag, "4.21.1"}}},
|
||||
{throttle, ".*", {git, "https://github.com/lambdaclass/throttle.git", {tag, "0.3.0"}}},
|
||||
{dns_erlang, ".*", {git, "https://github.com/dnsimple/dns_erlang.git", {tag, "v4.4.0"}}},
|
||||
{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"}}}
|
||||
]}.
|
||||
|
||||
21
rebar.lock
21
rebar.lock
@ -1,5 +1,6 @@
|
||||
{"1.2.0",
|
||||
[{<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.2">>},1},
|
||||
[{<<"base32">>,{pkg,<<"base32">>,<<"1.0.0">>},2},
|
||||
{<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.2">>},1},
|
||||
{<<"cowboy">>,
|
||||
{git,"https://github.com/ninenines/cowboy.git",
|
||||
{ref,"3ea8395eb8f53a57acb5d3c00b99c70296e7cdbd"}},
|
||||
@ -8,9 +9,13 @@
|
||||
{git,"https://github.com/ninenines/cowlib",
|
||||
{ref,"1eb7f4293a652adcfe43b1835d22c58d8def839f"}},
|
||||
1},
|
||||
{<<"esockd">>,
|
||||
{git,"https://github.com/emqx/esockd.git",
|
||||
{ref,"d9ce4024cc42a65e9a05001997031e743442f955"}},
|
||||
{<<"dns_erlang">>,
|
||||
{git,"https://github.com/dnsimple/dns_erlang.git",
|
||||
{ref,"e1149a2dd6f49c6560aa245bc6f3d40a5cbe70e1"}},
|
||||
1},
|
||||
{<<"dns_proxy">>,
|
||||
{git,"https://gitea.s5s8.com/anlicheng/dns_proxy.git",
|
||||
{ref,"5ed832359e42ec99d148bf2ada1729b540017ab8"}},
|
||||
0},
|
||||
{<<"fs">>,{pkg,<<"fs">>,<<"6.1.1">>},1},
|
||||
{<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.9">>},1},
|
||||
@ -41,6 +46,10 @@
|
||||
{git,"https://github.com/uwiger/parse_trans",
|
||||
{ref,"6f3645afb43c7c57d61b54ef59aecab288ce1013"}},
|
||||
0},
|
||||
{<<"pkt">>,
|
||||
{git,"https://github.com/msantos/pkt.git",
|
||||
{ref,"67a4a14f596fded5ad5f2d8f94318faa8ad2c288"}},
|
||||
1},
|
||||
{<<"poolboy">>,
|
||||
{git,"https://github.com/devinus/poolboy.git",
|
||||
{ref,"3bb48a893ff5598f7c73731ac17545206d259fac"}},
|
||||
@ -52,7 +61,7 @@
|
||||
{<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.6">>},1},
|
||||
{<<"sync">>,
|
||||
{git,"https://github.com/rustyio/sync.git",
|
||||
{ref,"7dc303ed4ce8d26db82e171dbbd7c41067852c65"}},
|
||||
{ref,"4e909f69d3d0db21a6d7128b20748819e415c9eb"}},
|
||||
0},
|
||||
{<<"throttle">>,
|
||||
{git,"https://github.com/lambdaclass/throttle.git",
|
||||
@ -61,6 +70,7 @@
|
||||
{<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.5.0">>},2}]}.
|
||||
[
|
||||
{pkg_hash,[
|
||||
{<<"base32">>, <<"1AB331F812FCC254C8F7D4348E1E5A6F2B9B32B7A260BF2BC3358E3BF14C841A">>},
|
||||
{<<"certifi">>, <<"B7CFEAE9D2ED395695DD8201C57A2D019C0C43ECAF8B8BCB9320B40D6662F340">>},
|
||||
{<<"fs">>, <<"9D147B944D60CFA48A349F12D06C8EE71128F610C90870BDF9A6773206452ED0">>},
|
||||
{<<"goldrush">>, <<"F06E5D5F1277DA5C413E84D5A2924174182FB108DABB39D5EC548B27424CD106">>},
|
||||
@ -70,6 +80,7 @@
|
||||
{<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>},
|
||||
{<<"unicode_util_compat">>, <<"8516502659002CEC19E244EBD90D312183064BE95025A319A6C7E89F4BCCD65B">>}]},
|
||||
{pkg_hash_ext,[
|
||||
{<<"base32">>, <<"0449285348ED0C4CD83C7198E76C5FD5A0451C4EF18695B9FD43792A503E551A">>},
|
||||
{<<"certifi">>, <<"3B3B5F36493004AC3455966991EAF6E768CE9884693D9968055AEEEB1E575040">>},
|
||||
{<<"fs">>, <<"EF94E95FFE79916860649FED80AC62B04C322B0BB70F5128144C026B4D171F8B">>},
|
||||
{<<"goldrush">>, <<"99CB4128CFFCB3227581E5D4D803D5413FA643F4EB96523F77D9E6937D994CEB">>},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user