fix issueg

This commit is contained in:
anlicheng 2026-05-03 16:10:57 +08:00
parent c2b2140a6b
commit 050cfbb662
7 changed files with 81 additions and 46 deletions

View File

@ -93,9 +93,13 @@ handle_data(_Json) ->
%% , , %% , ,
parse(Command = #command{stage = parse_arg_num, data = <<$*, Rest/binary>>}) -> parse(Command = #command{stage = parse_arg_num, data = <<$*, Rest/binary>>}) ->
[ArgNum0, ArgBin] = binary:split(Rest, <<$\r, $\n>>), case binary:split(Rest, <<$\r, $\n>>) of
ArgNum = binary_to_integer(ArgNum0), [ArgNum0, ArgBin] ->
parse(Command#command{arg_num = ArgNum, data = ArgBin, stage = parse_arg}); ArgNum = binary_to_integer(ArgNum0),
parse(Command#command{arg_num = ArgNum, data = ArgBin, stage = parse_arg});
_ ->
{more_data, Command}
end;
%% %%
parse(Command = #command{stage = parse_arg, args = Args, arg_num = 0, data = <<>>}) -> parse(Command = #command{stage = parse_arg, args = Args, arg_num = 0, data = <<>>}) ->
{ok, Command#command{args = lists:reverse(Args)}}; {ok, Command#command{args = lists:reverse(Args)}};

View File

@ -17,56 +17,60 @@
-spec get_all_networks() -> {ok, [NetworkId :: integer()]} | {error, Reason :: any()}. -spec get_all_networks() -> {ok, [NetworkId :: integer()]} | {error, Reason :: any()}.
get_all_networks() -> get_all_networks() ->
case catch do_get("get_all_networks", []) of case safe_request(fun() -> do_get("get_all_networks", []) end) of
{ok, Resp} -> {ok, Resp} ->
case catch jiffy:decode(Resp, [return_maps]) of case decode_json(Resp) of
#{<<"result">> := Networks} -> {ok, #{<<"result">> := Networks}} ->
{ok, Networks}; {ok, Networks};
#{<<"error">> := #{<<"code">> := _Code, <<"message">> := Message}} -> {ok, #{<<"error">> := #{<<"code">> := _Code, <<"message">> := Message}}} ->
{error, Message}; {error, Message};
_ -> {ok, _} ->
{error, <<"invalid json">>} {error, <<"invalid json">>};
{error, Reason} ->
{error, Reason}
end; end;
Error -> {error, _Reason} = Error ->
Error Error
end. end.
-spec get_network(Id :: integer()) -> {ok, Network :: map()} | {error, Reason :: any()}. -spec get_network(Id :: integer()) -> {ok, Network :: map()} | {error, Reason :: any()}.
get_network(Id) when is_integer(Id) -> get_network(Id) when is_integer(Id) ->
case catch do_get("get_network", [{<<"id">>, integer_to_binary(Id)}]) of case safe_request(fun() -> do_get("get_network", [{<<"id">>, integer_to_binary(Id)}]) end) of
{ok, Resp} -> {ok, Resp} ->
case catch jiffy:decode(Resp, [return_maps]) of case decode_json(Resp) of
#{<<"result">> := Network} -> {ok, #{<<"result">> := Network}} ->
{ok, Network}; {ok, Network};
#{<<"error">> := #{<<"code">> := _Code, <<"message">> := Message}} -> {ok, #{<<"error">> := #{<<"code">> := _Code, <<"message">> := Message}}} ->
{error, Message}; {error, Message};
_ -> {ok, _} ->
{error, <<"invalid json">>} {error, <<"invalid json">>};
{error, Reason} ->
{error, Reason}
end; end;
Error -> {error, _Reason} = Error ->
Error Error
end. end.
-spec auth_access_token(Params :: map()) -> {ok, Resp :: map()} | {error, Reason :: any()}. -spec auth_access_token(Params :: map()) -> {ok, Resp :: map()} | {error, Reason :: any()}.
auth_access_token(Params) when is_map(Params) -> auth_access_token(Params) when is_map(Params) ->
case catch do_post("auth/access_token", Params) of case safe_request(fun() -> do_post("auth/access_token", Params) end) of
{ok, Resp} -> {ok, Resp} ->
case catch jiffy:decode(Resp, [return_maps]) of case decode_json(Resp) of
Result when is_map(Result) -> {ok, Result} ->
{ok, Result}; {ok, Result};
{error, Reason} -> {error, Reason} ->
{error, Reason} {error, Reason}
end; end;
Error -> {error, _Reason} = Error ->
Error Error
end. end.
-spec set_node_status(Params :: map()) -> {ok, Resp :: map()} | {error, Reason :: any()}. -spec set_node_status(Params :: map()) -> {ok, Resp :: map()} | {error, Reason :: any()}.
set_node_status(Params) when is_map(Params) -> set_node_status(Params) when is_map(Params) ->
case catch do_post("set_node_status", Params) of case safe_request(fun() -> do_post("set_node_status", Params) end) of
{ok, Resp} -> {ok, Resp} ->
{ok, catch jiffy:decode(Resp, [return_maps])}; decode_json(Resp);
Error -> {error, _Reason} = Error ->
Error Error
end. end.
@ -81,10 +85,10 @@ flow_report(ClientId, NetworkId, ForwardNum, P2PNum, InboundNum)
<<"p2p_num">> => P2PNum, <<"p2p_num">> => P2PNum,
<<"inbound_num">> => InboundNum <<"inbound_num">> => InboundNum
}, },
case catch do_post("client_flow_report", Params) of case safe_request(fun() -> do_post("client_flow_report", Params) end) of
{ok, Resp} -> {ok, Resp} ->
{ok, catch jiffy:decode(Resp, [return_maps])}; decode_json(Resp);
Error -> {error, _Reason} = Error ->
Error Error
end. end.
@ -95,13 +99,37 @@ network_forward_report(NetworkId, ForwardNum) when is_integer(NetworkId), is_int
<<"network_id">> => NetworkId, <<"network_id">> => NetworkId,
<<"forward_num">> => ForwardNum <<"forward_num">> => ForwardNum
}, },
case catch do_post("network_forward_report", Params) of case safe_request(fun() -> do_post("network_forward_report", Params) end) of
{ok, Resp} -> {ok, Resp} ->
{ok, catch jiffy:decode(Resp, [return_maps])}; decode_json(Resp);
Error -> {error, _Reason} = Error ->
Error Error
end. end.
-spec safe_request(Fun :: fun(() -> {ok, binary()} | {error, any()})) -> {ok, binary()} | {error, any()}.
safe_request(Fun) when is_function(Fun, 0) ->
case catch Fun() of
{ok, _Resp} = Ok ->
Ok;
{error, _Reason} = Error ->
Error;
{'EXIT', Reason} ->
{error, Reason};
Error ->
{error, Error}
end.
-spec decode_json(Resp :: binary()) -> {ok, map()} | {error, any()}.
decode_json(Resp) when is_binary(Resp) ->
case catch jiffy:decode(Resp, [return_maps]) of
Result when is_map(Result) ->
{ok, Result};
{'EXIT', Reason} ->
{error, Reason};
Error ->
{error, Error}
end.
-spec do_get(Uri :: string(), Params :: [{K :: binary(), V :: binary()}]) -> {ok, Response :: binary()} | {error, Reason :: any()}. -spec do_get(Uri :: string(), Params :: [{K :: binary(), V :: binary()}]) -> {ok, Response :: binary()} | {error, Reason :: any()}.
do_get(Uri, Params) when is_list(Uri), is_list(Params) -> do_get(Uri, Params) when is_list(Uri), is_list(Params) ->
{ok, Url0} = application:get_env(sdlan, api_url), {ok, Url0} = application:get_env(sdlan, api_url),
@ -188,4 +216,4 @@ as_binary(I) when is_integer(I) ->
as_binary(F) when is_float(F) -> as_binary(F) when is_float(F) ->
float_to_binary(F, [short]); float_to_binary(F, [short]);
as_binary(Str) when is_list(Str) -> as_binary(Str) when is_list(Str) ->
list_to_binary(Str). list_to_binary(Str).

View File

@ -333,10 +333,11 @@ handle_call(debug_info, _From, State = #state{network_id = NetworkId, ipaddr = I
{noreply, NewState :: #state{}, timeout() | hibernate} | {noreply, NewState :: #state{}, timeout() | hibernate} |
{stop, Reason :: term(), NewState :: #state{}}). {stop, Reason :: term(), NewState :: #state{}}).
%% ip的占用并关闭channel %% ip的占用并关闭channel
handle_cast({unregister, _ClientId, Mac}, State = #state{network_id = NetworkId, endpoint_table = EndpointTable}) -> handle_cast({unregister, ClientId, Mac}, State = #state{network_id = NetworkId, endpoint_table = EndpointTable}) ->
logger:debug("[sdlan_network] networkd_id: ~p, unregister Mac: ~p", [NetworkId, sdlan_util:format_mac(Mac)]), logger:debug("[sdlan_network] networkd_id: ~p, unregister client_id: ~p, Mac: ~p",
[NetworkId, ClientId, sdlan_util:format_mac(Mac)]),
case lookup_endpoint(EndpointTable, Mac) of case lookup_endpoint(EndpointTable, Mac) of
Endpoint = #endpoint{} -> Endpoint = #endpoint{client_id = ClientId} ->
cleanup_endpoint(Endpoint, Endpoint#endpoint.channel_pid, unregister), cleanup_endpoint(Endpoint, Endpoint#endpoint.channel_pid, unregister),
delete_endpoint(EndpointTable, Mac), delete_endpoint(EndpointTable, Mac),
{noreply, State}; {noreply, State};

View File

@ -123,15 +123,16 @@ handle_info({udp, Sock, ClientIp, ClientPort, <<?PACKET_STUN_PROBE:8, Body/binar
port = ClientPort, port = ClientPort,
ip = int_ip(ClientIp) ip = int_ip(ClientIp)
}), }),
ProbeReply = <<?PACKET_STUN_PROBE_REPLY, ProbeReplyPkt/binary>>,
case Attr of case Attr of
?STUN_ATTR_CHANGE_NONE -> ?STUN_ATTR_CHANGE_NONE ->
ok = gen_udp:send(Sock, ClientIp, ClientPort, <<?PACKET_STUN_PROBE_REPLY, ProbeReplyPkt/binary>>); ok = gen_udp:send(Sock, ClientIp, ClientPort, ProbeReply);
?STUN_ATTR_CHANGE_PORT -> ?STUN_ATTR_CHANGE_PORT ->
%% ip %% ip
sdlan_stun_peer_assist:stun_relay(ClientIp, ClientPort, ProbeReplyPkt); sdlan_stun_peer_assist:stun_relay(ClientIp, ClientPort, ProbeReply);
?STUN_ATTR_CHANGE_PEER -> ?STUN_ATTR_CHANGE_PEER ->
%% %%
sdlan_stun_port_assist:stun_relay(ClientIp, ClientPort, ProbeReplyPkt) sdlan_stun_port_assist:stun_relay(ClientIp, ClientPort, ProbeReply)
end end
end, end,
{noreply, State}; {noreply, State};

View File

@ -8,6 +8,7 @@
%%%------------------------------------------------------------------- %%%-------------------------------------------------------------------
-module(sdlan_stun_peer_assist). -module(sdlan_stun_peer_assist).
-author("anlicheng"). -author("anlicheng").
-include("sdlan.hrl").
-behaviour(gen_server). -behaviour(gen_server).
@ -30,7 +31,7 @@
%%% API %%% API
%%%=================================================================== %%%===================================================================
-spec stun_relay(Ip :: inet:ip_address(), Port :: integer(), Reply :: binary()) -> no_return(). -spec stun_relay(Ip :: inet:ip_address(), Port :: integer(), Reply :: binary()) -> ok.
stun_relay(Ip, Port, Reply) when is_integer(Port), is_binary(Reply) -> stun_relay(Ip, Port, Reply) when is_integer(Port), is_binary(Reply) ->
gen_server:cast(?SERVER, {stun_relay, Ip, Port, Reply}). gen_server:cast(?SERVER, {stun_relay, Ip, Port, Reply}).
@ -80,7 +81,7 @@ handle_call(_Request, _From, State = #state{}) ->
{noreply, NewState :: #state{}, timeout() | hibernate} | {noreply, NewState :: #state{}, timeout() | hibernate} |
{stop, Reason :: term(), NewState :: #state{}}). {stop, Reason :: term(), NewState :: #state{}}).
handle_cast({stun_relay, _Ip = {Ip0, Ip1, Ip2, Ip3}, Port, Reply}, State = #state{socket = Sock, assist_ip = AssistIp, assist_port = AssistPort}) -> handle_cast({stun_relay, _Ip = {Ip0, Ip1, Ip2, Ip3}, Port, Reply}, State = #state{socket = Sock, assist_ip = AssistIp, assist_port = AssistPort}) ->
Packet = <<Ip0, Ip1, Ip2, Ip3, Port:16, Reply/binary>>, Packet = <<?PACKET_STUN_PROBE_RELAY, Ip0, Ip1, Ip2, Ip3, Port:16, Reply/binary>>,
ok = gen_udp:send(Sock, AssistIp, AssistPort, Packet), ok = gen_udp:send(Sock, AssistIp, AssistPort, Packet),
{noreply, State}. {noreply, State}.

View File

@ -8,6 +8,7 @@
%%%------------------------------------------------------------------- %%%-------------------------------------------------------------------
-module(sdlan_stun_port_assist). -module(sdlan_stun_port_assist).
-author("anlicheng"). -author("anlicheng").
-include("sdlan.hrl").
-behaviour(gen_server). -behaviour(gen_server).
@ -28,7 +29,7 @@
%%% API %%% API
%%%=================================================================== %%%===================================================================
-spec stun_relay(Ip :: inet:ip_address(), Port :: integer(), Reply :: binary()) -> no_return(). -spec stun_relay(Ip :: inet:ip_address(), Port :: integer(), Reply :: binary()) -> ok.
stun_relay(Ip, Port, Reply) when is_integer(Port), is_binary(Reply) -> stun_relay(Ip, Port, Reply) when is_integer(Port), is_binary(Reply) ->
gen_server:cast(?SERVER, {stun_relay, Ip, Port, Reply}). gen_server:cast(?SERVER, {stun_relay, Ip, Port, Reply}).
@ -87,6 +88,10 @@ handle_cast({stun_relay, Ip, Port, Reply}, State = #state{socket = Sock}) ->
{noreply, NewState :: #state{}} | {noreply, NewState :: #state{}} |
{noreply, NewState :: #state{}, timeout() | hibernate} | {noreply, NewState :: #state{}, timeout() | hibernate} |
{stop, Reason :: term(), NewState :: #state{}}). {stop, Reason :: term(), NewState :: #state{}}).
handle_info({udp, Sock, _Ip, _Port, <<?PACKET_STUN_PROBE_RELAY, Ip0, Ip1, Ip2, Ip3, ClientPort:16, Reply/binary>>},
State = #state{socket = Sock}) ->
ok = gen_udp:send(Sock, {Ip0, Ip1, Ip2, Ip3}, ClientPort, Reply),
{noreply, State};
handle_info(_Info, State = #state{}) -> handle_info(_Info, State = #state{}) ->
{noreply, State}. {noreply, State}.

View File

@ -39,12 +39,7 @@ mac_str_to_bin(MacBin) when is_binary(MacBin) ->
%% %%
-spec rand_byte(Num :: pos_integer()) -> binary(). -spec rand_byte(Num :: pos_integer()) -> binary().
rand_byte(Num) when is_integer(Num), Num > 0 -> rand_byte(Num) when is_integer(Num), Num > 0 ->
rand_byte0(Num, <<>>). crypto:strong_rand_bytes(Num).
rand_byte0(0, Acc) ->
Acc;
rand_byte0(Num, Acc) ->
Byte = ceil(rand:uniform() * 255),
rand_byte0(Num - 1, <<Acc/binary, Byte>>).
%% md5哈希算法 %% md5哈希算法
-spec md5(string() | binary()) -> string(). -spec md5(string() | binary()) -> string().