ssl_server.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,376 行 · 第 1/3 页

ERL
1,376
字号
		_ ->		    {noreply, St#st{cons = Cons}}	    end;	_ ->	    case delete_by_pid(Pid, St#st.paccepts) of		{ok, {ListenFd, _, _}, PAccepts} ->		    %% decrement ref count in port program		    send_cmd(St#st.port, ?NOACCEPT, int32(ListenFd)),		    {noreply, St#st{paccepts = PAccepts}};		_ ->		    {noreply, St}	    end    end;%%%% 'badsig' means bad message to port. Port program is unaffected.%%handle_info({'EXIT', Port, badsig}, St) when St#st.port == Port ->    debug(St, "badsig!!!~n", []),    {noreply, St};handle_info({'EXIT', Port, Reason}, St) when St#st.port == Port ->    {stop, Reason, St};handle_info(Info, St) ->    debug(St, "unexpected info: ~w~n", [Info]),    {noreply, St}.%%%% terminate(Reason, St) -> any%%terminate(_Reason, _St) ->    ok.%% %% code_change(OldVsn, St, Extra) -> {ok, NSt}%%code_change(_OldVsn, St, _Extra) ->    {ok, St}.%%%----------------------------------------------------------------------%%% Internal functions%%%----------------------------------------------------------------------%%%% Send binary command to sock%%send_cmd(Port, Cmd, Args) ->    Port ! {self(), {command, [Cmd| Args]}}.%%%% add(Descr, Cons) -> NCons%%add(D, L) ->     [D| L].%%%% get_by_fd(Fd, Cons) -> {ok, Descr} | not_found%%get_by_fd(Fd, Cons) ->    get_by_pos(Fd, 1, Cons).%%%% delete_by_fd(Fd, Cons) -> {ok, OldDesc, NewCons} | not_found.%%delete_by_fd(Fd, Cons) ->    delete_by_pos(Fd, 1, Cons).%%%% delete_all_by_fd(Fd, Cons) -> {ok, DelCons, RemCons} | not_found.%%delete_all_by_fd(Fd, Cons) ->    delete_all_by_pos(Fd, 1, Cons).%%%% delete_by_intref(IntRef, Cons) -> {ok, OldDesc, NewCons} | not_found.%%delete_by_intref(IntRef, Cons) ->    delete_by_pos({intref, IntRef}, 1, Cons).%%%% delete_by_pid(Pid, Cons) -> {ok, OldDesc, NewCons} | not_found.%%delete_by_pid(Pid, Cons) ->    delete_by_pos(Pid, 2, Cons).%%%% delete_last_by_fd(Fd, Cons) -> {ok, OldDesc, NCons} | not_found%%delete_last_by_fd(Fd, Cons) ->    case dlbf(Fd, Cons) of 	{X, L} ->	    {ok, X, L};	_Other  ->	    not_found    end.dlbf(Fd, [H]) ->     last_elem(Fd, H, []);dlbf(Fd, [H|T]) ->    case dlbf(Fd, T) of	{X, L} -> 	    {X, [H|L]};	L -> 	    last_elem(Fd, H, L)    end;dlbf(_Fd, []) ->      [].last_elem(Fd, H, L) when element(1, H) == Fd ->    {H, L};last_elem(_, H, L) ->    [H|L].%%%% replace_from_by_fd(Fd, Cons, From) -> {ok, OldDesc, NewList} | not_found%%replace_from_by_fd(Fd, Cons, From) ->    replace_posn_by_pos(Fd, 1, Cons, [{From, 3}]).%%%% replace_fd_by_intref(IntRef, Cons, Fd) -> {ok, OldDesc, NewList} | not_f.%%replace_fd_by_intref(IntRef, Cons, Fd) ->    replace_posn_by_pos({intref, IntRef}, 1, Cons, [{Fd, 1}]).%%%% replace_fd_from_by_intref(IntRef, Cons, NFd, From) -> %%					{ok, OldDesc, NewList} |  not_found%%replace_fd_from_by_intref(IntRef, Cons, NFd, From) ->    replace_posn_by_pos({intref, IntRef}, 1, Cons, [{NFd, 1}, {From, 3}]).%%%% All *_by_pos functions%%get_by_pos(Key, Pos, [H|_]) when element(Pos, H) == Key ->     {ok, H};get_by_pos(Key, Pos, [_|T]) ->     get_by_pos(Key, Pos, T);get_by_pos(_, _, []) ->     not_found.delete_by_pos(Key, Pos, Cons) ->    case delete_by_pos1(Key, Pos, {not_found, Cons}) of	{not_found, _} ->	    not_found;	{ODesc, NCons} ->	    {ok, ODesc, NCons}    end.delete_by_pos1(Key, Pos, {_R, [H|T]}) when element(Pos, H) == Key ->    {H, T};delete_by_pos1(Key, Pos, {R, [H|T]}) ->    {R0, T0} = delete_by_pos1(Key, Pos, {R, T}),    {R0, [H| T0]};delete_by_pos1(_, _, {R, []}) ->    {R, []}.delete_all_by_pos(Key, Pos, Cons) ->    case lists:foldl(fun(H, {Ds, Rs}) when element(Pos, H) == Key ->			     {[H|Ds], Rs};			(H, {Ds, Rs}) ->			     {Ds, [H|Rs]} 		     end, {[], []}, Cons) of	{[], _} ->	    not_found;	{DelCons, RemCons} ->	    {ok, DelCons, RemCons}    end.replace_posn_by_pos(Key, Pos, Cons, Repls) ->    replace_posn_by_pos1(Key, Pos, Cons, Repls, []).replace_posn_by_pos1(Key, Pos, [H0| T], Repls, Acc)  when element(Pos, H0) =:= Key ->    H = lists:foldl(fun({Val, VPos}, Tuple) -> 			    setelement(VPos, Tuple, Val) 		    end, H0, Repls),     {ok, H0, lists:reverse(Acc, [H| T])};replace_posn_by_pos1(Key, Pos, [H|T], Repls, Acc) ->    replace_posn_by_pos1(Key, Pos, T, Repls, [H| Acc]);replace_posn_by_pos1(_, _, [], _, _) ->    not_found.%%%% Binary/integer conversions%%int16(I) ->    %%[(I bsr 8) band 255, I band 255].    <<I:16>>.int32(I) ->     %%     [(I bsr 24) band 255,    %%      (I bsr 16) band 255,    %%      (I bsr  8) band 255,    %%      I band 255].    <<I:32>>.%% decode_msg(Bin, Format) -> Tuple | integer() | atom() | string() | %%				list of binaries()%%%% Decode message from binary%% Format = [spec()]%% spec() = int16 | int32 | string | atom | bin | bins%%%% Notice:  The first byte (op code) of the binary message is removed.%% Notice:  bins returns a *list* of binaries. %%  decode_msg(<<_, Bin/binary>>, Format) ->    Dec = dec(Format, Bin),    if 	length(Dec) == 1 ->	    hd(Dec);	true  ->	    list_to_tuple(Dec)    end.dec([], _) ->    [];dec([int16| F], <<N:16, Bin/binary>>) ->    [N| dec(F, Bin)];dec([int32| F], <<N:32, Bin/binary>>) ->    [N| dec(F, Bin)];dec([string| F], Bin0) ->    {Cs, Bin1} = dec_string(Bin0),    [Cs| dec(F, Bin1)];dec([atom|F], Bin0) ->    {Cs, Bin1} = dec_string(Bin0),    [list_to_atom(Cs)| dec(F, Bin1)];dec([bin|F], Bin) ->    {Bin1, Bin2} = dec_bin(Bin),    [Bin1| dec(F, Bin2)].%% NOTE: This clause is not actually used yet.%% dec([bins|F], <<N:32, Bin0/binary>>) ->%%     {Bins, Bin1} = dec_bins(N, Bin0),%%     [Bins| dec(F, Bin1)].dec_string(Bin) ->    dec_string(Bin, []).dec_string(<<0, Bin/binary>>, RCs) ->    {lists:reverse(RCs), Bin};dec_string(<<C, Bin/binary>>, RCs) ->    dec_string(Bin, [C| RCs]).dec_bin(<<L:32, Bin0/binary>>) ->    <<Bin1:L/binary, Bin2/binary>> = Bin0,    {Bin1, Bin2}.%% dec_bins(N, Bin) ->%%     dec_bins(N, Bin, []).%% dec_bins(0, Bin, Acc) ->%%     {lists:reverse(Acc), Bin};%% dec_bins(N, Bin0, Acc) when N > 0 ->%%     {Bin1, Bin2} = dec_bin(Bin0),%%     dec_bins(N - 1, Bin2, [Bin1| Acc]).%%%% new_intref%%new_intref(St) ->    (St#st.intref + 1) band 16#ffffffff.%%%% {Program, Flags} = mk_cmd_line(DefaultProgram)%%mk_cmd_line(Default) ->    {port_program(Default),      lists:flatten([debug_flag(), " ", debugdir_flag(), " ", 		    msgdebug_flag(), " ", proxylsport_flag(), " ", 		    proxybacklog_flag(), " ", ephemeral_rsa_flag(), " ",		    ephemeral_dh_flag(), " ",		    protocol_version_flag(), " "])}.port_program(Default) ->    case application:get_env(ssl, port_program) of	{ok, Program} when list(Program) ->	    Program;	_Other ->	    Default    end.%%%% As this server may be started by the distribution, it is not safe to assume %% a working code server, neither a working file server.%% I try to utilize the most primitive interfaces available to determine%% the directory of the port_program.%%find_priv_bin() ->    PrivDir = case (catch code:priv_dir(ssl)) of		  {'EXIT', _} ->		      %% Code server probably not startet yet		      {ok, P} = erl_prim_loader:get_path(),		      ModuleFile = atom_to_list(?MODULE) ++ extension(),		      Pd = (catch lists:foldl			    (fun(X,Acc) ->				     M = filename:join([X, ModuleFile]),				     %% The file server probably not started				     %% either, has to use raw interface.				     case file:raw_read_file_info(M) of 					 {ok,_} -> 					     %% Found our own module in the					     %% path, lets bail out with					     %% the priv_dir of this directory					     Y = filename:split(X),					     throw(filename:join						   (lists:sublist						    (Y,length(Y) - 1) 						    ++ ["priv"])); 					 _ -> 					     Acc 				     end 			     end,			     false,P)),		      case Pd of			  false ->			      exit(ssl_priv_dir_indeterminate);			  _ ->			      Pd		      end;		  Dir ->		      Dir	      end,    filename:join([PrivDir, "bin"]).extension() ->    %% erlang:info(machine) returns machine name as text in all uppercase    "." ++ lists:map(fun(X) ->			     X + $a - $A		     end,		     erlang:system_info(machine)).debug_flag() ->    case os:getenv("ERL_SSL_DEBUG") of	false ->	    get_env(debug, "-d");	_ ->	    "-d"    end.msgdebug_flag() ->    case os:getenv("ERL_SSL_MSGDEBUG") of	false ->	    get_env(msgdebug, "-dm");	_  ->	    "-dm"    end.proxylsport_flag() ->    case application:get_env(ssl, proxylsport) of	{ok, PortNum} ->	    "-pp " ++ integer_to_list(PortNum);	_Other ->	    ""    end.proxybacklog_flag() ->    case application:get_env(ssl, proxylsbacklog) of	{ok, Size} ->	    "-pb " ++ integer_to_list(Size);	_Other ->	    ""    end.debugdir_flag() ->    case os:getenv("ERL_SSL_DEBUG") of	false ->	    case application:get_env(ssl, debugdir) of		{ok, Dir} when list(Dir) ->		    "-dd " ++ Dir;		_Other ->		    ""	    end;	_  ->	    "-dd ./"    end.    ephemeral_rsa_flag() ->    case application:get_env(ssl, ephemeral_rsa) of	{ok, true} ->	    "-ersa ";	_Other ->	    ""    end.ephemeral_dh_flag() ->    case application:get_env(ssl, ephemeral_dh) of	{ok, true} ->	    "-edh ";	_Other ->	    ""    end.protocol_version_flag() ->    case application:get_env(ssl, protocol_version) of	{ok, []} ->	    "";	{ok, Vsns} when list(Vsns) ->	    case transform_vsns(Vsns) of		N when (N > 0) ->		    "-pv " ++ integer_to_list(N);		_ ->		    ""	    end;	_Other ->	    ""    end.transform_vsns(Vsns) ->    transform_vsns(Vsns, 0).transform_vsns([sslv2| Vsns], I) ->    transform_vsns(Vsns, I bor ?SSLv2);transform_vsns([sslv3| Vsns], I) ->    transform_vsns(Vsns, I bor ?SSLv3);transform_vsns([tlsv1| Vsns], I) ->    transform_vsns(Vsns, I bor ?TLSv1);transform_vsns([_ | Vsns], I) ->    transform_vsns(Vsns, I);transform_vsns([], I) ->    I.protocol_name("SSLv2") -> sslv2;protocol_name("SSLv3") -> sslv3;protocol_name("TLSv1") -> tlsv1.get_env(Key, Val) ->    case application:get_env(ssl, Key) of	{ok, true} ->	    Val;	_Other ->	    ""    end.ip_to_string({A,B,C,D}) ->    [integer_to_list(A),$.,integer_to_list(B),$.,     integer_to_list(C),$.,integer_to_list(D)].debug(St, Format, Args) ->    debug1(St#st.debug, Format, Args).debug1(true, Format0, Args) ->    {_MS, S, MiS} = erlang:now(),    Secs = S rem 100,     MiSecs = MiS div 1000,    Format = "++++ ~3..0w:~3..0w ssl_server (~w): " ++ Format0,     io:format(Format, [Secs, MiSecs, self()| Args]);debug1(_, _, _) ->    ok.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?