From f45b5e4ed4e889ecd177561a50d3c0e9737a0c9f Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Fri, 13 Feb 2026 17:32:23 +0800 Subject: [PATCH] fix warning --- apps/sdlan/src/http_handler/file_handler.erl | 24 -- .../src/http_handler/network_handler.erl | 21 -- apps/sdlan/src/http_handler/node_handler.erl | 43 ---- apps/sdlan/src/mnesia/client_model.erl | 162 -------------- apps/sdlan/src/mnesia/mnesia_id_generator.erl | 26 --- apps/sdlan/src/mnesia/mnesia_manager.erl | 43 ---- apps/sdlan/src/quic/sdlan_quic_channel.erl | 2 +- apps/sdlan/src/quic/sdlan_quic_server.erl | 26 ++- apps/sdlan/src/sdlan_network.erl | 10 +- apps/sdlan/src/{quic => test}/quic_client.erl | 0 apps/sdlan/src/test/sdlan_quicer_test.erl | 20 -- apps/sdlan/src/test/sdlan_tcp_client.erl | 101 --------- apps/sdlan/src/test/sdlan_udp_downloader.erl | 110 --------- apps/sdlan/src/test/sdlan_udp_wget.erl | 114 ---------- apps/sdlan/src/test/stun_client.erl | 208 ------------------ 15 files changed, 19 insertions(+), 891 deletions(-) delete mode 100644 apps/sdlan/src/http_handler/file_handler.erl delete mode 100644 apps/sdlan/src/mnesia/client_model.erl delete mode 100644 apps/sdlan/src/mnesia/mnesia_id_generator.erl delete mode 100644 apps/sdlan/src/mnesia/mnesia_manager.erl rename apps/sdlan/src/{quic => test}/quic_client.erl (100%) delete mode 100644 apps/sdlan/src/test/sdlan_quicer_test.erl delete mode 100644 apps/sdlan/src/test/sdlan_tcp_client.erl delete mode 100644 apps/sdlan/src/test/sdlan_udp_downloader.erl delete mode 100644 apps/sdlan/src/test/sdlan_udp_wget.erl delete mode 100644 apps/sdlan/src/test/stun_client.erl diff --git a/apps/sdlan/src/http_handler/file_handler.erl b/apps/sdlan/src/http_handler/file_handler.erl deleted file mode 100644 index 838e385..0000000 --- a/apps/sdlan/src/http_handler/file_handler.erl +++ /dev/null @@ -1,24 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 09. 4月 2024 14:28 -%%%------------------------------------------------------------------- --module(file_handler). --author("anlicheng"). - -%% API --export([init/2]). - -init(Req, State) -> - %% 拼接得到文件的真实路径 - FullPath = "/tmp/files/test.dmg", - %% 使用cowboy_req:reply函数返回文件内容 - {ok, Content} = file:read_file(FullPath), - Req1 = cowboy_req:reply(200, #{ - <<"Content-Type">> => <<"application/octet-stream">> - }, Content, Req), - - {ok, Req1, State}. \ No newline at end of file diff --git a/apps/sdlan/src/http_handler/network_handler.erl b/apps/sdlan/src/http_handler/network_handler.erl index 3475723..49c939f 100644 --- a/apps/sdlan/src/http_handler/network_handler.erl +++ b/apps/sdlan/src/http_handler/network_handler.erl @@ -21,27 +21,6 @@ handle_request("POST", "/network/create", _, #{<<"id">> := NetworkId}) when Netw {ok, 200, sdlan_util:json_error(-1, <<"error">>)} end; -handle_request("POST", "/network/reload", _, #{<<"id">> := NetworkId}) when NetworkId > 0 -> - case sdlan_network:get_pid(NetworkId) of - undefined -> - case sdlan_network_sup:start_network(NetworkId) of - {ok, Pid} when is_pid(Pid) -> - sdlan_network_sup:reallocate_bind_width(), - {ok, 200, sdlan_util:json_data(<<"success">>)}; - {error, Reason} -> - logger:debug("[network_handler] start network: ~p, get error: ~p", [NetworkId, Reason]), - {ok, 200, sdlan_util:json_error(-1, <<"error">>)} - end; - NetworkPid when is_pid(NetworkPid) -> - case sdlan_network:reload(NetworkPid) of - ok -> - {ok, 200, sdlan_util:json_data(<<"success">>)}; - {error, Reason} -> - logger:debug("[network_handler] reload network: ~p, get error: ~p", [NetworkId, Reason]), - {ok, 200, sdlan_util:json_error(-1, <<"error">>)} - end - end; - handle_request("POST", "/network/delete", _, #{<<"id">> := NetworkId}) when NetworkId > 0 -> case sdlan_network:get_pid(NetworkId) of undefined -> diff --git a/apps/sdlan/src/http_handler/node_handler.erl b/apps/sdlan/src/http_handler/node_handler.erl index d00aff3..b353e93 100644 --- a/apps/sdlan/src/http_handler/node_handler.erl +++ b/apps/sdlan/src/http_handler/node_handler.erl @@ -15,23 +15,6 @@ %% API -export([handle_request/4]). -handle_request("POST", "/node/list", _, #{<<"network_id">> := NetworkId}) when NetworkId > 0 -> - Pid = sdlan_network:get_pid(NetworkId), - UsedMap = sdlan_network:get_used_map(Pid), - - Clients = client_model:get_clients(NetworkId), - ClientInfos = lists:map(fun(#client{client_id = ClientId, mac = Mac, ip = Ip, status = Status}) -> - Info = #{ - <<"client_id">> => ClientId, - <<"mac">> => Mac, - <<"ip">> => sdlan_ipaddr:int_to_ipv4(Ip), - <<"status">> => atom_to_binary(Status) - }, - maps:merge(Info, maps:get(Mac, UsedMap, #{})) - end, Clients), - - {ok, 200, sdlan_util:json_data(ClientInfos)}; - handle_request("POST", "/node/disable", _, #{<<"network_id">> := NetworkId, <<"client_id">> := ClientId}) when NetworkId > 0 -> case sdlan_network:get_pid(NetworkId) of undefined -> @@ -41,32 +24,6 @@ handle_request("POST", "/node/disable", _, #{<<"network_id">> := NetworkId, <<"c {ok, 200, sdlan_util:json_data(<<"success">>)} end; -handle_request("POST", "/node/move", _, #{<<"client_id">> := ClientId, <<"from_network_id">> := FromNetworkId, <<"to_network_id">> := ToNetworkId, <<"timeout">> := Timeout}) -> - 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, HostName} -> - Ref = sdlan_channel:move_network(ChannelPid, self(), ToPid, HostName), - receive - {command_reply, Ref, {error, Reason}} -> - logger:warning("[node_handler] client_id: ~p, move network from: ~p, to: ~p, get error: ~p", [ClientId, FromPid, ToPid, Reason]), - {ok, 200, sdlan_util:json_error(-1, <<"move failed">>)}; - {command_reply, Ref, #sdl_command_ack{status = true}} -> - {ok, 200, sdlan_util:json_data(<<"success">>)}; - {command_reply, Ref, #sdl_command_ack{status = false, message = ErrorMsg}} when is_binary(ErrorMsg) -> - {ok, 200, sdlan_util:json_error(-1, <<"move failed: ", ErrorMsg/binary>>)} - after Timeout * 1000 -> - {ok, 200, sdlan_util:json_error(-1, <<"move timeout">>)} - end; - error -> - {ok, 200, sdlan_util:json_error(-1, <<"dropout from from_network error">>)} - end; - {FromPid, undefined} when is_pid(FromPid) -> - {ok, 200, sdlan_util:json_error(-1, <<"to_network not found">>)}; - {undefined, ToPid} when is_pid(ToPid) -> - {ok, 200, sdlan_util:json_error(-1, <<"from_network not found">>)} - end; - 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 diff --git a/apps/sdlan/src/mnesia/client_model.erl b/apps/sdlan/src/mnesia/client_model.erl deleted file mode 100644 index edb7d9c..0000000 --- a/apps/sdlan/src/mnesia/client_model.erl +++ /dev/null @@ -1,162 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author aresei -%%% @copyright (C) 2023, -%%% @doc -%%% -%%% @end -%%% Created : 04. 7月 2023 12:31 -%%%------------------------------------------------------------------- --module(client_model). --author("aresei"). --include("sdlan_tables.hrl"). --include_lib("stdlib/include/qlc.hrl"). - -%% API --export([create_table/1, get_table_name/1]). --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) -> - mnesia:create_table(Tab, [ - {attributes, record_info(fields, client)}, - {record_name, client}, - {disc_copies, [node()]}, - {type, set} - ]). - --spec get_table_name(NetworkId :: integer()) -> TableName :: atom(). -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), - case mnesia:transaction(fun() -> mnesia:foldl(fun(R, Acc0) -> [R|Acc0] end, [], Tab) end) of - {'atomic', Items} -> - lists:reverse(Items); - {'aborted', _} -> - [] - end. - --spec delete_clients(NetworkId :: integer()) -> ok | {error, Reason :: any()}. -delete_clients(NetworkId) when is_integer(NetworkId) -> - Tab = get_table_name(NetworkId), - case mnesia:transaction(fun() -> mnesia:clear_table(Tab) end) of - {'atomic', ok} -> - ok; - {'aborted', Reason} -> - {error, Reason} - end. - --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), - - 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. - --spec disable_client(NetworkId :: integer(), ClientId :: binary()) -> ok | {error, Reason :: any()}. -disable_client(NetworkId, ClientId) when is_integer(NetworkId), is_binary(ClientId) -> - Tab = get_table_name(NetworkId), - Fun = fun() -> - case mnesia:read(Tab, ClientId, read) of - [] -> - ok; - [Client] -> - mnesia:write(Tab, Client#client{status = disabled}, write) - end - end, - - case mnesia:transaction(Fun) of - {'atomic', ok} -> - ok; - {'aborted', Reason} -> - {error, Reason} - end. - -%% 分配ip地址的时候,以mac地址为唯一基准 --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, 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, HostName) -> - Tab = get_table_name(NetworkId), - - case mnesia:read(Tab, ClientId) of - [Client=#client{ip = Ip, status = normal}] -> - ok = mnesia:write(Tab, Client#client{mac = Mac}, write), - Ip; - [#client{status = disabled}] -> - mnesia:abort(client_disabled); - [] -> - {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 -> - mnesia:abort(host_name_used); - false -> - 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), - 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. - -%%%=================================================================== -%%% helper functions -%%%=================================================================== - -debug(NetworkId) when is_integer(NetworkId) -> - Tab = get_table_name(NetworkId), - F = fun() -> - Q = qlc:q([E || E <- mnesia:table(Tab)]), - qlc:e(Q) - end, - case mnesia:transaction(F) of - {'atomic', Records} -> - lists:foreach(fun(C) -> logger:debug("client: ~p", [C]) end, Records); - {'aborted', Reason} -> - logger:warning("read clients get error: ~p", [Reason]) - end. \ No newline at end of file diff --git a/apps/sdlan/src/mnesia/mnesia_id_generator.erl b/apps/sdlan/src/mnesia/mnesia_id_generator.erl deleted file mode 100644 index cab8586..0000000 --- a/apps/sdlan/src/mnesia/mnesia_id_generator.erl +++ /dev/null @@ -1,26 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author aresei -%%% @copyright (C) 2023, -%%% @doc -%%% -%%% @end -%%% Created : 04. 7月 2023 12:31 -%%%------------------------------------------------------------------- --module(mnesia_id_generator). --author("aresei"). --include("sdlan.hrl"). - -%% API --export([next_id/1, create_table/0]). - -create_table() -> - %% id生成器 - mnesia:create_table(id_generator, [ - {attributes, record_info(fields, id_generator)}, - {record_name, id_generator}, - {disc_copies, [node()]}, - {type, ordered_set} - ]). - -next_id(Tab) when is_atom(Tab) -> - mnesia:dirty_update_counter(id_generator, Tab, 1). \ No newline at end of file diff --git a/apps/sdlan/src/mnesia/mnesia_manager.erl b/apps/sdlan/src/mnesia/mnesia_manager.erl deleted file mode 100644 index 55e18bd..0000000 --- a/apps/sdlan/src/mnesia/mnesia_manager.erl +++ /dev/null @@ -1,43 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% TODO 数据库暂时不启用 -%%% @end -%%% Created : 28. 3月 2024 11:01 -%%%------------------------------------------------------------------- --module(mnesia_manager). --author("anlicheng"). --include("sdlan.hrl"). - -%% API --export([init_database/0, join/1, copy_database/1]). - -init_database() -> - %% 清理掉以前的schema - mnesia:stop(), - mnesia:delete_schema([node()]), - - %% 创建schema - ok = mnesia:create_schema([node()]), - ok = mnesia:start(), - ok. - -%% 加入集群 -join(MasterNode) when is_atom(MasterNode) -> - net_kernel:connect_node(MasterNode). - -%% 初始化slave数据库 -copy_database(MasterNode) when is_atom(MasterNode) -> - %% 清理旧的schema - mnesia:stop(), - mnesia:delete_schema([node()]), - %% 重新启动数据库 - mnesia:start(), - - rpc:call(MasterNode, mnesia, change_config, [extra_db_nodes, [node()]]), - mnesia:change_table_copy_type(schema, node(), disc_copies), - - %% 增加表的分区复制 - % mnesia:add_table_copy(client, node(), ram_copies), - ok. \ No newline at end of file diff --git a/apps/sdlan/src/quic/sdlan_quic_channel.erl b/apps/sdlan/src/quic/sdlan_quic_channel.erl index db6b66e..1b4ed9f 100644 --- a/apps/sdlan/src/quic/sdlan_quic_channel.erl +++ b/apps/sdlan/src/quic/sdlan_quic_channel.erl @@ -99,7 +99,7 @@ callback_mode() -> handle_event(internal, do_init, initializing, State=#state{conn = Conn}) -> logger:debug("[sdlan_quic_channel] conn: ~p, do_init", [Conn]), - case quicer:accept_stream(Conn, []) of + case quicer:accept_stream(Conn, #{active => true}) of {ok, Stream} -> logger:debug("[sdlan_quic_channel] get stream: ~p", [Stream]), {next_state, initialized, State#state{stream_handle = Stream}}; diff --git a/apps/sdlan/src/quic/sdlan_quic_server.erl b/apps/sdlan/src/quic/sdlan_quic_server.erl index 3f65e5f..bece451 100644 --- a/apps/sdlan/src/quic/sdlan_quic_server.erl +++ b/apps/sdlan/src/quic/sdlan_quic_server.erl @@ -21,19 +21,23 @@ init() -> Alpn = proplists:get_value(alpn, Props), Path = code:priv_dir(sdlan), - - LOptions = [ - {certfile, Path ++ "/cert.pem"}, - {keyfile, Path ++ "/key.pem"}, - {alpn, Alpn}, - {ip, {0,0,0,0}}, - {peer_bidi_stream_count, 1} - ], - {ok, L} = quicer:listen(Port, LOptions), - loop_accept(L). + LOptions = #{ + certfile => Path ++ "/cert.pem", + keyfile => Path ++ "/key.pem", + alpn => Alpn, + peer_bidi_stream_count => 1, + conn_acceptors => 10 + }, + ListenAddr = "0.0.0.0:" ++ integer_to_list(Port), + case quicer:listen(ListenAddr, LOptions) of + {ok, L} -> + loop_accept(L); + Error -> + exit(Error) + end. loop_accept(L) -> - case quicer:accept(L, [], infinity) of + case quicer:accept(L, #{}, infinity) of {ok, Conn} -> logger:debug("[sdlan_quic_server] accept a new connection: ~p", [Conn]), case quicer:handshake(Conn) of diff --git a/apps/sdlan/src/sdlan_network.erl b/apps/sdlan/src/sdlan_network.erl index cf9d57b..99a51d0 100644 --- a/apps/sdlan/src/sdlan_network.erl +++ b/apps/sdlan/src/sdlan_network.erl @@ -197,8 +197,8 @@ handle_call({attach, ChannelPid, ClientId, Mac, Ip, Hostname}, _From, mac = Mac, ip = Ip }), - broadcast(fun(#endpoint{channel_pid = ChannelPid}) -> - sdlan_quic_channel:send_event(ChannelPid, ?PACKET_EVENT_NAT_CHANGED, NatChangedEvent) + broadcast(fun(#endpoint{channel_pid = ChannelPid0}) -> + sdlan_quic_channel:send_event(ChannelPid0, ?PACKET_EVENT_NAT_CHANGED, NatChangedEvent) end, [Mac], Endpoints), %% 清理就的绑定关系 @@ -397,7 +397,7 @@ terminate(Reason, #state{network_id = NetworkId, endpoints = Endpoints}) -> false -> ok end - end, Endpoints), + end, [], Endpoints), logger:debug("[sdlan_network] network: ~p, will terminate with reason: ~p", [NetworkId, Reason]), ok. @@ -439,10 +439,6 @@ limiting_check(ThrottleKey) -> end end. --spec broadcast(Fun :: fun((#endpoint{}) -> no_return()), Endpoints :: map()) -> no_return(). -broadcast(Fun, Endpoints) when is_function(Fun, 1), is_map(Endpoints) -> - broadcast(Fun, [], Endpoints). - -spec broadcast(Fun :: fun((#endpoint{}) -> no_return()), ExcludeMacs :: [binary()], Endpoints :: map()) -> no_return(). broadcast(Fun, ExcludeMacs, Endpoints) when is_function(Fun, 1), is_map(Endpoints), is_list(ExcludeMacs) -> maps:foreach(fun(Mac, Endpoint) -> diff --git a/apps/sdlan/src/quic/quic_client.erl b/apps/sdlan/src/test/quic_client.erl similarity index 100% rename from apps/sdlan/src/quic/quic_client.erl rename to apps/sdlan/src/test/quic_client.erl diff --git a/apps/sdlan/src/test/sdlan_quicer_test.erl b/apps/sdlan/src/test/sdlan_quicer_test.erl deleted file mode 100644 index 89c7928..0000000 --- a/apps/sdlan/src/test/sdlan_quicer_test.erl +++ /dev/null @@ -1,20 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2026, -%%% @doc -%%% -%%% @end -%%% Created : 11. 2月 2026 15:49 -%%%------------------------------------------------------------------- --module(sdlan_quicer_test). --author("anlicheng"). - -%% API --export([test/0]). - -test() -> - {ok, Conn} = quicer:connect("http3.is", 443, [{alpn, ["h3"]}, - {verify, verify_peer}, - {peer_unidi_stream_count, 3}], 5000), - logger:debug("conn is: ~p", [Conn]), - quicer:shutdown_connection(Conn). \ No newline at end of file diff --git a/apps/sdlan/src/test/sdlan_tcp_client.erl b/apps/sdlan/src/test/sdlan_tcp_client.erl deleted file mode 100644 index cae3213..0000000 --- a/apps/sdlan/src/test/sdlan_tcp_client.erl +++ /dev/null @@ -1,101 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 29. 3月 2024 14:32 -%%%------------------------------------------------------------------- --module(sdlan_tcp_client). --author("anlicheng"). - --behaviour(gen_server). - -%% 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]). - --define(SERVER, ?MODULE). - --record(state, { - socket -}). - -%%%=================================================================== -%%% API -%%%=================================================================== - -%% @doc Spawns the server and registers the local name (unique) --spec(start_link() -> - {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). -start_link() -> - gen_server:start_link({local, ?SERVER}, ?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, Socket} = gen_tcp:connect("localhost", 18083, [binary, {packet, 2}, {active, true}]), - ok = gen_tcp:send(Socket, <<"hello world">>), - {ok, #state{socket = Socket}}. - -%% @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(_Request, State = #state{}) -> - {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(_Info, State = #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 -%%%=================================================================== diff --git a/apps/sdlan/src/test/sdlan_udp_downloader.erl b/apps/sdlan/src/test/sdlan_udp_downloader.erl deleted file mode 100644 index 9177b5b..0000000 --- a/apps/sdlan/src/test/sdlan_udp_downloader.erl +++ /dev/null @@ -1,110 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 17. 4月 2024 10:35 -%%%------------------------------------------------------------------- --module(sdlan_udp_downloader). --author("anlicheng"). - --behaviour(gen_server). - -%% 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]). - --define(SERVER, ?MODULE). - --record(state, { - socket -}). - -%%%=================================================================== -%%% API -%%%=================================================================== - -%% @doc Spawns the server and registers the local name (unique) --spec(start_link() -> - {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). -start_link() -> - gen_server:start_link({local, ?SERVER}, ?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, Socket} = gen_udp:open(22222, [binary]), - {ok, #state{socket = Socket}}. - -%% @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) -> - {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(_Info, State) -> - {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, Sock, Ip, Port, <<1>>}, State = #state{socket = Sock}) -> - {ok, Content} = file:read_file("/tmp/files/test.dmg"), - send_file_content(Sock, Ip, Port, 1200, Content), - {noreply, State#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 -%%%=================================================================== - -send_file_content(Sock, Ip, Port, Size, Content) when byte_size(Content) =< Size -> - gen_udp:send(Sock, Ip, Port, Content); -send_file_content(Sock, Ip, Port, Size, Content) -> - <> = Content, - gen_udp:send(Sock, Ip, Port, Part), - send_file_content(Sock, Ip, Port, Size, Rest). diff --git a/apps/sdlan/src/test/sdlan_udp_wget.erl b/apps/sdlan/src/test/sdlan_udp_wget.erl deleted file mode 100644 index b910336..0000000 --- a/apps/sdlan/src/test/sdlan_udp_wget.erl +++ /dev/null @@ -1,114 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 17. 4月 2024 10:35 -%%%------------------------------------------------------------------- --module(sdlan_udp_wget). --author("anlicheng"). - --behaviour(gen_server). - -%% API --export([start_link/0]). --export([wget/0]). - -%% gen_server callbacks --export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). - --define(SERVER, ?MODULE). - --record(state, { - socket, - bytes = 0 -}). - -%%%=================================================================== -%%% API -%%%=================================================================== -wget() -> - gen_server:call(?MODULE, wget). - -%% @doc Spawns the server and registers the local name (unique) --spec(start_link() -> - {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). -start_link() -> - gen_server:start_link({local, ?SERVER}, ?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, Socket} = gen_udp:open(0, [binary, {active, true}]), - inet_udp:controlling_process(Socket, self()), - - erlang:start_timer(5000, self(), qps_ticker), - - {ok, #state{socket = Socket}}. - -%% @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(wget, _From, State=#state{socket = Socket}) -> - gen_udp:send(Socket, "127.0.0.1", 22222, <<1>>), - {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(_Info, State) -> - {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, Sock, _Ip, _Port, Data}, State = #state{socket = Sock, bytes = Bytes}) -> - {noreply, State#state{bytes = Bytes + byte_size(Data)}}; -handle_info({timeout, _, qps_ticker}, State = #state{bytes = Bytes}) -> - logger:debug("[sdlan_udp_wget] qps is: ~p(M)", [Bytes / 1024 / 1024]), - erlang:start_timer(5000, self(), qps_ticker), - {noreply, State#state{bytes = 0}}. - - -%% @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 -%%%=================================================================== diff --git a/apps/sdlan/src/test/stun_client.erl b/apps/sdlan/src/test/stun_client.erl deleted file mode 100644 index 7601ea7..0000000 --- a/apps/sdlan/src/test/stun_client.erl +++ /dev/null @@ -1,208 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author anlicheng -%%% @copyright (C) 2024, -%%% @doc -%%% -%%% @end -%%% Created : 08. 4月 2024 10:37 -%%%------------------------------------------------------------------- --module(stun_client). --author("anlicheng"). --include("sdlan_pb.hrl"). - --behaviour(gen_server). - -%% API --export([start_link/0]). --export([register/1, debug_info/1]). - -%% gen_server callbacks --export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, - code_change/3]). - --define(SERVER, ?MODULE). -%% 请求 --define(STUN_REGISTER, 3). -%% 响应 --define(STUN_REGISTER_ACK, 4). - --define(STUN_DATA, 5). - --record(state, { - socket, - tun_socket, - client_id :: binary(), - network_id, - net_addr, - mask_len, - aes_key, - cookie = 1, - - sessions = #{} -}). - -%%%=================================================================== -%%% API -%%%=================================================================== - -register(Pid) when is_pid(Pid) -> - gen_server:call(Pid, register). - -debug_info(Pid) -> - gen_server:call(Pid, debug_info). - -%% @doc Spawns the server and registers the local name (unique) --spec(start_link() -> - {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). -start_link() -> - 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, Socket} = gen_tcp:connect("localhost", 18083, [binary, {packet, 2}, {active, true}]), - inet_tcp:controlling_process(Socket, self()), - {ok, TunSocket} = gen_udp:open(12345, [binary, {active, true}]), - - {ok, #state{socket = Socket, tun_socket = TunSocket, client_id = <<"22222222222222222222222222222222">>}}. - -%% @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(debug_info, _From, State) -> - {reply, {ok, State}, State}; - -handle_call(register, _From, State = #state{socket = Socket, client_id = ClientId}) -> - Req = #{ - <<"version">> => 1, - <<"client_id">> => ClientId, - <<"dev_addr">> => #{ - <<"net_addr">> => 0, - <<"net_bit_len">> => 0 - }, - <<"token">> => <<"1234567890">> - }, - - Register = #sdl_register_super { - version = 1, - installed_channel = <<"macos">>, - client_id = ClientId, - dev_addr = #sdl_dev_addr { - network_id = 0, - mac = <<11, 12, 13, 14, 15, 16>>, - net_addr = 0, - net_bit_len = 0 - }, - pub_key = <<>>, - token = <<"1234567890">> - }, - - logger:debug("register is: ~p", [Register]), - - Packet = jiffy:encode(Req, [force_utf8]), - ok = gen_tcp:send(Socket, <<1:32, 101, Packet/binary>>), - - {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(_Request, State = #state{}) -> - {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({tcp, Socket, <<1:32, 5, Data/binary>>}, State = #state{socket = Socket, tun_socket = TunSocket, client_id = ClientId, cookie = Cookie}) -> - Response = jiffy:decode(Data, [return_maps]), - #{ - <<"dev_addr">> := #{ - <<"network_id">> := NetworkId, - <<"net_addr">> := NetAddr, - <<"net_bit_len">> := NetBitLen - }, - <<"aes_key">> := AesKey, - <<"lifetime">> := Lifetime - } = Response, - - logger:debug("[stun_client] get a register super response: ~p, alloc ip addr: ~p", [Response, sdlan_ipaddr:int_to_ipv4(NetAddr)]), - - %% 开始注册自己的tun信息 - gen_udp:send(TunSocket, "localhost", 1265, <<1, Cookie:32, ClientId/binary, NetworkId:32, NetAddr:32>>), - - {noreply, State#state{network_id = NetworkId, net_addr = NetAddr, mask_len = NetBitLen, aes_key = AesKey, cookie = Cookie + 1}}; - -handle_info({udp, _, _, _, <<2, Cookie:32, Family, Port:16, Ip0, Ip1, Ip2, Ip3>>}, State = #state{}) -> - logger:debug("[stun_client] tun register ack, cookie: ~p, ack: ~p", [Cookie, {Family, Port, {Ip0, Ip1, Ip2, Ip3}}]), - {noreply, State}; - -handle_info({udp, _, Ip, Port, <>}, State = #state{tun_socket = TunSocket, sessions = Sessions}) -> - Packet = <>, - logger:debug("[stun_client] will send stun reply: ~p, peer: ~p", [Packet, {Ip, Port}]), - ok = gen_udp:send(TunSocket, Ip, Port, Packet), - - NSessions = maps:put(SrcIp, {Ip, Port}, Sessions), - {noreply, State#state{sessions = NSessions}}; - -handle_info({udp, _, Ip, Port, <>}, State = #state{sessions = Sessions}) -> - logger:debug("[stun_client] stun_data: network_id: ~p, src: ~p, dst: ~p, register_ack!!!", [NetworkId, SrcIp, DstIp]), - NSessions = maps:put(SrcIp, {Ip, Port}, Sessions), - {noreply, State#state{sessions = NSessions}}; - -handle_info({udp, _, _Ip0, _Port0, <>}, State = #state{tun_socket = TunSocket, sessions = Sessions}) -> - logger:debug("[stun_client] stun_data: network_id: ~p, src: ~p, dst: ~p, data!!!", [NetworkId, SrcIp, DstIp]), - case maps:is_key(SrcIp, Sessions) of - true -> - {Ip, Port} = maps:get(SrcIp, Sessions), - ok = gen_udp:send(TunSocket, Ip, Port, <>), - logger:debug("[stun_client] stun_data: network_id: ~p, src: ~p, dst: ~p, reply data!!!", [NetworkId, SrcIp, DstIp]); - false -> - logger:debug("[stun_client] stun_data: network_id: ~p, src: ~p, dst: ~p, no session", [NetworkId, SrcIp, DstIp]) - end, - {noreply, State}; - -handle_info(Info, State = #state{}) -> - logger:debug("[stun_client] get info: ~p", [Info]), - {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 -%%%===================================================================