This commit is contained in:
anlicheng 2026-01-26 22:07:58 +08:00
parent 388096a29a
commit d272258312
3 changed files with 33 additions and 29 deletions

View File

@ -17,6 +17,7 @@
%% API
-export([start_link/1]).
-export([send_packets/3]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
@ -31,11 +32,15 @@
%%% API
%%%===================================================================
-spec send_packets(Pid :: pid(), Peers :: [{Ip :: inet:ip4_address(), Port :: integer()}], Packet :: binary()) -> no_return().
send_packets(Pid, Peers, Packet) when is_pid(Pid), is_list(Peers), is_binary(Packet) ->
gen_server:cast(Pid, {send_packets, Peers, Packet}).
%% @doc Spawns the server and registers the local name (unique)
-spec(start_link(Socket :: inet:socket()) ->
-spec(start_link(Port :: integer()) ->
{ok, Pid :: pid()} | ignore | {error, Reason :: term()}).
start_link(Socket) ->
gen_server:start_link(?MODULE, [Socket], []).
start_link(Port) ->
gen_server:start_link(?MODULE, [Port], []).
%%%===================================================================
%%% gen_server callbacks
@ -46,7 +51,17 @@ start_link(Socket) ->
-spec(init(Args :: term()) ->
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
{stop, Reason :: term()} | ignore).
init([Socket]) ->
init([Port]) ->
Opts = [
binary,
{reuseaddr, true},
{reuseport, true},
{active, true},
{recbuf, 5 * 1024 * 1024},
{sndbuf, 5 * 1024 * 1024}
],
{ok, Socket} = gen_udp:open(Port, Opts),
%%
erlang:process_flag(priority, high),
inet_udp:controlling_process(Socket, self()),
@ -71,7 +86,10 @@ handle_call(_Request, _From, State = #state{}) ->
{noreply, NewState :: #state{}} |
{noreply, NewState :: #state{}, timeout() | hibernate} |
{stop, Reason :: term(), NewState :: #state{}}).
%%
handle_cast({send_packets, Peers, Packet}, State = #state{socket = Sock}) ->
lists:foreach(fun({Ip, Port}) -> gen_udp:send(Sock, Ip, Port, Packet) end, Peers),
{noreply, State};
%% node下的转发
handle_cast({stun_relay, Ip, Port, Reply}, State = #state{socket = Sock}) ->
ok = gen_udp:send(Sock, Ip, Port, Reply),
@ -89,7 +107,7 @@ handle_info({udp, Sock, PeerIp, PeerPort, Packet}, State = #state{socket = Sock}
handle_info({udp_error , Sock, Reason}, State = #state{socket = Sock}) ->
{stop, Reason, State};
handle_info(Info, State) ->
logger:error("[sdlan_stun] get a unknown message: ~p, channel will closed", [Info]),
logger:error("[sdlan_stun] get a unknown message?: ~p, channel will closed, state: ~p", [Info, State]),
{noreply, State}.
%% @private

View File

@ -35,7 +35,7 @@
-spec send_packet(Peer :: {Ip :: inet:ip4_address(), Port :: integer()}, Packet :: binary()) -> no_return().
send_packet(Peer, Packet) ->
gen_server:cast(?SERVER, {send_packet, Peer, Packet}).
gen_server:cast(?SERVER, {send_packets, [Peer], Packet}).
-spec send_packets(Peers :: [{Ip :: inet:ip4_address(), Port :: integer()}], Packet :: binary()) -> no_return().
send_packets(Peers, Packet) when is_list(Peers), is_binary(Packet) ->
@ -61,19 +61,9 @@ init([]) ->
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) ->
{ok, Socket} = gen_udp:open(Port, Opts),
{ok, Pid} = sdlan_stun:start_link(Socket),
{Socket, Pid}
{ok, Pid} = sdlan_stun:start_link(Port),
Pid
end, lists:seq(1, AcceptorNums)),
{ok, #state{workers = list_to_tuple(Workers), idx = 1, num = length(Workers)}}.
@ -98,15 +88,9 @@ handle_call(_Request, _From, State = #state{}) ->
{stop, Reason :: term(), NewState :: #state{}}).
%% node下的转发
handle_cast({send_packet, {Ip, Port}, Packet}, State = #state{workers = Workers, idx = Idx, num = Num}) ->
{Sock, _} = element(Idx, Workers),
gen_udp:send(Sock, Ip, Port, Packet),
NewIdx = (Idx rem Num) + 1,
{noreply, State#state{idx = NewIdx}};
handle_cast({send_packets, Peers, Packet}, State = #state{workers = Workers, idx = Idx, num = Num}) ->
{Sock, _} = element(Idx, Workers),
lists:foreach(fun({Ip, Port}) -> gen_udp:send(Sock, Ip, Port, Packet) end, Peers),
WorkerPid = element(Idx, Workers),
sdlan_stun:send_packets(WorkerPid, Peers, Packet),
NewIdx = (Idx rem Num) + 1,
{noreply, State#state{idx = NewIdx}}.
@ -117,7 +101,7 @@ handle_cast({send_packets, Peers, Packet}, State = #state{workers = Workers, idx
{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]),
logger:error("[sdlan_stun] get a unknown message:xx ~p, channel will closed", [Info]),
{noreply, State}.
%% @private

View File

@ -81,7 +81,9 @@ start_link() ->
{stop, Reason :: term()} | ignore).
init([]) ->
{ok, TunSocket} = gen_udp:open(0, [binary, {active, true}]),
{ok, #state{tun_socket = TunSocket, network_id = 8, mac = <<11, 12, 13, 14, 15, 16>>, ip = x, mask_len = 24, client_id = <<"22222222222222222222222222222222">>}}.
Ip = sdlan_ipaddr:ipv4_to_int({10, 211, 179, 1}),
{ok, #state{tun_socket = TunSocket, network_id = 8, mac = <<11, 12, 13, 14, 15, 16>>, ip = Ip, mask_len = 24, client_id = <<"22222222222222222222222222222222">>}}.
%% @private
%% @doc Handling call messages