diff --git a/src/dns_proxy/dns_server_sup.erl b/src/dns_proxy/dns_server_sup.erl index 9d26ef8..0d54814 100644 --- a/src/dns_proxy/dns_server_sup.erl +++ b/src/dns_proxy/dns_server_sup.erl @@ -12,6 +12,7 @@ -define(SERVER, ?MODULE). +-spec start_link() -> supervisor:startlink_ret(). start_link() -> supervisor:start_link({local, ?SERVER}, ?MODULE, []). @@ -23,7 +24,9 @@ start_link() -> %% restart => restart(), % optional %% shutdown => shutdown(), % optional %% type => worker(), % optional -%% modules => modules()} % optional +-spec init(Args :: term()) -> + {ok, {SupFlags :: supervisor:sup_flags(), [ChildSpec :: supervisor:child_spec()]}} + | ignore. init([]) -> SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600}, Port = 15353, @@ -40,4 +43,4 @@ init([]) -> modules => ['dns_server'] } end, lists:seq(1, AcceptorNum)), - {ok, {SupFlags, Specs}}. \ No newline at end of file + {ok, {SupFlags, Specs}}. diff --git a/src/dns_proxy/dns_utils.erl b/src/dns_proxy/dns_utils.erl index 3dc81e6..5a64c00 100644 --- a/src/dns_proxy/dns_utils.erl +++ b/src/dns_proxy/dns_utils.erl @@ -112,6 +112,7 @@ ip_checksum(#ipv4{hl = HL, tos = ToS, len = Len, CheckSum end. +-spec test() -> term(). 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>>, @@ -128,4 +129,4 @@ test() -> logger:debug("ip_sum: ~p, =: ~p, udp: ~p, checkSum: ~p, =: ~p", [IpSum, ip_checksum(IPPacket), UDP, CheckSum, X]), - dns:decode_message(UDPPayload). \ No newline at end of file + dns:decode_message(UDPPayload). diff --git a/src/http/api_handler.erl b/src/http/api_handler.erl index 2d2b6d2..b3a2c89 100644 --- a/src/http/api_handler.erl +++ b/src/http/api_handler.erl @@ -17,6 +17,8 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% 重新加载对应的主机信息 +-spec handle_request(Method :: string(), Path :: string(), GetParams :: map(), PostParams :: map()) -> + {ok, StatusCode :: non_neg_integer(), Body :: iodata()}. handle_request("POST", "/test/auth_token", _, PostParams) -> logger:debug("[test_handler] get post params: ~p", [PostParams]), [Id | _] = network_bo:get_all_networks(), @@ -31,4 +33,4 @@ handle_request(_, Path, _, _) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% helper methods -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ No newline at end of file +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/http/binlog_handler.erl b/src/http/binlog_handler.erl index e5d3bd1..788a4d2 100644 --- a/src/http/binlog_handler.erl +++ b/src/http/binlog_handler.erl @@ -17,6 +17,8 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% 重新加载对应的主机信息 +-spec handle_request(Method :: string(), Path :: string(), GetParams :: map(), PostParams :: map()) -> + {ok, StatusCode :: non_neg_integer(), Body :: iodata()}. handle_request("POST", "/binlog", _, PostParams) -> logger:debug("[binlog_handler] get post params: ~p", [PostParams]), {ok, 200, sdlan_util:json_data(<<"ok">>)}; @@ -27,4 +29,4 @@ handle_request(_, Path, _, _) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% helper methods -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ No newline at end of file +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/http/http_protocol.erl b/src/http/http_protocol.erl index b24140d..b01a687 100644 --- a/src/http/http_protocol.erl +++ b/src/http/http_protocol.erl @@ -12,6 +12,7 @@ %% API -export([init/2]). +-spec init(Req :: cowboy_req:req(), Opts :: [module()]) -> {ok, cowboy_req:req(), [module()]}. init(Req0, Opts = [Mod|_]) -> Method = binary_to_list(cowboy_req:method(Req0)), Path = binary_to_list(cowboy_req:path(Req0)), @@ -86,4 +87,4 @@ read_body(Req, AccData) -> {ok, <>, Req1}; {more, Data, Req1} -> read_body(Req1, <>) - end. \ No newline at end of file + end. diff --git a/src/http/network_handler.erl b/src/http/network_handler.erl index da04d2a..ec49602 100644 --- a/src/http/network_handler.erl +++ b/src/http/network_handler.erl @@ -13,6 +13,8 @@ %% API -export([handle_request/4]). +-spec handle_request(Method :: string(), Path :: string(), GetParams :: map(), PostParams :: map()) -> + {ok, StatusCode :: non_neg_integer(), Body :: iodata()}. handle_request("POST", "/network/create", _, #{<<"id">> := NetworkId}) when NetworkId > 0 -> case sdlan_network_sup:ensure_network_started(NetworkId) of {ok, Pid} when is_pid(Pid) -> @@ -67,4 +69,4 @@ handle_request("POST", "/network/exit_node_control", _, #{<<"id">> := NetworkId, handle_request(_, Path, _, _) -> Path1 = list_to_binary(Path), - {ok, 200, sdlan_util:json_error(-1, <<"url: ", Path1/binary, " not found">>)}. \ No newline at end of file + {ok, 200, sdlan_util:json_error(-1, <<"url: ", Path1/binary, " not found">>)}. diff --git a/src/http/node_handler.erl b/src/http/node_handler.erl index 7684494..58801d2 100644 --- a/src/http/node_handler.erl +++ b/src/http/node_handler.erl @@ -12,6 +12,8 @@ %% API -export([handle_request/4]). +-spec handle_request(Method :: string(), Path :: string(), GetParams :: map(), PostParams :: map()) -> + {ok, StatusCode :: non_neg_integer(), Body :: iodata()}. handle_request("POST", "/node/disable", _, #{<<"network_id">> := NetworkId, <<"client_id">> := ClientId}) when NetworkId > 0 -> case sdlan_network:get_pid(NetworkId) of undefined -> @@ -23,4 +25,4 @@ handle_request("POST", "/node/disable", _, #{<<"network_id">> := NetworkId, <<"c handle_request(_, Path, _, _) -> Path1 = list_to_binary(Path), - {ok, 200, sdlan_util:json_error(-1, <<"url: ", Path1/binary, " not found">>)}. \ No newline at end of file + {ok, 200, sdlan_util:json_error(-1, <<"url: ", Path1/binary, " not found">>)}. diff --git a/src/http/sdlan_http_server.erl b/src/http/sdlan_http_server.erl index cca72a8..2e755fc 100644 --- a/src/http/sdlan_http_server.erl +++ b/src/http/sdlan_http_server.erl @@ -13,6 +13,7 @@ -export([start/0]). %% 启动http服务 +-spec start() -> ok. start() -> {ok, Props} = application:get_env(sdlan, http_server), Acceptors = proplists:get_value(acceptors, Props, 50), @@ -37,4 +38,4 @@ start() -> {max_connections, MaxConnections} ], {ok, Pid} = cowboy:start_clear(http_listener, TransOpts, #{env => #{dispatch => Dispatcher}}), - logger:debug("[iot_app] the http server start at: ~p, pid is: ~p", [Port, Pid]). \ No newline at end of file + logger:debug("[iot_app] the http server start at: ~p, pid is: ~p", [Port, Pid]). diff --git a/src/http/test_handler.erl b/src/http/test_handler.erl index e5736ab..612d0d9 100644 --- a/src/http/test_handler.erl +++ b/src/http/test_handler.erl @@ -17,6 +17,8 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% 重新加载对应的主机信息 +-spec handle_request(Method :: string(), Path :: string(), GetParams :: map(), PostParams :: map()) -> + {ok, StatusCode :: non_neg_integer(), Body :: iodata()}. handle_request("POST", "/test/auth_access_token", _, _PostParams) -> {ok, 200, sdlan_util:json_data(<<"ok">>)}; @@ -46,4 +48,4 @@ handle_request(_, Path, _, _) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% helper methods -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ No newline at end of file +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/ipv6_assist/ipv6_assist_server_sup.erl b/src/ipv6_assist/ipv6_assist_server_sup.erl index 4c83fd2..3f73ed8 100644 --- a/src/ipv6_assist/ipv6_assist_server_sup.erl +++ b/src/ipv6_assist/ipv6_assist_server_sup.erl @@ -12,9 +12,13 @@ -define(SERVER, ?MODULE). +-spec start_link() -> supervisor:startlink_ret(). start_link() -> supervisor:start_link({local, ?SERVER}, ?MODULE, []). +-spec init(Args :: term()) -> + {ok, {SupFlags :: supervisor:sup_flags(), [ChildSpec :: supervisor:child_spec()]}} + | ignore. init([]) -> SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600}, {ok, Props} = application:get_env(sdlan, ipv6_assist), diff --git a/src/policy/identity_policy_ets.erl b/src/policy/identity_policy_ets.erl index 37f0881..de69c9a 100644 --- a/src/policy/identity_policy_ets.erl +++ b/src/policy/identity_policy_ets.erl @@ -4,6 +4,7 @@ -export([init/0]). -export([get_policies/1, insert/1, delete/1, update/2]). +-spec init() -> ets:tab(). init() -> ets:new(identity_policy, [named_table, bag, public, {keypos, 2}, {read_concurrency, true}]). @@ -12,18 +13,21 @@ get_policies(IdentityId) when is_integer(IdentityId) -> Records = ets:lookup(identity_policy, IdentityId), lists:map(fun(#identity_policy{policy_id = PolicyId}) -> PolicyId end, Records). +-spec insert(map() | #identity_policy{}) -> true. insert(#{<<"identity_id">> := IdentityId, <<"policy_id">> := PolicyId}) -> insert(#identity_policy{identity_id = IdentityId, policy_id = PolicyId}); insert(IdentityPolicy=#identity_policy{}) -> true = ets:insert(identity_policy, IdentityPolicy). +-spec delete(map() | #identity_policy{}) -> true. delete(#{<<"identity_id">> := IdentityId, <<"policy_id">> := PolicyId}) -> ets:delete_object(identity_policy, #identity_policy{identity_id = IdentityId, policy_id = PolicyId}); delete(IdentityPolicy = #identity_policy{}) -> true = ets:delete_object(identity_policy, IdentityPolicy). +-spec update(NewData :: map(), OldData :: map()) -> true. update(NewData=#{<<"identity_id">> := IdentityId, <<"policy_id">> := PolicyId}, OldData) -> %% 清理老的数据 #{<<"identity_id">> := OldIdentityId, <<"policy_id">> := OldPolicyId} = maps:merge(NewData, OldData), ets:delete_object(identity_policy, #identity_policy{identity_id = OldIdentityId, policy_id = OldPolicyId}), - ets:insert(identity_policy, #identity_policy{identity_id = IdentityId, policy_id = PolicyId}). \ No newline at end of file + ets:insert(identity_policy, #identity_policy{identity_id = IdentityId, policy_id = PolicyId}). diff --git a/src/policy/maxwell_redis_channel.erl b/src/policy/maxwell_redis_channel.erl index 02e2ade..4040a9a 100644 --- a/src/policy/maxwell_redis_channel.erl +++ b/src/policy/maxwell_redis_channel.erl @@ -29,9 +29,11 @@ %% esockd callback %%-------------------------------------------------------------------- +-spec start(Socket :: inet:socket()) -> pid(). start(Socket) -> spawn(?MODULE, loop, [#state{socket = Socket, command = #command{}}]). +-spec loop(State :: #state{}) -> no_return(). loop(State=#state{socket = Socket, command = Command = #command{data = Data}}) -> inet:setopts(Socket, [{active, once}]), receive diff --git a/src/policy/maxwell_redis_server.erl b/src/policy/maxwell_redis_server.erl index ad994e5..bc6ff4f 100644 --- a/src/policy/maxwell_redis_server.erl +++ b/src/policy/maxwell_redis_server.erl @@ -16,9 +16,11 @@ %% esockd callback %%-------------------------------------------------------------------- +-spec start_link(Port :: inet:port_number()) -> {ok, pid()}. start_link(Port) when is_integer(Port) -> {ok, spawn_link(?MODULE, init, [Port])}. +-spec init(Port :: inet:port_number()) -> no_return(). init(Port) -> {ok, LSocket} = gen_tcp:listen(Port, [ binary, @@ -42,4 +44,4 @@ accept_loop(LSocket) -> {error, Reason} -> logger:debug("[maxwell_redis_server] Accept error: ~p~n", [Reason]), accept_loop(LSocket) - end. \ No newline at end of file + end. diff --git a/src/policy/rule_ets.erl b/src/policy/rule_ets.erl index 9c99088..f3c8c85 100644 --- a/src/policy/rule_ets.erl +++ b/src/policy/rule_ets.erl @@ -4,6 +4,7 @@ -export([init/0]). -export([insert/1, get_rules/2, delete/1, update/2]). +-spec init() -> ets:tab(). init() -> ets:new(rule_table, [named_table, ordered_set, public, {keypos, 2}, {read_concurrency, true}]), ets:new(rule_index, [named_table, bag, public, {read_concurrency, true}]). @@ -25,6 +26,7 @@ get_rules(SrcPolicyIds, DstPolicyIds) when is_list(SrcPolicyIds), is_list(DstPol {ok, sets:to_list(S)}. +-spec insert(Data :: map()) -> true. insert(#{<<"rule_id">> := RuleId, <<"network_id">> := NetworkId, <<"src_policy_id">> := SrcPolicyId, <<"dst_policy_id">> := DstPolicyId, <<"proto">> := Proto, <<"port">> := Port, <<"action">> := Action, <<"created_at">> := CreatedAt}) -> @@ -41,6 +43,7 @@ insert(#{<<"rule_id">> := RuleId, <<"network_id">> := NetworkId, ets:insert(rule_table, Rule), ets:insert(rule_index, {SrcPolicyId, DstPolicyId, RuleId}). +-spec update(NewData :: map(), OldData :: map()) -> true. update(NewData = #{<<"rule_id">> := RuleId, <<"network_id">> := NetworkId, <<"src_policy_id">> := SrcPolicyId, <<"dst_policy_id">> := DstPolicyId, <<"proto">> := Proto, <<"port">> := Port, <<"action">> := Action, <<"created_at">> := CreatedAt}, OldData) -> @@ -63,6 +66,7 @@ update(NewData = #{<<"rule_id">> := RuleId, <<"network_id">> := NetworkId, %% 建立信息的索引 ets:insert(rule_index, {SrcPolicyId, DstPolicyId, RuleId}). +-spec delete(Data :: map()) -> true. delete(#{<<"rule_id">> := RuleId, <<"src_policy_id">> := SrcPolicyId, <<"dst_policy_id">> := DstPolicyId}) -> ets:delete(rule_table, RuleId), ets:delete_object(rule_index, {SrcPolicyId, DstPolicyId, RuleId}). @@ -71,4 +75,4 @@ delete(#{<<"rule_id">> := RuleId, <<"src_policy_id">> := SrcPolicyId, <<"dst_pol format_action(<<"allow">>) -> allow; format_action(_) -> - deny. \ No newline at end of file + deny. diff --git a/src/quic/sdlan_quic_channel.erl b/src/quic/sdlan_quic_channel.erl index 7b933b9..8cc3cb1 100644 --- a/src/quic/sdlan_quic_channel.erl +++ b/src/quic/sdlan_quic_channel.erl @@ -18,17 +18,19 @@ %%%=================================================================== %% 测试规则函数 +-spec test_rules(SrcIdentityId :: integer(), DstIdentityId :: integer()) -> binary(). test_rules(SrcIdentityId, DstIdentityId) when is_integer(SrcIdentityId), is_integer(DstIdentityId) -> sdlan_session:test_rules(SrcIdentityId, DstIdentityId). --spec send_event(Pid :: pid(), Event :: binary()) -> no_return(). +-spec send_event(Pid :: pid(), Event :: binary()) -> ok. send_event(Pid, ProtobufEvent) when is_pid(Pid), is_binary(ProtobufEvent) -> sdlan_quic_transport:send_event(Pid, ProtobufEvent). --spec command(Pid :: pid(), Ref :: reference(), ReceiverPid :: pid(), {Tag :: atom(), SubCommand :: any()}) -> no_return(). +-spec command(Pid :: pid(), Ref :: reference(), ReceiverPid :: pid(), {Tag :: atom(), SubCommand :: any()}) -> ok. command(Pid, Ref, ReceiverPid, SubCommand) when is_pid(Pid), is_pid(ReceiverPid) -> sdlan_quic_transport:command(Pid, Ref, ReceiverPid, SubCommand). +-spec accept_stream(Pid :: pid()) -> ok. accept_stream(Pid) when is_pid(Pid) -> sdlan_quic_transport:accept_stream(Pid). @@ -36,9 +38,11 @@ accept_stream(Pid) when is_pid(Pid) -> stop(Pid, Reason) when is_pid(Pid) -> sdlan_quic_transport:stop(Pid, Reason). +-spec debug_info(Pid :: pid()) -> map(). debug_info(Pid) when is_pid(Pid) -> sdlan_quic_transport:debug_info(Pid). %% @doc Creates a transport process. Kept for existing supervisor specs. +-spec start_link(Conn :: quicer:connection_handle(), Limits :: proplists:proplist()) -> gen_statem:start_ret(). start_link(Conn, Limits) when is_list(Limits) -> sdlan_quic_transport:start_link(Conn, Limits). diff --git a/src/quic/sdlan_quic_server.erl b/src/quic/sdlan_quic_server.erl index 203d62e..c3b3bd4 100644 --- a/src/quic/sdlan_quic_server.erl +++ b/src/quic/sdlan_quic_server.erl @@ -12,9 +12,11 @@ %% API -export([start_link/0, init/0]). +-spec start_link() -> {ok, pid()}. start_link() -> {ok, spawn_link(?MODULE, init, [])}. +-spec init() -> ok. init() -> process_flag(trap_exit, true), {ok, Props} = application:get_env(sdlan, quic_server), diff --git a/src/quic/sdlan_quic_transport.erl b/src/quic/sdlan_quic_transport.erl index d4c5af2..0f09b77 100644 --- a/src/quic/sdlan_quic_transport.erl +++ b/src/quic/sdlan_quic_transport.erl @@ -43,14 +43,15 @@ %%% API %%%=================================================================== --spec send_event(Pid :: pid(), Event :: binary()) -> no_return(). +-spec send_event(Pid :: pid(), Event :: binary()) -> ok. send_event(Pid, ProtobufEvent) when is_pid(Pid), is_binary(ProtobufEvent) -> gen_statem:cast(Pid, {send_event, ProtobufEvent}). --spec command(Pid :: pid(), Ref :: reference(), ReceiverPid :: pid(), {Tag :: atom(), SubCommand :: any()}) -> no_return(). +-spec command(Pid :: pid(), Ref :: reference(), ReceiverPid :: pid(), {Tag :: atom(), SubCommand :: any()}) -> ok. command(Pid, Ref, ReceiverPid, SubCommand) when is_pid(Pid), is_pid(ReceiverPid) -> gen_statem:cast(Pid, {command, Ref, ReceiverPid, SubCommand}). +-spec accept_stream(Pid :: pid()) -> ok. accept_stream(Pid) when is_pid(Pid) -> gen_statem:cast(Pid, accept_stream). @@ -58,12 +59,14 @@ accept_stream(Pid) when is_pid(Pid) -> stop(Pid, Reason) when is_pid(Pid) -> gen_statem:stop(Pid, Reason, 2000). +-spec debug_info(Pid :: pid()) -> map(). debug_info(Pid) when is_pid(Pid) -> gen_statem:call(Pid, debug_info). %% @doc Creates a gen_statem process which calls Module:init/1 to %% initialize. To ensure a synchronized start-up procedure, this %% function does not return until Module:init/1 has returned. +-spec start_link(Conn :: quicer:connection_handle(), Limits :: proplists:proplist()) -> gen_statem:start_ret(). start_link(Conn, Limits) when is_list(Limits) -> gen_statem:start_link(?MODULE, [Conn, Limits], []). @@ -75,6 +78,7 @@ start_link(Conn, Limits) when is_list(Limits) -> %% @doc Whenever a gen_statem is started using gen_statem:start/[3,4] or %% gen_statem:start_link/[3,4], this function is called by the new %% process to initialize. +-spec init(Args :: term()) -> gen_statem:init_result(atom(), #state{}). init([Conn, Limits]) -> MaxPacketSize = proplists:get_value(max_packet_size, Limits, 16384), HeartbeatSec = proplists:get_value(heartbeat_sec, Limits, 15), @@ -91,6 +95,7 @@ init([Conn, Limits]) -> %% @private %% @doc This function is called by a gen_statem when it needs to find out %% the callback mode of the callback module. +-spec callback_mode() -> gen_statem:callback_mode_result(). callback_mode() -> handle_event_function. @@ -99,6 +104,8 @@ callback_mode() -> %% gen_statem receives an event from call/2, cast/2, or as a normal %% process message, this function is called. +-spec handle_event(EventType :: gen_statem:event_type(), EventContent :: term(), + StateName :: atom(), State :: #state{}) -> gen_statem:event_handler_result(atom(), #state{}). handle_event(cast, accept_stream, initializing, State = #state{conn = Conn, stream_active_n = StreamActiveN}) -> logger:debug("[sdlan_quic_transport] call do_init of conn: ~p", [Conn]), case quicer:async_accept_stream(Conn, #{active => StreamActiveN}) of @@ -219,6 +226,7 @@ handle_event(EventType, Info, StateName, State) -> %% terminate. It should be the opposite of Module:init/1 and do any %% necessary cleaning up. When it returns, the gen_statem terminates with %% Reason. The return value is ignored. +-spec terminate(Reason :: term(), StateName :: atom(), State :: #state{}) -> ok. terminate(Reason, _StateName, _State = #state{conn = Conn, stream = Stream, session = Session, close_reason = CloseReason}) -> Stream /= undefined andalso quicer:close_stream(Stream, 1000), quicer:close_connection(Conn), @@ -228,6 +236,8 @@ terminate(Reason, _StateName, _State = #state{conn = Conn, stream = Stream, sess %% @private %% @doc Convert process state when code is changed +-spec code_change(OldVsn :: term(), StateName :: atom(), State :: #state{}, Extra :: term()) -> + {ok, atom(), #state{}}. code_change(_OldVsn, StateName, State = #state{}, _Extra) -> {ok, StateName, State}. @@ -248,7 +258,7 @@ decode_frames0(<>, MaxPacketSize, Frames) decode_frames0(Rest, _MaxPacketSize, Frames) -> {ok, Rest, lists:reverse(Frames)}. --spec quic_send(Stream :: quicer:stream_handle(), Data :: iodata()) -> no_return(). +-spec quic_send(Stream :: quicer:stream_handle(), Data :: iodata()) -> ok. quic_send(_Stream, []) -> ok; quic_send(Stream, Data) -> diff --git a/src/sdlan_app.erl b/src/sdlan_app.erl index 4d0c3e1..058dc0a 100644 --- a/src/sdlan_app.erl +++ b/src/sdlan_app.erl @@ -9,6 +9,8 @@ -export([start/2, stop/1]). +-spec start(StartType :: application:start_type(), StartArgs :: term()) -> + {ok, pid()} | {ok, pid(), term()} | {error, term()}. start(_StartType, _StartArgs) -> io:setopts([{encoding, unicode}]), %% 加速内存的回收 @@ -38,7 +40,8 @@ start(_StartType, _StartArgs) -> sdlan_sup:start_link(). +-spec stop(State :: term()) -> ok. stop(_State) -> ok. -%% internal functions \ No newline at end of file +%% internal functions diff --git a/src/sdlan_cipher.erl b/src/sdlan_cipher.erl index 59a0484..4b8c56a 100644 --- a/src/sdlan_cipher.erl +++ b/src/sdlan_cipher.erl @@ -14,6 +14,7 @@ -export([aes_encrypt/3, aes_decrypt/3]). -export([test/0, test_chacha20/0]). +-spec test() -> ok. test() -> Key = <<"abcdabcdabcdabcd">>, X = aes_encrypt(Key, Key, <<"hello world">>), @@ -41,6 +42,7 @@ aes_decrypt(Key, IVec, CipherText) when is_binary(Key), is_binary(IVec), is_bina crypto:crypto_one_time(aes_128_ofb, Key, IVec, CipherText, [{encrypt, false}, {padding, pkcs_padding}]). +-spec test_chacha20() -> ok. test_chacha20() -> Key = crypto:strong_rand_bytes(32), Nonce = crypto:strong_rand_bytes(12), @@ -78,4 +80,4 @@ chacha20_decrypt(Key, <>) -> AAD, Tag, false - ). \ No newline at end of file + ). diff --git a/src/sdlan_domain_regedit.erl b/src/sdlan_domain_regedit.erl index dcefca0..d0692d5 100644 --- a/src/sdlan_domain_regedit.erl +++ b/src/sdlan_domain_regedit.erl @@ -14,6 +14,7 @@ -define(TABLE, sdlan_domain_regedit). +-spec init() -> ets:tab(). init() -> ets:new(?TABLE, [named_table, ordered_set, public, {read_concurrency, true}, {write_concurrency, true}]). diff --git a/src/sdlan_hostname_regedit.erl b/src/sdlan_hostname_regedit.erl index 843045c..d2ebfcd 100644 --- a/src/sdlan_hostname_regedit.erl +++ b/src/sdlan_hostname_regedit.erl @@ -14,6 +14,7 @@ -define(TABLE, sdlan_hostname_regedit). +-spec init() -> ets:tab(). init() -> ets:new(?TABLE, [named_table, set, public, {read_concurrency, true}, {write_concurrency, true}]). diff --git a/src/sdlan_network_sup.erl b/src/sdlan_network_sup.erl index 0e5bb57..62bbc25 100644 --- a/src/sdlan_network_sup.erl +++ b/src/sdlan_network_sup.erl @@ -38,6 +38,10 @@ start_link() -> %% this function is called by the new process to find out about %% restart strategy, maximum restart frequency and child %% specifications. +-spec init(Args :: term()) -> + {ok, {SupFlags :: supervisor:sup_flags(), [ChildSpec :: supervisor:child_spec()]}} + | ignore + | {stop, Reason :: term()}. init([]) -> SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600}, case sdlan_api:get_all_networks() of @@ -96,7 +100,7 @@ get_all_networks() -> lists:map(fun({_Id, ChildPid, _Type, _Modules}) -> ChildPid end, supervisor:which_children(?MODULE)). %% 重新分配网络带宽 --spec reallocate_bind_width() -> no_return(). +-spec reallocate_bind_width() -> term(). reallocate_bind_width() -> ChildPids = lists:map(fun({_Id, ChildPid, _Type, _Modules}) -> ChildPid end, supervisor:which_children(?MODULE)), set_network_bind(length(ChildPids)). diff --git a/src/sdlan_session.erl b/src/sdlan_session.erl index 43fe486..202047a 100644 --- a/src/sdlan_session.erl +++ b/src/sdlan_session.erl @@ -63,6 +63,7 @@ new(HeartbeatSec) -> #session{heartbeat_sec = HeartbeatSec}. %% 测试规则函数 +-spec test_rules(SrcIdentityId :: integer(), DstIdentityId :: integer()) -> binary(). test_rules(SrcIdentityId, DstIdentityId) when is_integer(SrcIdentityId), is_integer(DstIdentityId) -> {ok, Rules} = get_rules(SrcIdentityId, DstIdentityId), logger:debug("[sdlan_session] test_rules policy_request src_identity_id: ~p, dst_identity_id: ~p, rules: ~p", [SrcIdentityId, DstIdentityId, Rules]), @@ -371,4 +372,4 @@ stop_timeout_result(Reason, Session = #session{status = StateName}) -> heartbeat_ms(HeartbeatSec) when is_integer(HeartbeatSec), HeartbeatSec > 0 -> HeartbeatSec * 1000; heartbeat_ms(_) -> - ?PING_TICKER. \ No newline at end of file + ?PING_TICKER. diff --git a/src/sdlan_stun_sup.erl b/src/sdlan_stun_sup.erl index 06ceae7..3df2fde 100644 --- a/src/sdlan_stun_sup.erl +++ b/src/sdlan_stun_sup.erl @@ -12,6 +12,7 @@ -define(SERVER, ?MODULE). +-spec start_link() -> supervisor:startlink_ret(). start_link() -> supervisor:start_link({local, ?SERVER}, ?MODULE, []). @@ -23,7 +24,9 @@ start_link() -> %% restart => restart(), % optional %% shutdown => shutdown(), % optional %% type => worker(), % optional -%% modules => modules()} % optional +-spec init(Args :: term()) -> + {ok, {SupFlags :: supervisor:sup_flags(), [ChildSpec :: supervisor:child_spec()]}} + | ignore. init([]) -> SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600}, Specs = [ @@ -62,4 +65,4 @@ stun_acceptors() -> type => worker, modules => ['sdlan_stun'] } - end, lists:seq(1, AcceptorNums)). \ No newline at end of file + end, lists:seq(1, AcceptorNums)). diff --git a/src/sdlan_sup.erl b/src/sdlan_sup.erl index 72ed0b0..e61f5d4 100644 --- a/src/sdlan_sup.erl +++ b/src/sdlan_sup.erl @@ -13,6 +13,7 @@ -define(SERVER, ?MODULE). +-spec start_link() -> supervisor:startlink_ret(). start_link() -> supervisor:start_link({local, ?SERVER}, ?MODULE, []). @@ -24,7 +25,9 @@ start_link() -> %% restart => restart(), % optional %% shutdown => shutdown(), % optional %% type => worker(), % optional -%% modules => modules()} % optional +-spec init(Args :: term()) -> + {ok, {SupFlags :: supervisor:sup_flags(), [ChildSpec :: supervisor:child_spec()]}} + | ignore. init([]) -> SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600}, diff --git a/src/sdlan_sync_mysql.erl b/src/sdlan_sync_mysql.erl index 560ef4a..d5072ff 100644 --- a/src/sdlan_sync_mysql.erl +++ b/src/sdlan_sync_mysql.erl @@ -39,6 +39,7 @@ %% @doc Creates a gen_statem process which calls Module:init/1 to %% initialize. To ensure a synchronized start-up procedure, this %% function does not return until Module:init/1 has returned. +-spec start_link() -> gen_statem:start_ret(). start_link() -> gen_statem:start_link({local, ?MODULE}, ?MODULE, [], []). @@ -50,12 +51,14 @@ start_link() -> %% @doc Whenever a gen_statem is started using gen_statem:start/[3,4] or %% gen_statem:start_link/[3,4], this function is called by the new %% process to initialize. +-spec init(Args :: term()) -> gen_statem:init_result(atom(), #state{}). init([]) -> {ok, initializing, #state{}, [{next_event, internal, do_sync}]}. %% @private %% @doc This function is called by a gen_statem when it needs to find out %% the callback mode of the callback module. +-spec callback_mode() -> gen_statem:callback_mode_result(). callback_mode() -> handle_event_function. @@ -64,6 +67,8 @@ callback_mode() -> %% gen_statem receives an event from call/2, cast/2, or as a normal %% process message, this function is called. +-spec handle_event(EventType :: gen_statem:event_type(), EventContent :: term(), + StateName :: atom(), State :: #state{}) -> gen_statem:event_handler_result(atom(), #state{}). handle_event(internal, do_sync, initializing, State=#state{}) -> sync_identity_policy(), sync_rule(), @@ -74,12 +79,15 @@ handle_event(internal, do_sync, initializing, State=#state{}) -> %% terminate. It should be the opposite of Module:init/1 and do any %% necessary cleaning up. When it returns, the gen_statem terminates with %% Reason. The return value is ignored. +-spec terminate(Reason :: term(), StateName :: atom(), State :: #state{}) -> ok. terminate(Reason, _StateName, _State) -> logger:debug("[sdlan_sync_mysql] terminate with reason: ~p", [Reason]), ok. %% @private %% @doc Convert process state when code is changed +-spec code_change(OldVsn :: term(), StateName :: atom(), State :: #state{}, Extra :: term()) -> + {ok, atom(), #state{}}. code_change(_OldVsn, StateName, State = #state{}, _Extra) -> {ok, StateName, State}. @@ -106,4 +114,4 @@ sync_rule0(RuleIdOffset) -> sync_rule0(LastRuleOffset); false -> ok - end. \ No newline at end of file + end. diff --git a/src/sdlan_util.erl b/src/sdlan_util.erl index 52dcf39..82c2097 100644 --- a/src/sdlan_util.erl +++ b/src/sdlan_util.erl @@ -37,6 +37,7 @@ mac_str_to_bin(MacBin) when is_binary(MacBin) -> binary:decode_hex(HexBin2). %% 生成随机字节 +-spec rand_byte(Num :: pos_integer()) -> binary(). rand_byte(Num) when is_integer(Num), Num > 0 -> rand_byte0(Num, <<>>). rand_byte0(0, Acc) -> @@ -65,12 +66,15 @@ hex0(14) -> $e; hex0(15) -> $f; hex0(I) -> $0 + I. +-spec json_data(Data :: term()) -> iodata(). json_data(Data) -> jiffy:encode(#{<<"result">> => Data}, [force_utf8]). +-spec json_error(ErrCode :: integer(), ErrMessage :: binary()) -> iodata(). json_error(ErrCode, ErrMessage) when is_integer(ErrCode), is_binary(ErrMessage) -> jiffy:encode(#{<<"error">> => #{<<"code">> => ErrCode, <<"message">> => ErrMessage}}, [force_utf8]). +-spec assert_call(Condition :: boolean(), F :: fun(() -> T)) -> T | ok. assert_call(true, F) -> F(); assert_call(false, _) -> @@ -85,6 +89,7 @@ is_multicast_mac(Mac) when is_binary(Mac) -> binary:part(Mac, 0, 3) =:= <<16#01,16#00,16#5E>>. +-spec format_ip(Ip :: term()) -> term(). format_ip(Ip) when is_integer(Ip) -> int_to_ipv4(Ip); format_ip(Ip) -> @@ -163,5 +168,6 @@ hmac(Key, Data) when is_binary(Key), is_binary(Data) -> %% 转成十六进制小写字符串,和 PHP hash_hmac 一致 lists:flatten([io_lib:format("~2.16.0b", [B]) || B <- binary:bin_to_list(Digest)]). +-spec term_to_binary(Term :: term()) -> binary(). term_to_binary(Term) -> - iolist_to_binary(io_lib:format("~p", [Term])). \ No newline at end of file + iolist_to_binary(io_lib:format("~p", [Term])). diff --git a/src/ssl/sdlan_ssl_server.erl b/src/ssl/sdlan_ssl_server.erl index 77777f4..a9fc5ee 100644 --- a/src/ssl/sdlan_ssl_server.erl +++ b/src/ssl/sdlan_ssl_server.erl @@ -13,6 +13,7 @@ -export([start/0]). %% 启动ssl服务 +-spec start() -> ok. start() -> {ok, Props} = application:get_env(sdlan, ssl_server), Acceptors = proplists:get_value(acceptors, Props, 50), @@ -39,4 +40,4 @@ start() -> ] }, {ok, Pid} = ranch:start_listener(ssl_server, ranch_ssl, TransOpts, sdlan_ssl_transport, Limits), - logger:debug("[sdlan_ssl_server] the ssl server start at: ~p, pid is: ~p", [Port, Pid]). \ No newline at end of file + logger:debug("[sdlan_ssl_server] the ssl server start at: ~p, pid is: ~p", [Port, Pid]). diff --git a/src/ssl/sdlan_ssl_transport.erl b/src/ssl/sdlan_ssl_transport.erl index 582d949..2beed21 100644 --- a/src/ssl/sdlan_ssl_transport.erl +++ b/src/ssl/sdlan_ssl_transport.erl @@ -36,6 +36,8 @@ %%% Ranch protocol callback %%%=================================================================== +-spec start_link(Ref :: ranch:ref(), Socket :: inet:socket(), Transport :: module(), + Limits :: proplists:proplist()) -> gen_statem:start_ret(). start_link(Ref, Socket, Transport, Limits) -> gen_statem:start_link(?MODULE, [Ref, Socket, Transport, Limits], []). @@ -43,6 +45,7 @@ start_link(Ref, Socket, Transport, Limits) -> %%% gen_statem callbacks %%%=================================================================== +-spec init(Args :: term()) -> gen_statem:init_result(atom(), #state{}). init([Ref, Socket, Transport, Limits]) -> MaxPacketSize = proplists:get_value(max_packet_size, Limits, 16384), HeartbeatSec = proplists:get_value(heartbeat_sec, Limits, 15), @@ -56,9 +59,12 @@ init([Ref, Socket, Transport, Limits]) -> session = Session }}. +-spec callback_mode() -> gen_statem:callback_mode_result(). callback_mode() -> handle_event_function. +-spec handle_event(EventType :: gen_statem:event_type(), EventContent :: term(), + StateName :: atom(), State :: #state{}) -> gen_statem:event_handler_result(atom(), #state{}). handle_event(info, {handshake, Ref, Transport, Socket, Timeout}, handshaking, State = #state{ref = Ref, transport = Transport, max_packet_size = MaxPacketSize, heartbeat_sec = HeartbeatSec}) -> case Transport:handshake(Socket, [], Timeout) of @@ -123,12 +129,15 @@ handle_event(EventType, Info, StateName, State) -> logger:notice("[sdlan_ssl_transport] state: ~p, state_name: ~p, event_type: ~p, info: ~p", [State, StateName, EventType, Info]), keep_state_and_data. +-spec terminate(Reason :: term(), StateName :: atom(), State :: #state{}) -> ok. terminate(Reason, _StateName, #state{socket = Socket, transport = Transport, session = Session, close_reason = CloseReason}) -> Socket =/= undefined andalso catch Transport:close(Socket), logger:notice("[sdlan_ssl_transport] terminate closed with reason: ~p, close_reason: ~p", [Reason, CloseReason]), sdlan_session:close(Session), ok. +-spec code_change(OldVsn :: term(), StateName :: atom(), State :: #state{}, Extra :: term()) -> + {ok, atom(), #state{}}. code_change(_OldVsn, StateName, State = #state{}, _Extra) -> {ok, StateName, State}. diff --git a/src/test/test_ipv6_udp.erl b/src/test/test_ipv6_udp.erl index 7930056..e059584 100644 --- a/src/test/test_ipv6_udp.erl +++ b/src/test/test_ipv6_udp.erl @@ -12,6 +12,7 @@ %% API -export([test/0]). +-spec test() -> ok. test() -> Opts = [ binary, @@ -23,4 +24,4 @@ test() -> {sndbuf, 5 * 1024 * 1024} ], {ok, Socket} = gen_udp:open(0, Opts), - ok = gen_udp:send(Socket, "2408:4005:318:4900:164a:b5c6:9023:ca8d", 1367, <<"hello world">>). \ No newline at end of file + ok = gen_udp:send(Socket, "2408:4005:318:4900:164a:b5c6:9023:ca8d", 1367, <<"hello world">>).