解决udp数据包的转发问题
This commit is contained in:
parent
7cd645eb17
commit
f5a07e41f7
@ -25,46 +25,26 @@
|
|||||||
}).
|
}).
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
-ifndef('SDL_DEV_ADDR_PB_H').
|
|
||||||
-define('SDL_DEV_ADDR_PB_H', true).
|
|
||||||
-record(sdl_dev_addr,
|
|
||||||
{network_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits
|
|
||||||
mac = <<>> :: iodata() | undefined, % = 2, optional
|
|
||||||
net_addr = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits
|
|
||||||
net_bit_len = 0 :: non_neg_integer() | undefined, % = 4, optional, 32 bits
|
|
||||||
network_domain = <<>> :: unicode:chardata() | undefined % = 5, optional
|
|
||||||
}).
|
|
||||||
-endif.
|
|
||||||
|
|
||||||
-ifndef('SDL_EMPTY_PB_H').
|
|
||||||
-define('SDL_EMPTY_PB_H', true).
|
|
||||||
-record(sdl_empty,
|
|
||||||
{
|
|
||||||
}).
|
|
||||||
-endif.
|
|
||||||
|
|
||||||
-ifndef('SDL_REGISTER_SUPER_PB_H').
|
-ifndef('SDL_REGISTER_SUPER_PB_H').
|
||||||
-define('SDL_REGISTER_SUPER_PB_H', true).
|
-define('SDL_REGISTER_SUPER_PB_H', true).
|
||||||
-record(sdl_register_super,
|
-record(sdl_register_super,
|
||||||
{version = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits
|
{version = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits
|
||||||
installed_channel = <<>> :: unicode:chardata() | undefined, % = 2, optional
|
client_id = <<>> :: unicode:chardata() | undefined, % = 2, optional
|
||||||
client_id = <<>> :: unicode:chardata() | undefined, % = 3, optional
|
network_id = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits
|
||||||
dev_addr = undefined :: sdlan_pb:sdl_dev_addr() | undefined, % = 4, optional
|
mac = <<>> :: iodata() | undefined, % = 4, optional
|
||||||
pub_key = <<>> :: unicode:chardata() | undefined, % = 5, optional
|
ip = 0 :: non_neg_integer() | undefined, % = 5, optional, 32 bits
|
||||||
token = <<>> :: unicode:chardata() | undefined, % = 6, optional
|
mask_len = 0 :: non_neg_integer() | undefined, % = 6, optional, 32 bits
|
||||||
network_code = <<>> :: unicode:chardata() | undefined, % = 7, optional
|
hostname = <<>> :: unicode:chardata() | undefined, % = 7, optional
|
||||||
hostname = <<>> :: unicode:chardata() | undefined % = 8, optional
|
pub_key = <<>> :: unicode:chardata() | undefined, % = 8, optional
|
||||||
|
access_token = <<>> :: unicode:chardata() | undefined % = 9, optional
|
||||||
}).
|
}).
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
-ifndef('SDL_REGISTER_SUPER_ACK_PB_H').
|
-ifndef('SDL_REGISTER_SUPER_ACK_PB_H').
|
||||||
-define('SDL_REGISTER_SUPER_ACK_PB_H', true).
|
-define('SDL_REGISTER_SUPER_ACK_PB_H', true).
|
||||||
-record(sdl_register_super_ack,
|
-record(sdl_register_super_ack,
|
||||||
{dev_addr = undefined :: sdlan_pb:sdl_dev_addr() | undefined, % = 1, optional
|
{aes_key = <<>> :: iodata() | undefined, % = 1, optional
|
||||||
aes_key = <<>> :: iodata() | undefined, % = 2, optional
|
session_token = <<>> :: iodata() | undefined % = 2, optional
|
||||||
upgrade_type = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits
|
|
||||||
upgrade_prompt :: unicode:chardata() | undefined, % = 4, optional
|
|
||||||
upgrade_address :: unicode:chardata() | undefined % = 5, optional
|
|
||||||
}).
|
}).
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
@ -79,87 +59,61 @@
|
|||||||
-ifndef('SDL_QUERY_INFO_PB_H').
|
-ifndef('SDL_QUERY_INFO_PB_H').
|
||||||
-define('SDL_QUERY_INFO_PB_H', true).
|
-define('SDL_QUERY_INFO_PB_H', true).
|
||||||
-record(sdl_query_info,
|
-record(sdl_query_info,
|
||||||
{dst_mac = <<>> :: iodata() | undefined % = 1, optional
|
{network_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits
|
||||||
|
dst_mac = <<>> :: iodata() | undefined, % = 2, optional
|
||||||
|
session_token = <<>> :: iodata() | undefined % = 3, optional
|
||||||
}).
|
}).
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
-ifndef('SDL_PEER_INFO_PB_H').
|
-ifndef('SDL_PEER_INFO_PB_H').
|
||||||
-define('SDL_PEER_INFO_PB_H', true).
|
-define('SDL_PEER_INFO_PB_H', true).
|
||||||
-record(sdl_peer_info,
|
-record(sdl_peer_info,
|
||||||
{dst_mac = <<>> :: iodata() | undefined, % = 1, optional
|
{network_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits
|
||||||
v4_info = undefined :: sdlan_pb:sdl_v4_info() | undefined, % = 2, optional
|
dst_mac = <<>> :: iodata() | undefined, % = 2, optional
|
||||||
v6_info :: sdlan_pb:sdl_v6_info() | undefined % = 3, optional
|
v4_info = undefined :: sdlan_pb:sdl_v4_info() | undefined, % = 3, optional
|
||||||
|
v6_info :: sdlan_pb:sdl_v6_info() | undefined % = 4, optional
|
||||||
}).
|
}).
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
-ifndef('SDL_NAT_CHANGED_EVENT_PB_H').
|
-ifndef('SDL_NAT_CHANGED_EVENT_PB_H').
|
||||||
-define('SDL_NAT_CHANGED_EVENT_PB_H', true).
|
-define('SDL_NAT_CHANGED_EVENT_PB_H', true).
|
||||||
-record(sdl_nat_changed_event,
|
-record(sdl_nat_changed_event,
|
||||||
{mac = <<>> :: iodata() | undefined, % = 1, optional
|
{network_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits
|
||||||
ip = 0 :: non_neg_integer() | undefined % = 2, optional, 32 bits
|
mac = <<>> :: iodata() | undefined, % = 2, optional
|
||||||
|
ip = 0 :: non_neg_integer() | undefined % = 3, optional, 32 bits
|
||||||
}).
|
}).
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
-ifndef('SDL_SEND_REGISTER_EVENT_PB_H').
|
-ifndef('SDL_SEND_REGISTER_EVENT_PB_H').
|
||||||
-define('SDL_SEND_REGISTER_EVENT_PB_H', true).
|
-define('SDL_SEND_REGISTER_EVENT_PB_H', true).
|
||||||
-record(sdl_send_register_event,
|
-record(sdl_send_register_event,
|
||||||
{dst_mac = <<>> :: iodata() | undefined, % = 1, optional
|
{network_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits
|
||||||
nat_ip = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits
|
dst_mac = <<>> :: iodata() | undefined, % = 2, optional
|
||||||
nat_port = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits
|
nat_ip = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits
|
||||||
nat_type = 0 :: non_neg_integer() | undefined, % = 4, optional, 32 bits
|
nat_port = 0 :: non_neg_integer() | undefined, % = 4, optional, 32 bits
|
||||||
v6_info :: sdlan_pb:sdl_v6_info() | undefined % = 5, optional
|
nat_type = 0 :: non_neg_integer() | undefined, % = 5, optional, 32 bits
|
||||||
|
v6_info :: sdlan_pb:sdl_v6_info() | undefined % = 6, optional
|
||||||
}).
|
}).
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
-ifndef('SDL_NETWORK_SHUTDOWN_EVENT_PB_H').
|
-ifndef('SDL_NETWORK_SHUTDOWN_EVENT_PB_H').
|
||||||
-define('SDL_NETWORK_SHUTDOWN_EVENT_PB_H', true).
|
-define('SDL_NETWORK_SHUTDOWN_EVENT_PB_H', true).
|
||||||
-record(sdl_network_shutdown_event,
|
-record(sdl_network_shutdown_event,
|
||||||
{message = <<>> :: unicode:chardata() | undefined % = 1, optional
|
{network_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits
|
||||||
}).
|
message = <<>> :: unicode:chardata() | undefined % = 2, optional
|
||||||
-endif.
|
|
||||||
|
|
||||||
-ifndef('SDL_CHANGE_NETWORK_COMMAND_PB_H').
|
|
||||||
-define('SDL_CHANGE_NETWORK_COMMAND_PB_H', true).
|
|
||||||
-record(sdl_change_network_command,
|
|
||||||
{dev_addr = undefined :: sdlan_pb:sdl_dev_addr() | undefined, % = 1, optional
|
|
||||||
aes_key = <<>> :: iodata() | undefined % = 2, optional
|
|
||||||
}).
|
|
||||||
-endif.
|
|
||||||
|
|
||||||
-ifndef('SDL_COMMAND_ACK_PB_H').
|
|
||||||
-define('SDL_COMMAND_ACK_PB_H', true).
|
|
||||||
-record(sdl_command_ack,
|
|
||||||
{status = false :: boolean() | 0 | 1 | undefined, % = 1, optional
|
|
||||||
message :: unicode:chardata() | undefined % = 2, optional
|
|
||||||
}).
|
|
||||||
-endif.
|
|
||||||
|
|
||||||
-ifndef('SDL_FLOWS_PB_H').
|
|
||||||
-define('SDL_FLOWS_PB_H', true).
|
|
||||||
-record(sdl_flows,
|
|
||||||
{forward_num = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits
|
|
||||||
p2p_num = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits
|
|
||||||
inbound_num = 0 :: non_neg_integer() | undefined % = 3, optional, 32 bits
|
|
||||||
}).
|
}).
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
-ifndef('SDL_STUN_REQUEST_PB_H').
|
-ifndef('SDL_STUN_REQUEST_PB_H').
|
||||||
-define('SDL_STUN_REQUEST_PB_H', true).
|
-define('SDL_STUN_REQUEST_PB_H', true).
|
||||||
-record(sdl_stun_request,
|
-record(sdl_stun_request,
|
||||||
{cookie = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits
|
{client_id = <<>> :: unicode:chardata() | undefined, % = 1, optional
|
||||||
client_id = <<>> :: unicode:chardata() | undefined, % = 2, optional
|
network_id = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits
|
||||||
network_id = 0 :: non_neg_integer() | undefined, % = 3, optional, 32 bits
|
mac = <<>> :: iodata() | undefined, % = 3, optional
|
||||||
mac = <<>> :: iodata() | undefined, % = 4, optional
|
ip = 0 :: non_neg_integer() | undefined, % = 4, optional, 32 bits
|
||||||
ip = 0 :: non_neg_integer() | undefined, % = 5, optional, 32 bits
|
nat_type = 0 :: non_neg_integer() | undefined, % = 5, optional, 32 bits
|
||||||
nat_type = 0 :: non_neg_integer() | undefined, % = 6, optional, 32 bits
|
v6_info :: sdlan_pb:sdl_v6_info() | undefined, % = 6, optional
|
||||||
v6_info :: sdlan_pb:sdl_v6_info() | undefined % = 7, optional
|
session_token = <<>> :: iodata() | undefined % = 7, optional
|
||||||
}).
|
|
||||||
-endif.
|
|
||||||
|
|
||||||
-ifndef('SDL_STUN_REPLY_PB_H').
|
|
||||||
-define('SDL_STUN_REPLY_PB_H', true).
|
|
||||||
-record(sdl_stun_reply,
|
|
||||||
{cookie = 0 :: non_neg_integer() | undefined % = 1, optional, 32 bits
|
|
||||||
}).
|
}).
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
@ -171,7 +125,8 @@
|
|||||||
dst_mac = <<>> :: iodata() | undefined, % = 3, optional
|
dst_mac = <<>> :: iodata() | undefined, % = 3, optional
|
||||||
is_p2p = false :: boolean() | 0 | 1 | undefined, % = 4, optional
|
is_p2p = false :: boolean() | 0 | 1 | undefined, % = 4, optional
|
||||||
ttl = 0 :: non_neg_integer() | undefined, % = 5, optional, 32 bits
|
ttl = 0 :: non_neg_integer() | undefined, % = 5, optional, 32 bits
|
||||||
data = <<>> :: iodata() | undefined % = 6, optional
|
data = <<>> :: iodata() | undefined, % = 6, optional
|
||||||
|
session_token = <<>> :: iodata() | undefined % = 7, optional
|
||||||
}).
|
}).
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
@ -214,7 +169,8 @@
|
|||||||
-define('SDL_ARP_REQUEST_PB_H', true).
|
-define('SDL_ARP_REQUEST_PB_H', true).
|
||||||
-record(sdl_arp_request,
|
-record(sdl_arp_request,
|
||||||
{network_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits
|
{network_id = 0 :: non_neg_integer() | undefined, % = 1, optional, 32 bits
|
||||||
target_ip = 0 :: non_neg_integer() | undefined % = 2, optional, 32 bits
|
target_ip = 0 :: non_neg_integer() | undefined, % = 2, optional, 32 bits
|
||||||
|
session_token = <<>> :: iodata() | undefined % = 3, optional
|
||||||
}).
|
}).
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([get_all_networks/0, get_network/1]).
|
-export([get_all_networks/0, get_network/1]).
|
||||||
-export([auth_token/3, node_online/3, node_offline/2, flow_report/5, network_forward_report/2, auth_network_code/3]).
|
-export([auth_access_token/1, node_online/3, node_offline/2, flow_report/5, network_forward_report/2]).
|
||||||
|
|
||||||
-export([assign_ip_address/3]).
|
-export([assign_ip_address/3]).
|
||||||
|
|
||||||
@ -49,23 +49,9 @@ get_network(Id) when is_integer(Id) ->
|
|||||||
Error
|
Error
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec auth_token(ClientId :: binary(), Token :: binary(), Version :: integer()) -> {ok, Resp :: map()} | {error, Reason :: any()}.
|
-spec auth_access_token(Params :: map()) -> {ok, Resp :: map()} | {error, Reason :: any()}.
|
||||||
auth_token(ClientId, Token, Version) when is_binary(ClientId), is_binary(Token), is_integer(Version) ->
|
auth_access_token(Params) when is_map(Params) ->
|
||||||
case catch do_post("auth_token", #{<<"client_id">> => ClientId, <<"token">> => Token, <<"version">> => Version}) of
|
case catch do_post("auth_token", Params) of
|
||||||
{ok, Resp} ->
|
|
||||||
case catch jiffy:decode(Resp, [return_maps]) of
|
|
||||||
Result when is_map(Result) ->
|
|
||||||
{ok, Result};
|
|
||||||
{error, Reason} ->
|
|
||||||
{error, Reason}
|
|
||||||
end;
|
|
||||||
Error ->
|
|
||||||
Error
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec auth_network_code(ClientId :: binary(), NetworkCode :: binary(), Version :: integer()) -> {ok, Resp :: map()} | {error, Reason :: any()}.
|
|
||||||
auth_network_code(ClientId, NetworkCode, Version) when is_binary(ClientId), is_binary(NetworkCode), is_integer(Version) ->
|
|
||||||
case catch do_post("check_network", #{<<"client_id">> => ClientId, <<"code">> => NetworkCode, <<"version">> => Version}) of
|
|
||||||
{ok, Resp} ->
|
{ok, Resp} ->
|
||||||
case catch jiffy:decode(Resp, [return_maps]) of
|
case catch jiffy:decode(Resp, [return_maps]) of
|
||||||
Result when is_map(Result) ->
|
Result when is_map(Result) ->
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
%% API
|
%% API
|
||||||
-export([start_link/2]).
|
-export([start_link/2]).
|
||||||
-export([get_name/1, get_pid/1, lookup_pid/1, assign_ip_addr/4, peer_info/3, unregister/3, debug_info/1, get_network_id/1, get_used_map/1, arp_query/2]).
|
-export([get_name/1, get_pid/1, lookup_pid/1, assign_ip_addr/4, peer_info/3, unregister/3, debug_info/1, get_network_id/1, get_used_map/1, arp_query/2]).
|
||||||
-export([forward/5, update_hole/6, disable_client/2, get_channel/2, dropout_client/2]).
|
-export([forward/5, update_hole/6, disable_client/2, dropout_client/2]).
|
||||||
-export([test_event/1]).
|
-export([test_event/1]).
|
||||||
|
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
@ -39,7 +39,6 @@
|
|||||||
-record(endpoint, {
|
-record(endpoint, {
|
||||||
client_id :: binary(),
|
client_id :: binary(),
|
||||||
ip :: integer(),
|
ip :: integer(),
|
||||||
channel_pid :: pid(),
|
|
||||||
monitor_ref :: reference(),
|
monitor_ref :: reference(),
|
||||||
hole :: undefined | #hole{},
|
hole :: undefined | #hole{},
|
||||||
%% 记录ip和ip_v6的映射关系, #{ip_addr :: integer() => {}}
|
%% 记录ip和ip_v6的映射关系, #{ip_addr :: integer() => {}}
|
||||||
@ -92,10 +91,11 @@ lookup_pid(Id) when is_integer(Id) ->
|
|||||||
get_name(Id) when is_integer(Id) ->
|
get_name(Id) when is_integer(Id) ->
|
||||||
list_to_atom("sdlan_network:" ++ integer_to_list(Id)).
|
list_to_atom("sdlan_network:" ++ integer_to_list(Id)).
|
||||||
|
|
||||||
-spec assign_ip_addr(Pid :: pid(), ChannelPid :: pid(), ClientId :: binary(), Mac :: binary()) ->
|
-spec attach(Pid :: pid(), ChannelPid :: pid(), ClientId :: binary(), Mac :: binary()) ->
|
||||||
{ok, Domain :: binary(), NetAddr :: integer(), MaskLen :: integer(), AesKey :: binary()} | {error, Reason :: any()}.
|
{ok, Domain :: binary(), NetAddr :: integer(), MaskLen :: integer(), AesKey :: binary()} | {error, Reason :: any()}.
|
||||||
assign_ip_addr(Pid, ChannelPid, ClientId, Mac) when is_pid(Pid), is_pid(ChannelPid), is_binary(ClientId), is_binary(Mac) ->
|
|
||||||
gen_server:call(Pid, {assign_ip_addr, ChannelPid, ClientId, Mac}).
|
attach(Pid, ChannelPid, ClientId, Mac, Ip, HostName) when is_pid(Pid), is_pid(ChannelPid), is_binary(ClientId), is_binary(Mac) ->
|
||||||
|
gen_server:call(Pid, {attach, ChannelPid, ClientId, Mac, Ip, HostName}).
|
||||||
|
|
||||||
-spec get_network_id(Pid :: pid()) -> {ok, NetworkId :: integer()}.
|
-spec get_network_id(Pid :: pid()) -> {ok, NetworkId :: integer()}.
|
||||||
get_network_id(Pid) when is_pid(Pid) ->
|
get_network_id(Pid) when is_pid(Pid) ->
|
||||||
@ -127,10 +127,6 @@ update_hole(Pid, ClientId, Mac, Peer, NatType, V6Info) when is_pid(Pid), is_bina
|
|||||||
disable_client(Pid, ClientId) when is_pid(Pid), is_binary(ClientId) ->
|
disable_client(Pid, ClientId) when is_pid(Pid), is_binary(ClientId) ->
|
||||||
gen_server:call(Pid, {disable_client, ClientId}).
|
gen_server:call(Pid, {disable_client, ClientId}).
|
||||||
|
|
||||||
-spec get_channel(Pid :: pid(), ClientId :: binary()) -> error | {ok, ChannelPid :: pid()}.
|
|
||||||
get_channel(Pid, ClientId) when is_pid(Pid), is_binary(ClientId) ->
|
|
||||||
gen_server:call(Pid, {get_channel, ClientId}).
|
|
||||||
|
|
||||||
%% 剔除client_id,channel不关闭; channel会被重新绑定到其他的network里面
|
%% 剔除client_id,channel不关闭; channel会被重新绑定到其他的network里面
|
||||||
-spec dropout_client(Pid :: pid(), ClientId :: binary()) -> {ok, ChannelPid :: pid(), HostName :: binary()} | error.
|
-spec dropout_client(Pid :: pid(), ClientId :: binary()) -> {ok, ChannelPid :: pid(), HostName :: binary()} | error.
|
||||||
dropout_client(Pid, ClientId) when is_pid(Pid), is_binary(ClientId) ->
|
dropout_client(Pid, ClientId) when is_pid(Pid), is_binary(ClientId) ->
|
||||||
@ -195,28 +191,21 @@ init([Id]) when is_integer(Id) ->
|
|||||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||||
{stop, Reason :: term(), Reply :: term(), NewState :: #state{}} |
|
{stop, Reason :: term(), Reply :: term(), NewState :: #state{}} |
|
||||||
{stop, Reason :: term(), NewState :: #state{}}).
|
{stop, Reason :: term(), NewState :: #state{}}).
|
||||||
%% 给客户端分配ip地址
|
%% 给客户端分配ip地址, TODO 这里要绑定hole
|
||||||
handle_call({assign_ip_addr, ChannelPid, ClientId, Mac}, _From,
|
handle_call({attach, ClientId, Mac, Ip, HostName}, _From,
|
||||||
State = #state{network_id = NetworkId, domain = Domain, endpoints = Endpoints, mask_len = MaskLen, aes_key = AesKey}) ->
|
State = #state{network_id = NetworkId, domain = Domain, endpoints = Endpoints, mask_len = MaskLen, aes_key = AesKey}) ->
|
||||||
|
|
||||||
case sdlan_api:assign_ip_address(NetworkId, ClientId, Mac) of
|
%% 分配ip地址的时候,以mac地址为唯一基准
|
||||||
{ok, #{<<"ip">> := Ip, <<"host_name">> := HostName}} ->
|
logger:debug("[sdlan_network] alloc_ip, network_id: ~p, client_id: ~p, mac: ~p, net_addr: ~p",
|
||||||
%% 分配ip地址的时候,以mac地址为唯一基准
|
[NetworkId, ClientId, sdlan_util:format_mac(Mac), sdlan_ipaddr:int_to_ipv4(Ip)]),
|
||||||
logger:debug("[sdlan_network] alloc_ip, network_id: ~p, client_id: ~p, mac: ~p, net_addr: ~p",
|
%% 关闭之前的channel
|
||||||
[NetworkId, ClientId, sdlan_util:format_mac(Mac), sdlan_ipaddr:int_to_ipv4(Ip)]),
|
maybe_close_channel(maps:get(Mac, Endpoints, undefined)),
|
||||||
%% 关闭之前的channel
|
%% 添加域名->ip的映射关系
|
||||||
maybe_close_channel(maps:get(Mac, Endpoints, undefined)),
|
sdlan_hostname_regedit:insert(HostName, Domain, Ip),
|
||||||
%% 添加域名->ip的映射关系
|
|
||||||
sdlan_hostname_regedit:insert(HostName, Domain, Ip),
|
|
||||||
|
|
||||||
%% 建立到新的channel之间的关系
|
NEndpoints = maps:put(Mac, #endpoint{client_id = ClientId, ip = Ip}, Endpoints),
|
||||||
MRef = monitor(process, ChannelPid),
|
|
||||||
NEndpoints = maps:put(Mac, #endpoint{client_id = ClientId, ip = Ip, channel_pid = ChannelPid, monitor_ref = MRef}, Endpoints),
|
|
||||||
|
|
||||||
{reply, {ok, Domain, Ip, MaskLen, AesKey}, State#state{endpoints = NEndpoints}};
|
{reply, {ok, Domain, Ip, MaskLen, AesKey}, State#state{endpoints = NEndpoints}};
|
||||||
{error, Reason} ->
|
|
||||||
{reply, {error, Reason}, State}
|
|
||||||
end;
|
|
||||||
|
|
||||||
handle_call(get_used_map, _From, State = #state{endpoints = Endpoints}) ->
|
handle_call(get_used_map, _From, State = #state{endpoints = Endpoints}) ->
|
||||||
UsedInfos = maps:map(fun(_, #endpoint{hole = Hole, v6_info = V6Info}) ->
|
UsedInfos = maps:map(fun(_, #endpoint{hole = Hole, v6_info = V6Info}) ->
|
||||||
@ -247,32 +236,12 @@ handle_call(get_used_map, _From, State = #state{endpoints = Endpoints}) ->
|
|||||||
%% client设置为禁止状态,不允许重连
|
%% client设置为禁止状态,不允许重连
|
||||||
handle_call({disable_client, ClientId}, _From, State = #state{endpoints = Endpoints}) ->
|
handle_call({disable_client, ClientId}, _From, State = #state{endpoints = Endpoints}) ->
|
||||||
case lists:search(fun({_, #endpoint{client_id = ClientId0}}) -> ClientId =:= ClientId0 end, maps:to_list(Endpoints)) of
|
case lists:search(fun({_, #endpoint{client_id = ClientId0}}) -> ClientId =:= ClientId0 end, maps:to_list(Endpoints)) of
|
||||||
{value, {Mac, #endpoint{channel_pid = ChannelPid, monitor_ref = MRef}}} ->
|
{value, {Mac, #endpoint{}}} ->
|
||||||
is_reference(MRef) andalso demonitor(MRef),
|
|
||||||
sdlan_channel:stop(ChannelPid, disable),
|
|
||||||
{reply, ok, State#state{endpoints = maps:remove(Mac, Endpoints)}};
|
{reply, ok, State#state{endpoints = maps:remove(Mac, Endpoints)}};
|
||||||
false ->
|
false ->
|
||||||
{reply, error, State}
|
{reply, error, State}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
handle_call({get_channel, ClientId}, _From, State = #state{endpoints = Endpoints}) ->
|
|
||||||
case lists:search(fun({_, #endpoint{client_id = ClientId0}}) -> ClientId =:= ClientId0 end, maps:to_list(Endpoints)) of
|
|
||||||
{value, {_Ip, #endpoint{channel_pid = ChannelPid}}} ->
|
|
||||||
{reply, {ok, ChannelPid}, State};
|
|
||||||
false ->
|
|
||||||
{reply, error, State}
|
|
||||||
end;
|
|
||||||
|
|
||||||
%% 区别在于是否关闭掉channel, 这里是在网络迁移中的功能; drop的时候需要从当前网络中移除
|
|
||||||
handle_call({dropout_client, ClientId}, _From, State = #state{endpoints = Endpoints}) ->
|
|
||||||
case lists:search(fun({_, #endpoint{client_id = ClientId0}}) -> ClientId =:= ClientId0 end, maps:to_list(Endpoints)) of
|
|
||||||
{value, {Mac, #endpoint{channel_pid = ChannelPid, monitor_ref = MRef}}} ->
|
|
||||||
is_reference(MRef) andalso demonitor(MRef),
|
|
||||||
{reply, {ok, ChannelPid}, State#state{endpoints = maps:remove(Mac, Endpoints)}};
|
|
||||||
false ->
|
|
||||||
{reply, error, State}
|
|
||||||
end;
|
|
||||||
|
|
||||||
handle_call(get_network_id, _From, State = #state{network_id = NetworkId}) ->
|
handle_call(get_network_id, _From, State = #state{network_id = NetworkId}) ->
|
||||||
{reply, {ok, NetworkId}, State};
|
{reply, {ok, NetworkId}, State};
|
||||||
|
|
||||||
@ -393,9 +362,8 @@ handle_cast({unregister, _ClientId, Mac}, State = #state{network_id = NetworkId,
|
|||||||
case maps:take(Mac, Endpoints) of
|
case maps:take(Mac, Endpoints) of
|
||||||
error ->
|
error ->
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
{#endpoint{channel_pid = ChannelPid, monitor_ref = MRef}, NEndpoints} ->
|
{#endpoint{monitor_ref = MRef}, NEndpoints} ->
|
||||||
is_reference(MRef) andalso demonitor(MRef),
|
is_reference(MRef) andalso demonitor(MRef),
|
||||||
sdlan_channel:stop(ChannelPid, normal),
|
|
||||||
{noreply, State#state{endpoints = NEndpoints}}
|
{noreply, State#state{endpoints = NEndpoints}}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -32,63 +32,58 @@ start_link(Sock, Ip, Port, Packet) ->
|
|||||||
{ok, erlang:spawn_link(?MODULE, do_work, [Sock, Ip, Port, Packet])}.
|
{ok, erlang:spawn_link(?MODULE, do_work, [Sock, Ip, Port, Packet])}.
|
||||||
|
|
||||||
do_work(Sock, Ip, Port, <<PacketId:32, Body/binary>>) ->
|
do_work(Sock, Ip, Port, <<PacketId:32, Body/binary>>) ->
|
||||||
#sdl_register_super{version = Version, client_id = ClientId, dev_addr = #sdl_dev_addr{mac = Mac}, network_code = NetworkCode, token = Token, pub_key = PubKey} = sdlan_pb:decode_msg(Body, sdl_register_super),
|
#sdl_register_super{
|
||||||
|
version = Version,
|
||||||
|
client_id = ClientId,
|
||||||
|
network_id = NetworkId,
|
||||||
|
mac = Mac,
|
||||||
|
ip = Ip,
|
||||||
|
mask_len = MaskLen,
|
||||||
|
hostname = HostName,
|
||||||
|
pub_key = PubKey,
|
||||||
|
access_token = AccessToken
|
||||||
|
} = sdlan_pb:decode_msg(Body, sdl_register_super),
|
||||||
|
|
||||||
%% 参数检查
|
%% 参数检查
|
||||||
logger:debug("[sdlan_channel] client_id: ~p, public_key: ~p, token: ~p, network_code: ~p", [ClientId, PubKey, Token, NetworkCode]),
|
logger:debug("[sdlan_channel] client_id: ~p, ip: ~p, mac: ~p, host_name: ~p, access_token: ~p, network_id: ~p", [ClientId, Ip, Mac, HostName, AccessToken, NetworkId]),
|
||||||
true = (Mac =/= <<>> andalso PubKey =/= <<>> andalso ClientId =/= <<>>),
|
true = (Mac =/= <<>> andalso PubKey =/= <<>> andalso ClientId =/= <<>>),
|
||||||
%% Mac地址不能是广播地址
|
%% Mac地址不能是广播地址
|
||||||
true = not (sdlan_util:is_multicast_mac(Mac) orelse sdlan_util:is_broadcast_mac(Mac)),
|
true = not (sdlan_util:is_multicast_mac(Mac) orelse sdlan_util:is_broadcast_mac(Mac)),
|
||||||
|
|
||||||
AuthResult = if
|
Params = #{
|
||||||
Token /= <<>> ->
|
<<"network_id">> => NetworkId,
|
||||||
logger:debug("[sdlan_channel] auth token: ~p", [Token]),
|
<<"client_id">> => ClientId,
|
||||||
sdlan_api:auth_token(ClientId, Token, Version);
|
<<"mac">> => Mac,
|
||||||
NetworkCode /= <<>> ->
|
<<"ip">> => Ip,
|
||||||
logger:debug("[sdlan_channel] auth network code: ~p", [NetworkCode]),
|
<<"mask_len">> => MaskLen,
|
||||||
sdlan_api:auth_network_code(ClientId, NetworkCode, Version)
|
<<"hostname">> => HostName,
|
||||||
end,
|
<<"access_token">> => AccessToken
|
||||||
|
},
|
||||||
|
|
||||||
case AuthResult of
|
case sdlan_api:auth_access_token(Params) of
|
||||||
{ok, #{<<"result">> := #{<<"network_id">> := NetworkId, <<"upgrade_type">> := UpgradeType, <<"upgrade_prompt">> := UpgradePrompt, <<"upgrade_address">> := UpgradeAddress}}} when is_integer(NetworkId) ->
|
{ok, #{<<"result">> := <<"ok">>}} ->
|
||||||
logger:debug("[sdlan_channel] client_id: ~p, mac: ~p, token: ~p, version: ~p, registerd, alloc network_id: ~p", [ClientId, sdlan_util:format_mac(Mac), Token, Version, NetworkId]),
|
|
||||||
%% 建立到network的对应关系
|
%% 建立到network的对应关系
|
||||||
case sdlan_network:get_pid(NetworkId) of
|
case sdlan_network:get_pid(NetworkId) of
|
||||||
NetworkPid when is_pid(NetworkPid) ->
|
NetworkPid when is_pid(NetworkPid) ->
|
||||||
try sdlan_network:assign_ip_addr(NetworkPid, self(), ClientId, Mac) of
|
try sdlan_network:attach(NetworkPid, self(), ClientId, Mac, Ip, HostName) of
|
||||||
{ok, Domain, NetAddr, NetBitLen, AesKey} ->
|
{ok, AesKey, SessionToken} ->
|
||||||
RsaPubKey = sdlan_cipher:rsa_pem_decode(PubKey),
|
RsaPubKey = sdlan_cipher:rsa_pem_decode(PubKey),
|
||||||
EncodedAesKey = rsa_encode(AesKey, RsaPubKey),
|
EncodedAesKey = rsa_encode(AesKey, RsaPubKey),
|
||||||
|
|
||||||
RegisterSuperAck = sdlan_pb:encode_msg(#sdl_register_super_ack {
|
RegisterSuperAck = sdlan_pb:encode_msg(#sdl_register_super_ack {
|
||||||
dev_addr = #sdl_dev_addr{
|
|
||||||
network_id = NetworkId,
|
|
||||||
net_addr = NetAddr,
|
|
||||||
mac = Mac,
|
|
||||||
net_bit_len = NetBitLen,
|
|
||||||
network_domain = Domain
|
|
||||||
},
|
|
||||||
aes_key = EncodedAesKey,
|
aes_key = EncodedAesKey,
|
||||||
upgrade_type = UpgradeType,
|
session_token = SessionToken
|
||||||
upgrade_prompt = UpgradePrompt,
|
|
||||||
upgrade_address = UpgradeAddress
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
%% 发送确认信息
|
%% 发送确认信息
|
||||||
Reply = <<?PACKET_REGISTER_SUPER_ACK, PacketId:32, RegisterSuperAck/binary>>,
|
Reply = <<?PACKET_REGISTER_SUPER_ACK, PacketId:32, RegisterSuperAck/binary>>,
|
||||||
gen_udp:send(Sock, Ip, Port, Reply),
|
gen_udp:send(Sock, Ip, Port, Reply),
|
||||||
|
|
||||||
logger:debug("[sdlan_channel] client_id: ~p, mac: ~p, alloc ip: ~p, register will send ack, aes_key: ~p, enc_aes_key: ~p",
|
|
||||||
[ClientId, sdlan_util:format_mac(Mac), sdlan_ipaddr:int_to_ipv4(NetAddr), AesKey, EncodedAesKey]),
|
|
||||||
|
|
||||||
%% 设置节点的在线状态
|
%% 设置节点的在线状态
|
||||||
Result = sdlan_api:node_online(ClientId, NetworkId, sdlan_ipaddr:int_to_ipv4(NetAddr)),
|
Result = sdlan_api:node_online(ClientId, NetworkId, sdlan_ipaddr:int_to_ipv4(Ip)),
|
||||||
logger:debug("[sdlan_channel] client_id: ~p, set none online, result is: ~p", [ClientId, Result]),
|
logger:debug("[sdlan_channel] client_id: ~p, set none online result is: ~p", [ClientId, Result]);
|
||||||
|
|
||||||
%% TODO 这里要处理session_token的逻辑
|
|
||||||
ok;
|
|
||||||
{error, no_ip} ->
|
{error, no_ip} ->
|
||||||
logger:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: no_ip", [ClientId, Token]),
|
logger:warning("[sdlan_channel] client_id: ~p, register get error: no_ip", [ClientId, Token]),
|
||||||
gen_udp:send(Sock, Ip, Port, register_nak_reply(PacketId, ?NAK_NO_IP, <<"No Ip address">>));
|
gen_udp:send(Sock, Ip, Port, register_nak_reply(PacketId, ?NAK_NO_IP, <<"No Ip address">>));
|
||||||
{error, host_name_used} ->
|
{error, host_name_used} ->
|
||||||
logger:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: host_name_used", [ClientId, Token]),
|
logger:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: host_name_used", [ClientId, Token]),
|
||||||
@ -103,14 +98,11 @@ do_work(Sock, Ip, Port, <<PacketId:32, Body/binary>>) ->
|
|||||||
logger:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: network not found", [ClientId, Token]),
|
logger:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: network not found", [ClientId, Token]),
|
||||||
gen_udp:send(Sock, Ip, Port, register_nak_reply(PacketId, ?NAK_INTERNAL_FAULT, <<"Internal Error">>))
|
gen_udp:send(Sock, Ip, Port, register_nak_reply(PacketId, ?NAK_INTERNAL_FAULT, <<"Internal Error">>))
|
||||||
end;
|
end;
|
||||||
{ok, #{<<"error">> := #{<<"code">> := 1, <<"message">> := Message}}} ->
|
{ok, #{<<"error">> := #{<<"code">> := Code, <<"message">> := Message}}} ->
|
||||||
logger:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: ~ts, error_code: 1", [ClientId, Token, Message]),
|
logger:warning("[sdlan_channel] network_id: ~p, client_id: ~p, register get error: ~ts, error_code: ~p", [NetworkId, ClientId, Message, Code]),
|
||||||
gen_udp:send(Sock, Ip, Port, register_nak_reply(PacketId, ?NAK_INVALID_TOKEN, Message));
|
gen_udp:send(Sock, Ip, Port, register_nak_reply(PacketId, Code, Message));
|
||||||
{ok, #{<<"error">> := #{<<"code">> := 2, <<"message">> := Message}}} ->
|
|
||||||
logger:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: ~p, error_code: 2", [ClientId, Token, Message]),
|
|
||||||
gen_udp:send(Sock, Ip, Port, register_nak_reply(PacketId, ?NAK_NODE_DISABLE, Message));
|
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
logger:warning("[sdlan_channel] client_id: ~p, token: ~p, register get error: ~p", [ClientId, Token, Reason]),
|
logger:warning("[sdlan_channel] network_id: ~p, client_id: ~p, register get error: ~p", [NetworkId, ClientId, Reason]),
|
||||||
gen_udp:send(Sock, Ip, Port, register_nak_reply(PacketId, ?NAK_NETWORK_FAULT, <<"Network Error">>))
|
gen_udp:send(Sock, Ip, Port, register_nak_reply(PacketId, ?NAK_NETWORK_FAULT, <<"Network Error">>))
|
||||||
end,
|
end,
|
||||||
exit(normal).
|
exit(normal).
|
||||||
|
|||||||
@ -37,10 +37,10 @@ get_name(Id) when is_integer(Id) ->
|
|||||||
list_to_atom("sdlan_stun:" ++ integer_to_list(Id)).
|
list_to_atom("sdlan_stun:" ++ integer_to_list(Id)).
|
||||||
|
|
||||||
%% @doc Spawns the server and registers the local name (unique)
|
%% @doc Spawns the server and registers the local name (unique)
|
||||||
-spec(start_link(Name :: atom(), Port :: integer()) ->
|
-spec(start_link(Name :: atom(), Socket :: inet:socket()) ->
|
||||||
{ok, Pid :: pid()} | ignore | {error, Reason :: term()}).
|
{ok, Pid :: pid()} | ignore | {error, Reason :: term()}).
|
||||||
start_link(Name, Port) when is_atom(Name), is_integer(Port) ->
|
start_link(Name, Socket) when is_atom(Name) ->
|
||||||
gen_server:start_link({local, Name}, ?MODULE, [Port], []).
|
gen_server:start_link({local, Name}, ?MODULE, [Socket], []).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% gen_server callbacks
|
%%% gen_server callbacks
|
||||||
@ -51,22 +51,10 @@ start_link(Name, Port) when is_atom(Name), is_integer(Port) ->
|
|||||||
-spec(init(Args :: term()) ->
|
-spec(init(Args :: term()) ->
|
||||||
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
|
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
|
||||||
{stop, Reason :: term()} | ignore).
|
{stop, Reason :: term()} | ignore).
|
||||||
init([Port]) ->
|
init([Socket]) ->
|
||||||
%% 需要提高进程的调度优先级
|
%% 需要提高进程的调度优先级
|
||||||
erlang:process_flag(priority, high),
|
erlang:process_flag(priority, high),
|
||||||
Opts = [
|
|
||||||
binary,
|
|
||||||
{reuseaddr, true},
|
|
||||||
{reuseport, true},
|
|
||||||
{active, true},
|
|
||||||
{recbuf, 5 * 1024 * 1024},
|
|
||||||
{sndbuf, 5 * 1024 * 1024}
|
|
||||||
],
|
|
||||||
|
|
||||||
{ok, Socket} = gen_udp:open(Port, Opts),
|
|
||||||
inet_udp:controlling_process(Socket, self()),
|
inet_udp:controlling_process(Socket, self()),
|
||||||
logger:debug("[sdlan_stun] start at port: ~p", [Port]),
|
|
||||||
|
|
||||||
{ok, #state{socket = Socket}}.
|
{ok, #state{socket = Socket}}.
|
||||||
|
|
||||||
%% @private
|
%% @private
|
||||||
|
|||||||
134
apps/sdlan/src/sdlan_stun_pool.erl
Normal file
134
apps/sdlan/src/sdlan_stun_pool.erl
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author anlicheng
|
||||||
|
%%% @copyright (C) 2024, <COMPANY>
|
||||||
|
%%% @doc
|
||||||
|
%%%
|
||||||
|
%%% @end
|
||||||
|
%%% Created : 09. 4月 2024 17:37
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(sdlan_stun_pool).
|
||||||
|
-feature(maybe_expr, enable).
|
||||||
|
|
||||||
|
-author("anlicheng").
|
||||||
|
-include("sdlan.hrl").
|
||||||
|
-include("sdlan_pb.hrl").
|
||||||
|
|
||||||
|
-behaviour(gen_server).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([start_link/0, send_packets/1]).
|
||||||
|
|
||||||
|
%% 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, {
|
||||||
|
workers :: tuple(),
|
||||||
|
idx = 1,
|
||||||
|
num = 0
|
||||||
|
}).
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
|
||||||
|
send_packets(Packets) when is_list(Packets) ->
|
||||||
|
gen_server:cast(?SERVER, {send_packets, Packets}).
|
||||||
|
|
||||||
|
%% @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, StunServerProps} = application:get_env(sdlan, stun_servers),
|
||||||
|
Port = proplists:get_value(port, StunServerProps),
|
||||||
|
AcceptorNums = proplists:get_value(acceptor_nums, StunServerProps),
|
||||||
|
|
||||||
|
Opts = [
|
||||||
|
binary,
|
||||||
|
{reuseaddr, true},
|
||||||
|
{reuseport, true},
|
||||||
|
{active, true},
|
||||||
|
{recbuf, 5 * 1024 * 1024},
|
||||||
|
{sndbuf, 5 * 1024 * 1024}
|
||||||
|
],
|
||||||
|
|
||||||
|
Workers = lists:map(fun(Id) ->
|
||||||
|
Name = sdlan_stun:get_name(Id),
|
||||||
|
{ok, Socket} = gen_udp:open(Port, Opts),
|
||||||
|
{ok, Pid} = sdlan_stun:start_link(Name, Socket),
|
||||||
|
{Socket, Pid}
|
||||||
|
end, lists:seq(1, AcceptorNums)),
|
||||||
|
{ok, #state{workers = list_to_tuple(Workers), idx = 1, num = length(Workers)}}.
|
||||||
|
|
||||||
|
%% @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{}}).
|
||||||
|
|
||||||
|
%% 当前node下的转发,基于进程间的通讯
|
||||||
|
handle_cast({send_packets, Packets}, State = #state{workers = Workers, idx = Idx, num = Num}) ->
|
||||||
|
{Sock, _} = element(Idx, Workers),
|
||||||
|
lists:foreach(fun({Ip, Port, Data}) -> gen_udp:send(Sock, Ip, Port, Data) end, Packets),
|
||||||
|
NewIdx = (Idx rem Num) + 1,
|
||||||
|
|
||||||
|
{noreply, State#state{idx = NewIdx}}.
|
||||||
|
|
||||||
|
%% @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) ->
|
||||||
|
logger:error("[sdlan_stun] get a unknown message: ~p, channel will closed", [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
|
||||||
|
%%%===================================================================
|
||||||
@ -26,12 +26,16 @@ start_link() ->
|
|||||||
%% modules => modules()} % optional
|
%% modules => modules()} % optional
|
||||||
init([]) ->
|
init([]) ->
|
||||||
SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600},
|
SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600},
|
||||||
|
|
||||||
{ok, StunServerProps} = application:get_env(sdlan, stun_servers),
|
|
||||||
Port = proplists:get_value(port, StunServerProps),
|
|
||||||
AcceptorNums = proplists:get_value(acceptor_nums, StunServerProps),
|
|
||||||
|
|
||||||
Specs = [
|
Specs = [
|
||||||
|
#{
|
||||||
|
id => sdlan_stun_pool,
|
||||||
|
start => {sdlan_stun_pool, start_link, []},
|
||||||
|
restart => permanent,
|
||||||
|
shutdown => 2000,
|
||||||
|
type => worker,
|
||||||
|
modules => ['sdlan_stun_pool']
|
||||||
|
},
|
||||||
|
|
||||||
#{
|
#{
|
||||||
id => sdlan_stun_port_assist,
|
id => sdlan_stun_port_assist,
|
||||||
start => {sdlan_stun_port_assist, start_link, []},
|
start => {sdlan_stun_port_assist, start_link, []},
|
||||||
@ -50,16 +54,4 @@ init([]) ->
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
StunSpecs = lists:map(fun(Id) ->
|
{ok, {SupFlags, Specs}}.
|
||||||
Name = sdlan_stun:get_name(Id),
|
|
||||||
#{
|
|
||||||
id => Name,
|
|
||||||
start => {sdlan_stun, start_link, [Name, Port]},
|
|
||||||
restart => permanent,
|
|
||||||
shutdown => 2000,
|
|
||||||
type => worker,
|
|
||||||
modules => ['sdlan_stun']
|
|
||||||
}
|
|
||||||
end, lists:seq(1, AcceptorNums)),
|
|
||||||
|
|
||||||
{ok, {SupFlags, Specs ++ StunSpecs}}.
|
|
||||||
Loading…
x
Reference in New Issue
Block a user