aboutsummaryrefslogtreecommitdiffstats
path: root/lib/orber/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/orber/src')
-rw-r--r--lib/orber/src/orber.erl19
-rw-r--r--lib/orber/src/orber_env.erl42
-rw-r--r--lib/orber/src/orber_socket.erl58
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