From f6e1cd7c5e86695ca059aab24c086ee8d0b3eb87 Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Tue, 26 May 2026 13:59:59 +0800 Subject: [PATCH] fix sdlan_network --- src/sdlan_network.erl | 43 ++++++++++++++++++--------------- src/sdlan_session.erl | 4 +-- src/ssl/sdlan_ssl_transport.erl | 19 +++++++++++++++ 3 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/sdlan_network.erl b/src/sdlan_network.erl index 614d0ce..c503c28 100644 --- a/src/sdlan_network.erl +++ b/src/sdlan_network.erl @@ -19,7 +19,7 @@ %% API -export([start_link/2]). --export([get_name/1, get_pid/1, lookup_pid/1, peer_info/3, unregister/3, debug_info/1, get_network_id/1, attach/6, arp_request/2]). +-export([get_name/1, get_pid/1, lookup_pid/1, peer_info/3, unregister/3, debug_info/1, get_network_id/1, attach/7, arp_request/2]). -export([forward_by_ets/5, update_hole/7, disable_client/2, get_channel/2, acl_changed/2]). -export([command/4, wait_command_ack/2]). @@ -35,6 +35,7 @@ -record(endpoint, { channel_pid :: undefined | pid(), channel_ref :: undefined | reference(), + transport :: module(), client_id :: binary(), mac :: binary(), @@ -90,10 +91,11 @@ get_name(Id) when is_integer(Id) -> get_network_id(Pid) when is_pid(Pid) -> gen_server:call(Pid, get_network_id). --spec attach(Pid :: pid(), ChannelPid :: pid(), ClientId :: binary(), Mac :: binary(), Ip :: integer(), Hostname :: binary()) -> +-spec attach(Pid :: pid(), ChannelPid :: pid(), Transport :: module(), ClientId :: binary(), Mac :: binary(), Ip :: integer(), Hostname :: binary()) -> {ok, Algorithm :: binary(), Key :: binary(), RegionId :: integer(), SessionToken :: binary()}. -attach(Pid, ChannelPid, ClientId, Mac, Ip, Hostname) when is_pid(Pid), is_pid(ChannelPid), is_binary(ClientId), is_binary(Mac), is_integer(Ip), is_binary(Hostname) -> - gen_server:call(Pid, {attach, ChannelPid, ClientId, Mac, Ip, Hostname}). +attach(Pid, ChannelPid, Transport, ClientId, Mac, Ip, Hostname) + when is_pid(Pid), is_pid(ChannelPid), is_atom(Transport), is_binary(ClientId), is_binary(Mac), is_integer(Ip), is_binary(Hostname) -> + gen_server:call(Pid, {attach, ChannelPid, Transport, ClientId, Mac, Ip, Hostname}). -spec unregister(Pid :: pid(), ClientId :: binary(), Mac :: binary()) -> ok. unregister(Pid, ClientId, Mac) when is_pid(Pid), is_binary(ClientId), is_binary(Mac) -> @@ -209,7 +211,7 @@ init([{network, Id, Name, Domain, IpAddr, MaskLen, OwnerId, Algorithm0}]) -> {stop, Reason :: term(), Reply :: term(), NewState :: #state{}} | {stop, Reason :: term(), NewState :: #state{}}). %% 给客户端分配ip地址 -handle_call({attach, ChannelPid, ClientId, Mac, Ip, Hostname}, _From, +handle_call({attach, ChannelPid, Transport, ClientId, Mac, Ip, Hostname}, _From, State = #state{network_id = NetworkId, domain = Domain, algorithm = Algorithm, key = Key, endpoint_table = EndpointTable}) -> %% 分配ip地址的时候,以mac地址为唯一基准 logger:debug("[sdlan_network] alloc_ip, network_id: ~p, client_id: ~p, mac: ~p, ip_addr: ~p", @@ -225,6 +227,7 @@ handle_call({attach, ChannelPid, ClientId, Mac, Ip, Hostname}, _From, Endpoint = #endpoint{ channel_pid = ChannelPid, channel_ref = ChannelRef, + transport = Transport, client_id = ClientId, mac = Mac, ip = Ip, @@ -270,7 +273,7 @@ handle_call(get_network_id, _From, State = #state{network_id = NetworkId}) -> %% 网络存在的nat_peer信息 handle_call({peer_info, SrcMac, DstMac}, _From, State = #state{endpoint_table = EndpointTable}) -> case lookup_endpoint(EndpointTable, DstMac) of - #endpoint{channel_pid = DstChannelPid, hole = #hole{peer = DstNatPeer, nat_type = DstNatType}, v6_info = DstV6Info} -> + #endpoint{channel_pid = DstChannelPid, transport = Transport, hole = #hole{peer = DstNatPeer, nat_type = DstNatType}, v6_info = DstV6Info} -> %% 让目标服务器发送sendRegister事件(2024-06-25 新增,提高打洞的成功率) maybe #endpoint{hole = #hole{peer = {SrcNatIp, SrcNatPort}, nat_type = SrcNatType}, v6_info = SrcV6Info} ?= lookup_endpoint(EndpointTable, SrcMac), @@ -286,7 +289,7 @@ handle_call({peer_info, SrcMac, DstMac}, _From, State = #state{endpoint_table = }), logger:debug("Event: send_register, for peer_info"), - sdlan_quic_transport:send_event(DstChannelPid, RegisterEvent) + Transport:send_event(DstChannelPid, RegisterEvent) end, {reply, {ok, {DstNatPeer, DstNatType}, DstV6Info}, State}; _ -> @@ -311,9 +314,9 @@ handle_call({command, ReceiverPid, ClientId, SubCommand}, _From, State = #state{ Object end), case select_endpoint(EndpointTable, MatchSpec) of - {ok, _Mac, #endpoint{channel_pid = ChannelPid}} -> + {ok, _Mac, #endpoint{channel_pid = ChannelPid, transport = Transport}} -> Ref = make_ref(), - sdlan_quic_transport:command(ChannelPid, Ref, ReceiverPid, SubCommand), + Transport:command(ChannelPid, Ref, ReceiverPid, SubCommand), {reply, {ok, Ref}, State}; error -> {reply, {error, <<"目标Node不在线"/utf8>>}, State} @@ -325,9 +328,9 @@ handle_call({acl_changed, ReceiverPid, ClientId, SubCommand}, _From, State = #st Object end), case select_endpoint(EndpointTable, MatchSpec) of - {ok, _Mac, #endpoint{channel_pid = ChannelPid}} -> + {ok, _Mac, #endpoint{channel_pid = ChannelPid, transport = Transport}} -> Ref = make_ref(), - sdlan_quic_transport:command(ChannelPid, Ref, ReceiverPid, SubCommand), + Transport:command(ChannelPid, Ref, ReceiverPid, SubCommand), {reply, {ok, Ref}, State}; error -> {reply, {error, <<"目标Node不在线"/utf8>>}, State} @@ -380,8 +383,8 @@ handle_cast({update_hole, SessionToken, ClientId, Mac, Peer, NatType, V6Info}, S }), logger:debug("[sdlan_network] Event: nat_changed, update_hole, client_id: ~p(~p), hole changed", [ClientId, Ip]), - broadcast(fun(#endpoint{channel_pid = ChannelPid}) -> - sdlan_quic_transport:send_event(ChannelPid, NatChangedEvent) + broadcast(fun(#endpoint{channel_pid = ChannelPid, transport = Transport}) -> + Transport:send_event(ChannelPid, NatChangedEvent) end, [Mac], EndpointTable) end, NEndpoint = Endpoint0#endpoint{hole = NHole, v6_info = V6Info, last_seen = erlang:monotonic_time(second)}, @@ -417,7 +420,7 @@ handle_info(Info, State) -> -spec(terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()), State :: #state{}) -> ok). terminate(Reason, #state{network_id = NetworkId, endpoint_table = EndpointTable}) -> - broadcast(fun(#endpoint{channel_pid = ChannelPid}) -> + broadcast(fun(#endpoint{channel_pid = ChannelPid, transport = Transport}) -> case is_pid(ChannelPid) andalso is_process_alive(ChannelPid) of true -> NetworkShutdownEvent = sdlan_pb:encode_msg(#'SDLEvent'{ @@ -428,8 +431,8 @@ terminate(Reason, #state{network_id = NetworkId, endpoint_table = EndpointTable} logger:debug("[sdlan_network] Event: shutdown"), - sdlan_quic_transport:send_event(ChannelPid, NetworkShutdownEvent), - sdlan_quic_transport:stop(ChannelPid, normal); + Transport:send_event(ChannelPid, NetworkShutdownEvent), + Transport:stop(ChannelPid, normal); false -> ok end @@ -589,8 +592,8 @@ maybe_nat_changed(ChannelPid, Mac, Ip, EndpointTable) -> }), logger:debug("Event: nat_changed, for attach"), - broadcast(fun(#endpoint{channel_pid = ChannelPid0}) -> - sdlan_quic_transport:send_event(ChannelPid0, Event) + broadcast(fun(#endpoint{channel_pid = ChannelPid0, transport = Transport}) -> + Transport:send_event(ChannelPid0, Event) end, [Mac], EndpointTable) end, %% 重复attach需要清理之前的绑定信息;即使IP未变化,也不能保留旧channel。 @@ -598,11 +601,11 @@ maybe_nat_changed(ChannelPid, Mac, Ip, EndpointTable) -> cleanup_endpoint(undefined, _KeepChannelPid, _Reason) -> ok; -cleanup_endpoint(#endpoint{channel_ref = ChannelRef, channel_pid = ChannelPid}, KeepChannelPid, Reason) -> +cleanup_endpoint(#endpoint{channel_ref = ChannelRef, channel_pid = ChannelPid, transport = Transport}, KeepChannelPid, Reason) -> is_reference(ChannelRef) andalso erlang:demonitor(ChannelRef, [flush]), case should_stop_channel(ChannelPid, KeepChannelPid) of true -> - catch sdlan_quic_transport:stop(ChannelPid, Reason), + catch Transport:stop(ChannelPid, Reason), ok; false -> ok diff --git a/src/sdlan_session.erl b/src/sdlan_session.erl index b07e6d7..08f691c 100644 --- a/src/sdlan_session.erl +++ b/src/sdlan_session.erl @@ -121,7 +121,7 @@ handle_frame(<>, Session = #session{status %% 建立到network的对应关系 case sdlan_network:get_pid(NetworkId) of NetworkPid when is_pid(NetworkPid) -> - {ok, Algorithm, Key, RegionId, SessionToken} = sdlan_network:attach(NetworkPid, self(), ClientId, Mac, Ip, HostName), + {ok, Algorithm, Key, RegionId, SessionToken} = sdlan_network:attach(NetworkPid, self(), Transport, ClientId, Mac, Ip, HostName), RsaPubKey = sdlan_cipher:rsa_pem_decode(PubKey), RegisterSuperAck = sdlan_pb:encode_msg(#'SDLRegisterSuperAck'{ algorithm = Algorithm, @@ -410,4 +410,4 @@ heartbeat_ms(_) -> ?PING_TICKER. parse_ports(Ports0) when is_list(Ports0) -> - lists:filter(fun(P0) -> is_integer(P0) andalso (P0 > 0 andalso P0 < 65535) end, Ports0). \ No newline at end of file + lists:filter(fun(P0) -> is_integer(P0) andalso (P0 > 0 andalso P0 < 65535) end, Ports0). diff --git a/src/ssl/sdlan_ssl_transport.erl b/src/ssl/sdlan_ssl_transport.erl index 90f425b..cd7df08 100644 --- a/src/ssl/sdlan_ssl_transport.erl +++ b/src/ssl/sdlan_ssl_transport.erl @@ -16,6 +16,9 @@ %% Ranch protocol callback -export([start_link/4]). +%% API +-export([send_event/2, command/4, stop/2, debug_info/1]). + %% gen_statem callbacks -export([init/1, handle_event/4, terminate/3, code_change/4, callback_mode/0]). @@ -36,6 +39,22 @@ %%% Ranch protocol callback %%%=================================================================== +-spec send_event(Pid :: pid(), Event :: binary()) -> ok. +send_event(Pid, ProtobufEvent) when is_pid(Pid), is_binary(ProtobufEvent) -> + gen_statem:cast(Pid, {send_event, ProtobufEvent}). + +-spec command(Pid :: pid(), Ref :: reference(), ReceiverPid :: pid(), {Tag :: atom(), SubCommand :: any()}) -> ok. +command(Pid, Ref, ReceiverPid, SubCommand) when is_pid(Pid), is_pid(ReceiverPid) -> + gen_statem:cast(Pid, {command, Ref, ReceiverPid, SubCommand}). + +-spec stop(Pid :: pid(), Reason :: term()) -> ok. +stop(Pid, Reason) when is_pid(Pid) -> + gen_statem:stop(Pid, Reason, 2000). + +-spec debug_info(Pid :: pid()) -> map(). +debug_info(Pid) when is_pid(Pid) -> + gen_statem:call(Pid, debug_info). + -spec start_link(Ref :: ranch:ref(), Socket :: inet:socket(), Transport :: module(), Limits :: proplists:proplist()) -> gen_statem:start_ret(). start_link(Ref, Socket, Transport, Limits) ->