-module(ntPptAcceptor).
|
|
|
|
-include("eNet.hrl").
|
|
-include("ntCom.hrl").
|
|
-include("proxyPt.hrl").
|
|
|
|
-compile(inline).
|
|
-compile({inline_size, 128}).
|
|
|
|
-export([
|
|
start_link/8
|
|
|
|
, pptAndHS/5
|
|
|
|
, init/1
|
|
, handleMsg/2
|
|
|
|
, init_it/2
|
|
, system_code_change/4
|
|
, system_continue/3
|
|
, system_get_state/1
|
|
, system_terminate/4
|
|
]).
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% genActor start %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
-spec start_link(list(), timeout(), boolean(), timeout(), inet:socket(), module(), term(), [proc_lib:spawn_option()]) -> {ok, pid()}.
|
|
start_link(SslOpts, SslHSTet, ProxyPt, ProxyPtTet, LSock, ConMod, ConArgs, SpawnOpts) ->
|
|
proc_lib:start_link(?MODULE, init_it, [self(), {SslOpts, SslHSTet, ProxyPt, ProxyPtTet, LSock, ConMod, ConArgs}], infinity, SpawnOpts).
|
|
|
|
init_it(Parent, Args) ->
|
|
process_flag(trap_exit, true),
|
|
modInit(Parent, Args).
|
|
|
|
-spec system_code_change(term(), module(), undefined | term(), term()) -> {ok, term()}.
|
|
system_code_change(State, _Module, _OldVsn, _Extra) ->
|
|
{ok, State}.
|
|
|
|
-spec system_continue(pid(), [], {module(), atom(), pid(), term()}) -> ok.
|
|
system_continue(_Parent, _Debug, {Parent, State}) ->
|
|
loop(Parent, State).
|
|
|
|
-spec system_get_state(term()) -> {ok, term()}.
|
|
system_get_state(State) ->
|
|
{ok, State}.
|
|
|
|
-spec system_terminate(term(), pid(), [], term()) -> none().
|
|
system_terminate(Reason, _Parent, _Debug, _State) ->
|
|
exit(Reason).
|
|
|
|
modInit(Parent, Args) ->
|
|
case init(Args) of
|
|
{ok, State} ->
|
|
proc_lib:init_ack(Parent, {ok, self()}),
|
|
loop(Parent, State);
|
|
{stop, Reason} ->
|
|
proc_lib:init_ack(Parent, {error, Reason}),
|
|
exit(Reason)
|
|
end.
|
|
|
|
loop(Parent, State) ->
|
|
receive
|
|
{system, From, Request} ->
|
|
sys:handle_system_msg(Request, From, Parent, ?MODULE, [], {Parent, State});
|
|
{'EXIT', Parent, Reason} ->
|
|
exit(Reason);
|
|
Msg ->
|
|
case handleMsg(Msg, State) of
|
|
{ok, NewState} ->
|
|
loop(Parent, NewState);
|
|
{stop, Reason} ->
|
|
exit(Reason)
|
|
end
|
|
end.
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% genActor end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
-record(state, {
|
|
lSock
|
|
, sslOpts
|
|
, sslHSTet
|
|
, proxyPt
|
|
, proxyPtTet
|
|
, ref
|
|
, conMod
|
|
, conArgs
|
|
, sockMod
|
|
}).
|
|
|
|
-spec init(Args :: term()) -> ok.
|
|
init({SslOpts, SslHSTet, ProxyPt, ProxyPtTet, LSock, ConMod, ConArgs}) ->
|
|
case prim_inet:async_accept(LSock, -1) of
|
|
{ok, Ref} ->
|
|
{ok, SockMod} = inet_db:lookup_socket(LSock),
|
|
{ok, #state{lSock = LSock, sslOpts = SslOpts, sslHSTet = SslHSTet, proxyPt = ProxyPt, proxyPtTet = ProxyPtTet, ref = Ref, conMod = ConMod, conArgs = ConArgs, sockMod = SockMod}};
|
|
{error, Reason} ->
|
|
?ntErr("init prim_inet:async_accept error ~p~n", [Reason]),
|
|
{stop, Reason}
|
|
end.
|
|
|
|
handleMsg({inet_async, LSock, Ref, Msg}, #state{lSock = LSock, sslOpts = SslOpts, sslHSTet = SslHSTet, proxyPt = ProxyPt, proxyPtTet = ProxyPtTet, ref = Ref, conMod = ConMod, conArgs = ConArgs, sockMod = SockMod} = State) ->
|
|
case Msg of
|
|
{ok, Sock} ->
|
|
%% make it look like gen_tcp:accept
|
|
inet_db:register_socket(Sock, SockMod),
|
|
try ConMod:newConn(Sock, ConArgs) of
|
|
{ok, Pid} ->
|
|
gen_tcp:controlling_process(Sock, Pid),
|
|
Pid ! {?mSockReady, Sock, SslOpts, SslHSTet, ProxyPt, ProxyPtTet},
|
|
newAsyncAccept(LSock, State);
|
|
{close, Reason} ->
|
|
?ntErr("handleMsg ConMod:newAcceptor return close ~p~n", [Reason]),
|
|
catch port_close(Sock),
|
|
newAsyncAccept(LSock, State);
|
|
_Ret ->
|
|
?ntErr("ConMod:newAcceptor return error ~p~n", [_Ret]),
|
|
{stop, error_ret}
|
|
catch
|
|
E:R:S ->
|
|
?ntErr("CliMod:newConnect crash: ~p:~p~n~p~n ~n ", [E, R, S]),
|
|
newAsyncAccept(LSock, State)
|
|
end;
|
|
{error, closed} ->
|
|
% ?ntErr("error, closed listen sock error ~p~n", [closed]),
|
|
{stop, normal};
|
|
{error, Reason} ->
|
|
?ntErr("listen sock error ~p~n", [Reason]),
|
|
{stop, {lsock, Reason}}
|
|
end;
|
|
handleMsg(_Msg, State) ->
|
|
?ntErr("~p receive unexpected ~p msg: ~p", [?MODULE, self(), _Msg]),
|
|
{ok, State}.
|
|
|
|
newAsyncAccept(LSock, State) ->
|
|
case prim_inet:async_accept(LSock, -1) of
|
|
{ok, Ref} ->
|
|
{ok, State#state{ref = Ref}};
|
|
{error, Reason} ->
|
|
?ntErr("~p prim_inet:async_accept error ~p~n", [?MODULE, Reason]),
|
|
{stop, Reason}
|
|
end.
|
|
|
|
pptAndHS(OSock, SslOpts, SslHSTet, ProxyPt, ProxyPtTet) ->
|
|
PptRet =
|
|
case ProxyPt of
|
|
true ->
|
|
nt_proxy_protocol:recv(OSock, ProxyPtTet);
|
|
_ ->
|
|
{ok, OSock, #proxy_socket{}}
|
|
end,
|
|
|
|
case PptRet of
|
|
{ok, TemSock, ProxySock} ->
|
|
case SslOpts /= undefined of
|
|
true ->
|
|
case ssl:handshake(TemSock, SslOpts, SslHSTet) of
|
|
{ok, SslSock} ->
|
|
{ok, SslSock, ProxySock};
|
|
{ok, SslSock, _Ext} -> %% OTP 21.0
|
|
{ok, SslSock, ProxySock};
|
|
{error, _} = Err -> Err
|
|
end;
|
|
_ ->
|
|
PptRet
|
|
end;
|
|
_ ->
|
|
PptRet
|
|
end.
|
|
|
|
|