fix issueg
This commit is contained in:
parent
c2b2140a6b
commit
050cfbb662
@ -93,9 +93,13 @@ handle_data(_Json) ->
|
||||
|
||||
%% 解析请求的包, 支持请求不在一个包里面的情况, 基于状态机
|
||||
parse(Command = #command{stage = parse_arg_num, data = <<$*, Rest/binary>>}) ->
|
||||
[ArgNum0, ArgBin] = binary:split(Rest, <<$\r, $\n>>),
|
||||
ArgNum = binary_to_integer(ArgNum0),
|
||||
parse(Command#command{arg_num = ArgNum, data = ArgBin, stage = parse_arg});
|
||||
case binary:split(Rest, <<$\r, $\n>>) of
|
||||
[ArgNum0, ArgBin] ->
|
||||
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 = <<>>}) ->
|
||||
{ok, Command#command{args = lists:reverse(Args)}};
|
||||
|
||||
@ -17,56 +17,60 @@
|
||||
|
||||
-spec get_all_networks() -> {ok, [NetworkId :: integer()]} | {error, Reason :: any()}.
|
||||
get_all_networks() ->
|
||||
case catch do_get("get_all_networks", []) of
|
||||
case safe_request(fun() -> do_get("get_all_networks", []) end) of
|
||||
{ok, Resp} ->
|
||||
case catch jiffy:decode(Resp, [return_maps]) of
|
||||
#{<<"result">> := Networks} ->
|
||||
case decode_json(Resp) of
|
||||
{ok, #{<<"result">> := Networks}} ->
|
||||
{ok, Networks};
|
||||
#{<<"error">> := #{<<"code">> := _Code, <<"message">> := Message}} ->
|
||||
{ok, #{<<"error">> := #{<<"code">> := _Code, <<"message">> := Message}}} ->
|
||||
{error, Message};
|
||||
_ ->
|
||||
{error, <<"invalid json">>}
|
||||
{ok, _} ->
|
||||
{error, <<"invalid json">>};
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
end;
|
||||
Error ->
|
||||
{error, _Reason} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec get_network(Id :: integer()) -> {ok, Network :: map()} | {error, Reason :: any()}.
|
||||
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} ->
|
||||
case catch jiffy:decode(Resp, [return_maps]) of
|
||||
#{<<"result">> := Network} ->
|
||||
case decode_json(Resp) of
|
||||
{ok, #{<<"result">> := Network}} ->
|
||||
{ok, Network};
|
||||
#{<<"error">> := #{<<"code">> := _Code, <<"message">> := Message}} ->
|
||||
{ok, #{<<"error">> := #{<<"code">> := _Code, <<"message">> := Message}}} ->
|
||||
{error, Message};
|
||||
_ ->
|
||||
{error, <<"invalid json">>}
|
||||
{ok, _} ->
|
||||
{error, <<"invalid json">>};
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
end;
|
||||
Error ->
|
||||
{error, _Reason} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec auth_access_token(Params :: map()) -> {ok, Resp :: map()} | {error, Reason :: any()}.
|
||||
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} ->
|
||||
case catch jiffy:decode(Resp, [return_maps]) of
|
||||
Result when is_map(Result) ->
|
||||
case decode_json(Resp) of
|
||||
{ok, Result} ->
|
||||
{ok, Result};
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
end;
|
||||
Error ->
|
||||
{error, _Reason} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec set_node_status(Params :: map()) -> {ok, Resp :: map()} | {error, Reason :: any()}.
|
||||
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, catch jiffy:decode(Resp, [return_maps])};
|
||||
Error ->
|
||||
decode_json(Resp);
|
||||
{error, _Reason} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
@ -81,10 +85,10 @@ flow_report(ClientId, NetworkId, ForwardNum, P2PNum, InboundNum)
|
||||
<<"p2p_num">> => P2PNum,
|
||||
<<"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, catch jiffy:decode(Resp, [return_maps])};
|
||||
Error ->
|
||||
decode_json(Resp);
|
||||
{error, _Reason} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
@ -95,13 +99,37 @@ network_forward_report(NetworkId, ForwardNum) when is_integer(NetworkId), is_int
|
||||
<<"network_id">> => NetworkId,
|
||||
<<"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, catch jiffy:decode(Resp, [return_maps])};
|
||||
Error ->
|
||||
decode_json(Resp);
|
||||
{error, _Reason} = Error ->
|
||||
Error
|
||||
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()}.
|
||||
do_get(Uri, Params) when is_list(Uri), is_list(Params) ->
|
||||
{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) ->
|
||||
float_to_binary(F, [short]);
|
||||
as_binary(Str) when is_list(Str) ->
|
||||
list_to_binary(Str).
|
||||
list_to_binary(Str).
|
||||
|
||||
@ -333,10 +333,11 @@ handle_call(debug_info, _From, State = #state{network_id = NetworkId, ipaddr = I
|
||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term(), NewState :: #state{}}).
|
||||
%% 删除ip的占用并关闭channel
|
||||
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)]),
|
||||
handle_cast({unregister, ClientId, Mac}, State = #state{network_id = NetworkId, endpoint_table = EndpointTable}) ->
|
||||
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
|
||||
Endpoint = #endpoint{} ->
|
||||
Endpoint = #endpoint{client_id = ClientId} ->
|
||||
cleanup_endpoint(Endpoint, Endpoint#endpoint.channel_pid, unregister),
|
||||
delete_endpoint(EndpointTable, Mac),
|
||||
{noreply, State};
|
||||
|
||||
@ -123,15 +123,16 @@ handle_info({udp, Sock, ClientIp, ClientPort, <<?PACKET_STUN_PROBE:8, Body/binar
|
||||
port = ClientPort,
|
||||
ip = int_ip(ClientIp)
|
||||
}),
|
||||
ProbeReply = <<?PACKET_STUN_PROBE_REPLY, ProbeReplyPkt/binary>>,
|
||||
case Attr of
|
||||
?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 ->
|
||||
%% 切换端口和ip
|
||||
sdlan_stun_peer_assist:stun_relay(ClientIp, ClientPort, ProbeReplyPkt);
|
||||
sdlan_stun_peer_assist:stun_relay(ClientIp, ClientPort, ProbeReply);
|
||||
?STUN_ATTR_CHANGE_PEER ->
|
||||
%% 切换端口返回
|
||||
sdlan_stun_port_assist:stun_relay(ClientIp, ClientPort, ProbeReplyPkt)
|
||||
sdlan_stun_port_assist:stun_relay(ClientIp, ClientPort, ProbeReply)
|
||||
end
|
||||
end,
|
||||
{noreply, State};
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(sdlan_stun_peer_assist).
|
||||
-author("anlicheng").
|
||||
-include("sdlan.hrl").
|
||||
|
||||
-behaviour(gen_server).
|
||||
|
||||
@ -30,7 +31,7 @@
|
||||
%%% 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) ->
|
||||
gen_server:cast(?SERVER, {stun_relay, Ip, Port, Reply}).
|
||||
|
||||
@ -80,7 +81,7 @@ handle_call(_Request, _From, State = #state{}) ->
|
||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||
{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}) ->
|
||||
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),
|
||||
{noreply, State}.
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(sdlan_stun_port_assist).
|
||||
-author("anlicheng").
|
||||
-include("sdlan.hrl").
|
||||
|
||||
-behaviour(gen_server).
|
||||
|
||||
@ -28,7 +29,7 @@
|
||||
%%% 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) ->
|
||||
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{}, timeout() | hibernate} |
|
||||
{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{}) ->
|
||||
{noreply, State}.
|
||||
|
||||
|
||||
@ -39,12 +39,7 @@ mac_str_to_bin(MacBin) when is_binary(MacBin) ->
|
||||
%% 生成随机字节
|
||||
-spec rand_byte(Num :: pos_integer()) -> binary().
|
||||
rand_byte(Num) when is_integer(Num), Num > 0 ->
|
||||
rand_byte0(Num, <<>>).
|
||||
rand_byte0(0, Acc) ->
|
||||
Acc;
|
||||
rand_byte0(Num, Acc) ->
|
||||
Byte = ceil(rand:uniform() * 255),
|
||||
rand_byte0(Num - 1, <<Acc/binary, Byte>>).
|
||||
crypto:strong_rand_bytes(Num).
|
||||
|
||||
%% md5哈希算法
|
||||
-spec md5(string() | binary()) -> string().
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user