1
1
%%--------------------------------------------------------------------
5
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
5
%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
7
7
%% The contents of this file are subject to the Erlang Public License,
8
8
%% Version 1.1, (the "License"); you may not use this file except in
9
9
%% compliance with the License. You should have received a copy of the
10
10
%% Erlang Public License along with this software. If not, it can be
11
11
%% retrieved online at http://www.erlang.org/.
13
13
%% Software distributed under the License is distributed on an "AS IS"
14
14
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
15
15
%% the License for the specific language governing rights and limitations
16
16
%% under the License.
37
37
%%-----------------------------------------------------------------
38
38
-export([start/0, connect/4, listen/3, listen/4, accept/2, accept/3, write/3,
39
39
controlling_process/3, close/2, peername/2, sockname/2,
40
peerdata/2, peercert/2, peercert/3, sockdata/2, setopts/3,
40
peerdata/2, peercert/2, sockdata/2, setopts/3,
41
41
clear/2, shutdown/3, post_accept/2, post_accept/3]).
43
43
%%-----------------------------------------------------------------
83
83
case orber:iiop_out_ports() of
84
84
{Min, Max} when Type == normal ->
85
multi_connect(Min, Max, Type, Host, Port,
86
[binary, {reuseaddr, true},
87
{packet,cdr}| Options2], Timeout);
85
multi_connect(get_port_sequence(Min, Max), orber_env:iiop_out_ports_attempts(),
86
Type, Host, Port, [binary, {reuseaddr, true},
87
{packet,cdr}| Options2], Timeout);
88
88
{Min, Max} when Generation > 2 ->
89
multi_connect(Min, Max, Type, Host, Port,
90
[binary, {reuseaddr, true},
91
{packet,cdr}| Options2], Timeout);
89
multi_connect(get_port_sequence(Min, Max), orber_env:iiop_out_ports_attempts(),
90
Type, Host, Port, [binary, {reuseaddr, true},
91
{packet,cdr}| Options2], Timeout);
93
93
%% reuseaddr not available for older SSL versions
94
multi_connect(Min, Max, Type, Host, Port,
95
[binary, {packet,cdr}| Options2], Timeout);
94
multi_connect(get_port_sequence(Min, Max), orber_env:iiop_out_ports_attempts(),
95
Type, Host, Port, [binary, {packet,cdr}| Options2], Timeout);
97
97
connect(Type, Host, Port, [binary, {packet,cdr}| Options2], Timeout)
130
130
corba:raise(#'COMM_FAILURE'{completion_status=?COMPLETED_NO})
133
multi_connect(CurrentPort, Max, Type, Host, Port, Options, _) when CurrentPort > Max ->
133
multi_connect([], _Retries, Type, Host, Port, Options, _) ->
134
134
orber:dbg("[~p] orber_socket:multi_connect(~p, ~p, ~p, ~p);~n"
135
135
"Unable to use any of the sockets defined by 'iiop_out_ports'.~n"
136
136
"Either all ports are in use or to many connections already exists.",
137
137
[?LINE, Type, Host, Port, Options], ?DEBUG_LEVEL),
138
138
corba:raise(#'IMP_LIMIT'{minor=(?ORBER_VMCID bor 1), completion_status=?COMPLETED_NO});
139
multi_connect(CurrentPort, Max, normal, Host, Port, Options, Timeout) ->
139
multi_connect([CurrentPort|Rest], Retries, normal, Host, Port, Options, Timeout) ->
140
140
case catch gen_tcp:connect(Host, Port, [{port, CurrentPort}|Options], Timeout) of
143
{error, timeout} when Retries =< 1 ->
144
144
orber:dbg("[~p] orber_socket:multi_connect(normal, ~p, ~p, ~p);~n"
145
145
"Timeout after ~p msec.",
146
146
[?LINE, Host, Port, [{port, CurrentPort}|Options],
148
148
corba:raise(#'COMM_FAILURE'{minor=(?ORBER_VMCID bor 4),
149
149
completion_status=?COMPLETED_NO});
151
multi_connect(CurrentPort+1, Max, normal, Host, Port, Options, Timeout)
151
multi_connect(Rest, Retries - 1, normal, Host, Port, Options, Timeout)
153
multi_connect(CurrentPort, Max, ssl, Host, Port, Options, Timeout) ->
153
multi_connect([CurrentPort|Rest], Retries, ssl, Host, Port, Options, Timeout) ->
154
154
case catch ssl:connect(Host, Port, [{port, CurrentPort}|Options], Timeout) of
157
{error, timeout} when Retries =< 1 ->
158
158
orber:dbg("[~p] orber_socket:multi_connect(ssl, ~p, ~p, ~p);~n"
159
159
"Timeout after ~p msec.",
160
160
[?LINE, Host, Port, [{port, CurrentPort}|Options],
162
162
corba:raise(#'COMM_FAILURE'{minor=(?ORBER_VMCID bor 4),
163
163
completion_status=?COMPLETED_NO});
165
multi_connect(CurrentPort+1, Max, ssl, Host, Port, Options, Timeout)
165
multi_connect(Rest, Retries - 1, ssl, Host, Port, Options, Timeout)
169
get_port_sequence(Min, Max) ->
170
case orber_env:iiop_out_ports_random() of
173
random:seed(A1, A2, A3),
174
Seq = lists:seq(Min, Max),
175
random_sequence((Max - Min) + 1, Seq, []);
180
random_sequence(0, _, Acc) ->
182
random_sequence(Length, Seq, Acc) ->
183
Nth = random:uniform(Length),
184
Value = lists:nth(Nth, Seq),
185
NewSeq = lists:delete(Value, Seq),
186
random_sequence(Length-1, NewSeq, [Value|Acc]).
170
188
%%-----------------------------------------------------------------
171
189
%% Create a listen socket at Port in CDR mode for
348
366
[?LINE, Type], ?DEBUG_LEVEL),
349
367
{error, ebadsocket}.
351
peercert(ssl, Socket, Opts) ->
352
ssl:peercert(Socket, Opts);
353
peercert(Type, _Socket, Opts) ->
354
orber:dbg("[~p] orber_socket:peercert(~p, ~p);~n"
355
"Only available for SSL sockets.",
356
[?LINE, Type, Opts], ?DEBUG_LEVEL),
359
369
%%-----------------------------------------------------------------
479
489
%%-----------------------------------------------------------------
480
490
%% Check Options.
481
%% We need this as a work-around since the SSL-app doesn't allow us
482
%% to pass 'inet' as an option. Also needed for R9B :-(
483
491
check_options(normal, Options, _Generation) ->
484
case orber:ip_version() of
488
%% Necessary for R9B. Should be [orber:ip_version()|Options];
492
[orber:ip_version()|Options];
491
493
check_options(ssl, Options, Generation) ->
492
494
case orber:ip_version() of
493
495
inet when Generation > 2 ->
494
496
[{ssl_imp, new}|Options];
498
[{ssl_imp, old}|Options];
497
499
inet6 when Generation > 2 ->
498
500
[{ssl_imp, new}, inet6|Options];
500
%% Will fail until SSL supports this option.
501
%% Note, we want this happen!
502
[{ssl_imp, old}, inet6|Options]