diff options
Diffstat (limited to 'lib/orber/src')
-rw-r--r-- | lib/orber/src/orber.erl | 19 | ||||
-rw-r--r-- | lib/orber/src/orber_env.erl | 42 | ||||
-rw-r--r-- | lib/orber/src/orber_socket.erl | 58 |
3 files changed, 85 insertions, 34 deletions
diff --git a/lib/orber/src/orber.erl b/lib/orber/src/orber.erl index e9c6822551..c3d37ad1fb 100644 --- a/lib/orber/src/orber.erl +++ b/lib/orber/src/orber.erl @@ -1,20 +1,20 @@ %%-------------------------------------------------------------------- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -34,7 +34,8 @@ %% External exports %%----------------------------------------------------------------- -export([start/0, start/1, stop/0, install/1, install/2, orber_nodes/0, iiop_port/0, - domain/0, iiop_ssl_port/0, iiop_out_ports/0, + domain/0, iiop_ssl_port/0, iiop_out_ports/0, iiop_out_ports_random/0, + iiop_out_ports_attempts/0, ssl_server_certfile/0, ssl_client_certfile/0, set_ssl_client_certfile/1, ssl_server_verify/0, ssl_client_verify/0, set_ssl_client_verify/1, ssl_server_depth/0, ssl_client_depth/0, set_ssl_client_depth/1, @@ -305,6 +306,12 @@ nat_iiop_port() -> iiop_out_ports() -> orber_env:iiop_out_ports(). +iiop_out_ports_random() -> + orber_env:iiop_out_ports_random(). + +iiop_out_ports_attempts() -> + orber_env:iiop_out_ports_attempts(). + orber_nodes() -> case catch mnesia:table_info(orber_objkeys,ram_copies) of Nodes when is_list(Nodes) -> diff --git a/lib/orber/src/orber_env.erl b/lib/orber/src/orber_env.erl index 79f852eee0..d80edb4ee0 100644 --- a/lib/orber/src/orber_env.erl +++ b/lib/orber/src/orber_env.erl @@ -1,20 +1,20 @@ %%-------------------------------------------------------------------- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -43,8 +43,8 @@ -export([iiop_acl/0, iiop_port/0, nat_iiop_port/0, nat_iiop_port/1, iiop_out_ports/0, domain/0, ip_address_variable_defined/0, nat_host/0, nat_host/1, host/0, - ip_address/0, ip_address/1, giop_version/0, iiop_timeout/0, - iiop_connection_timeout/0, iiop_setup_connection_timeout/0, + ip_address/0, ip_address/1, giop_version/0, iiop_timeout/0, iiop_out_ports_random/0, + iiop_connection_timeout/0, iiop_setup_connection_timeout/0, iiop_out_ports_attempts/0, iiop_in_connection_timeout/0, iiop_max_fragments/0, iiop_max_in_requests/0, iiop_max_in_connections/0, iiop_backlog/0, objectkeys_gc_time/0, get_ORBInitRef/0, get_ORBDefaultInitRef/0, get_interceptors/0, @@ -234,6 +234,8 @@ create_main_info() -> "IIOP out connection timeout...: ~p msec~n" "IIOP setup connection timeout.: ~p msec~n" "IIOP out ports................: ~p~n" + "IIOP out ports attempts.......: ~p~n" + "IIOP out ports random.........: ~p~n" "IIOP out connections..........: ~p~n" "IIOP out connections (pending): ~p~n" "IIOP out keepalive............: ~p~n" @@ -256,7 +258,8 @@ create_main_info() -> nat_host(), ip_address_local(), orber:orber_nodes(), Major, Minor, iiop_timeout(), iiop_connection_timeout(), - iiop_setup_connection_timeout(), iiop_out_ports(), + iiop_setup_connection_timeout(), iiop_out_ports(), + iiop_out_ports_attempts(), iiop_out_ports_random(), orber:iiop_connections(out), orber:iiop_connections_pending(), iiop_out_keepalive(), orber:iiop_connections(in), iiop_in_connection_timeout(), iiop_in_keepalive(), @@ -389,6 +392,23 @@ iiop_out_ports() -> 0 end. +iiop_out_ports_random() -> + case application:get_env(orber, iiop_out_ports_random) of + {ok, true} -> + true; + _ -> + false + end. + +iiop_out_ports_attempts() -> + case application:get_env(orber, iiop_out_ports_attempts) of + {ok, No} when is_integer(No) andalso No > 0 -> + No; + _ -> + 1 + end. + + domain() -> case application:get_env(orber, domain) of {ok, Domain} when is_list(Domain) -> @@ -1251,6 +1271,12 @@ configure(nat_ip_address, {local, Value1, Value2}, Status) when is_list(Value1) %% Set the range of ports we may use on this machine when connecting to a server. configure(iiop_out_ports, {Min, Max}, Status) when is_integer(Min) andalso is_integer(Max) -> do_safe_configure(iiop_out_ports, {Min, Max}, Status); +configure(iiop_out_ports_attempts, Max, Status) when is_integer(Max) andalso Max > 0 -> + do_safe_configure(iiop_out_ports_attempts, Max, Status); +configure(iiop_out_ports_random, true, Status) -> + do_safe_configure(iiop_out_ports_random, true, Status); +configure(iiop_out_ports_random, false, Status) -> + do_safe_configure(iiop_out_ports_random, false, Status); %% Set the lightweight option. configure(lightweight, Value, Status) when is_list(Value) -> do_safe_configure(lightweight, Value, Status); diff --git a/lib/orber/src/orber_socket.erl b/lib/orber/src/orber_socket.erl index 2a64bd4e75..af6df01b7d 100644 --- a/lib/orber/src/orber_socket.erl +++ b/lib/orber/src/orber_socket.erl @@ -1,20 +1,20 @@ %%-------------------------------------------------------------------- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %% @@ -82,17 +82,17 @@ connect(Type, Host, Port, Options) -> end, case orber:iiop_out_ports() of {Min, Max} when Type == normal -> - multi_connect(Min, Max, Type, Host, Port, - [binary, {reuseaddr, true}, - {packet,cdr}| Options2], Timeout); + multi_connect(get_port_sequence(Min, Max), orber_env:iiop_out_ports_attempts(), + Type, Host, Port, [binary, {reuseaddr, true}, + {packet,cdr}| Options2], Timeout); {Min, Max} when Generation > 2 -> - multi_connect(Min, Max, Type, Host, Port, - [binary, {reuseaddr, true}, - {packet,cdr}| Options2], Timeout); + multi_connect(get_port_sequence(Min, Max), orber_env:iiop_out_ports_attempts(), + Type, Host, Port, [binary, {reuseaddr, true}, + {packet,cdr}| Options2], Timeout); {Min, Max} -> %% reuseaddr not available for older SSL versions - multi_connect(Min, Max, Type, Host, Port, - [binary, {packet,cdr}| Options2], Timeout); + multi_connect(get_port_sequence(Min, Max), orber_env:iiop_out_ports_attempts(), + Type, Host, Port, [binary, {packet,cdr}| Options2], Timeout); _ -> connect(Type, Host, Port, [binary, {packet,cdr}| Options2], Timeout) end. @@ -130,17 +130,17 @@ connect(ssl, Host, Port, Options, Timeout) -> corba:raise(#'COMM_FAILURE'{completion_status=?COMPLETED_NO}) end. -multi_connect(CurrentPort, Max, Type, Host, Port, Options, _) when CurrentPort > Max -> +multi_connect([], _Retries, Type, Host, Port, Options, _) -> orber:dbg("[~p] orber_socket:multi_connect(~p, ~p, ~p, ~p);~n" "Unable to use any of the sockets defined by 'iiop_out_ports'.~n" "Either all ports are in use or to many connections already exists.", [?LINE, Type, Host, Port, Options], ?DEBUG_LEVEL), corba:raise(#'IMP_LIMIT'{minor=(?ORBER_VMCID bor 1), completion_status=?COMPLETED_NO}); -multi_connect(CurrentPort, Max, normal, Host, Port, Options, Timeout) -> +multi_connect([CurrentPort|Rest], Retries, normal, Host, Port, Options, Timeout) -> case catch gen_tcp:connect(Host, Port, [{port, CurrentPort}|Options], Timeout) of {ok, Socket} -> Socket; - {error, timeout} -> + {error, timeout} when Retries =< 1 -> orber:dbg("[~p] orber_socket:multi_connect(normal, ~p, ~p, ~p);~n" "Timeout after ~p msec.", [?LINE, Host, Port, [{port, CurrentPort}|Options], @@ -148,13 +148,13 @@ multi_connect(CurrentPort, Max, normal, Host, Port, Options, Timeout) -> corba:raise(#'COMM_FAILURE'{minor=(?ORBER_VMCID bor 4), completion_status=?COMPLETED_NO}); _ -> - multi_connect(CurrentPort+1, Max, normal, Host, Port, Options, Timeout) + multi_connect(Rest, Retries - 1, normal, Host, Port, Options, Timeout) end; -multi_connect(CurrentPort, Max, ssl, Host, Port, Options, Timeout) -> +multi_connect([CurrentPort|Rest], Retries, ssl, Host, Port, Options, Timeout) -> case catch ssl:connect(Host, Port, [{port, CurrentPort}|Options], Timeout) of {ok, Socket} -> Socket; - {error, timeout} -> + {error, timeout} when Retries =< 1 -> orber:dbg("[~p] orber_socket:multi_connect(ssl, ~p, ~p, ~p);~n" "Timeout after ~p msec.", [?LINE, Host, Port, [{port, CurrentPort}|Options], @@ -162,10 +162,28 @@ multi_connect(CurrentPort, Max, ssl, Host, Port, Options, Timeout) -> corba:raise(#'COMM_FAILURE'{minor=(?ORBER_VMCID bor 4), completion_status=?COMPLETED_NO}); _ -> - multi_connect(CurrentPort+1, Max, ssl, Host, Port, Options, Timeout) + multi_connect(Rest, Retries - 1, ssl, Host, Port, Options, Timeout) end. +get_port_sequence(Min, Max) -> + case orber_env:iiop_out_ports_random() of + true -> + {A1,A2,A3} = now(), + random:seed(A1, A2, A3), + Seq = lists:seq(Min, Max), + random_sequence((Max - Min) + 1, Seq, []); + _ -> + lists:seq(Min, Max) + end. + +random_sequence(0, _, Acc) -> + Acc; +random_sequence(Length, Seq, Acc) -> + Nth = random:uniform(Length), + Value = lists:nth(Nth, Seq), + NewSeq = lists:delete(Value, Seq), + random_sequence(Length-1, NewSeq, [Value|Acc]). %%----------------------------------------------------------------- %% Create a listen socket at Port in CDR mode for |