diff options
Diffstat (limited to 'lib/orber/src/orber_iiop_net.erl')
-rw-r--r-- | lib/orber/src/orber_iiop_net.erl | 511 |
1 files changed, 0 insertions, 511 deletions
diff --git a/lib/orber/src/orber_iiop_net.erl b/lib/orber/src/orber_iiop_net.erl deleted file mode 100644 index e7f54891a2..0000000000 --- a/lib/orber/src/orber_iiop_net.erl +++ /dev/null @@ -1,511 +0,0 @@ -%%-------------------------------------------------------------------- -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2016. All Rights Reserved. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -%% -%% %CopyrightEnd% -%% -%% -%%----------------------------------------------------------------- -%% File: orber_iiop_net.erl -%% -%% Description: -%% This file contains the IIOP communication server -%% -%%----------------------------------------------------------------- --module(orber_iiop_net). - --behaviour(gen_server). - --include_lib("orber/src/orber_iiop.hrl"). - -%%----------------------------------------------------------------- -%% External exports -%%----------------------------------------------------------------- --export([start/1, connect/5, connections/0, - sockname2peername/2, peername2sockname/2, - add_connection/5, - add/3, remove/1, reconfigure/1, reconfigure/2]). - -%%----------------------------------------------------------------- -%% Internal exports -%%----------------------------------------------------------------- --export([init/1, terminate/2, handle_call/3, - handle_cast/2, handle_info/2, code_change/3]). - -%%----------------------------------------------------------------- -%% Server state record and definitions -%%----------------------------------------------------------------- --define(CONNECTION_DB, orber_iiop_net_db). - --record(state, {ports=[], max_connections, db, counter = 1, queue}). - --record(connection, {pid, socket, type, peerdata, localdata, ref = 0}). - --record(listen, {pid, socket, port, type, ref = 0, options, proxy_options = []}). - -%%----------------------------------------------------------------- -%% External interface functions -%%----------------------------------------------------------------- -%%----------------------------------------------------------------- -%% Func: start/1 -%%----------------------------------------------------------------- -start(Opts) -> - gen_server:start_link({local, orber_iiop_net}, orber_iiop_net, Opts, []). - -add(IP, normal, Options) -> - Port = orber_tb:keysearch(iiop_port, Options, orber_env:iiop_port()), - gen_server:call(orber_iiop_net, {add, IP, normal, Port, Options}, infinity); -add(IP, ssl, Options) -> - Port = orber_tb:keysearch(iiop_ssl_port, Options, orber_env:iiop_ssl_port()), - gen_server:call(orber_iiop_net, {add, IP, ssl, Port, Options}, infinity). - -remove(Ref) -> - gen_server:call(orber_iiop_net, {remove, Ref}, infinity). - -reconfigure(Options) -> - lists:foreach(fun(P) -> - P ! {reconfigure, Options} - end, - do_select([{#connection{pid = '$1', _='_'}, - [], ['$1']}])). - -reconfigure(Options, Ref) -> - case do_select([{#connection{ref = Ref, pid = '$1', _='_'}, - [], ['$1']}]) of - [Pid] when is_pid(Pid) -> - Pid ! {reconfigure, Options}, - ok; - _ -> - {error, "No proxy matched the supplied reference"} - end. - -connect(Type, S, AcceptPid, Ref, ProxyOptions) -> - gen_server:call(orber_iiop_net, {connect, Type, S, AcceptPid, - Ref, ProxyOptions}, infinity). - -connections() -> - do_select([{#connection{peerdata = '$1', _='_'}, [], ['$1']}]). - -sockname2peername(SockHost, SockPort) -> - do_select([{#connection{peerdata = '$1', - localdata = {match_type(SockHost), - match_type(SockPort)}, - _='_'}, [], ['$1']}]). - - -peername2sockname(PeerHost, PeerPort) -> - do_select([{#connection{peerdata = {match_type(PeerHost), - match_type(PeerPort)}, - localdata = '$1', - _='_'}, [], ['$1']}]). - -do_select(Pattern) -> - case catch ets:select(?CONNECTION_DB, Pattern) of - {'EXIT', _What} -> - []; - Result -> - Result - end. - -match_type(0) -> - %% Wildcard port number - '_'; -match_type("") -> - %% Wildcard host - '_'; -match_type(Key) -> - %% Wildcard not used. - Key. - -add_connection(Socket, Type, PeerData, LocalData, Ref) -> - ets:insert(?CONNECTION_DB, #connection{pid = self(), socket = Socket, - type = Type, peerdata = PeerData, - localdata = LocalData, ref = Ref}). - -%%----------------------------------------------------------------- -%% Server functions -%%----------------------------------------------------------------- -%%----------------------------------------------------------------- -%% Func: init/1 -%%----------------------------------------------------------------- -init(Options) -> - process_flag(trap_exit, true), - {ok, parse_options(Options, - #state{max_connections = orber:iiop_max_in_connections(), - db = ets:new(?CONNECTION_DB, [set, public, - named_table, - {keypos, 2}]), - queue = queue:new()})}. - -%%----------------------------------------------------------------- -%% Func: terminate/1 -%%----------------------------------------------------------------- -terminate(_Reason, _State) -> - ok. - -%%----------------------------------------------------------------- -%% Func: get_options/2 -%%----------------------------------------------------------------- -get_options(normal, _Options) -> - []; -get_options(ssl, Options) -> - SSLOpts = - case orber_tb:keysearch(ssl_server_options, Options, - orber_env:ssl_server_options()) of - [] -> - Verify = orber_tb:keysearch(ssl_server_verify, Options, - orber_env:ssl_server_verify()), - Depth = orber_tb:keysearch(ssl_server_depth, Options, - orber_env:ssl_server_depth()), - Cert = orber_tb:keysearch(ssl_server_certfile, Options, - orber_env:ssl_server_certfile()), - CaCert = orber_tb:keysearch(ssl_server_cacertfile, Options, - orber_env:ssl_server_cacertfile()), - Pwd = orber_tb:keysearch(ssl_server_password, Options, - orber_env:ssl_server_password()), - Key = orber_tb:keysearch(ssl_server_keyfile, Options, - orber_env:ssl_server_keyfile()), - Ciphers = orber_tb:keysearch(ssl_server_ciphers, Options, - orber_env:ssl_server_ciphers()), - Timeout = orber_tb:keysearch(ssl_server_cachetimeout, Options, - orber_env:ssl_server_cachetimeout()), - KeepAlive = orber_tb:keysearch(ssl_server_cachetimeout, Options, - orber_env:iiop_ssl_in_keepalive()), - [{verify, Verify}, - {depth, Depth}, - {certfile, Cert}, - {cacertfile, CaCert}, - {password, Pwd}, - {keyfile, Key}, - {ciphers, Ciphers}, - {cachetimeout, Timeout}, - {keepalive, KeepAlive}]; - Opts -> - case orber_tb:check_illegal_tcp_options(Opts) of - ok -> - check_old_ssl_server_options(Options), - Opts; - {error, IllegalOpts} -> - error_logger:error_report([{application, orber}, - "TCP options not allowed to set on a connection", - IllegalOpts]), - error("Illegal TCP option") - end - end, - ssl_server_extra_options(SSLOpts, []). - -%%----------------------------------------------------------------- -%% Func: parse_options/2 -%%----------------------------------------------------------------- -parse_options([{port, Type, Port} | Rest], State) -> - Options = get_options(Type, []), - Family = orber_env:ip_version(), - IPFamilyOptions = - case Family of - inet -> [inet]; - inet6 -> [inet6, {ipv6_v6only, true}] - end, - Options2 = - case orber_env:ip_address_variable_defined() of - false -> - IPFamilyOptions ++ Options; - Host -> - {ok, IP} = inet:getaddr(Host, Family), - IPFamilyOptions ++ [{ip, IP} |Options] - end, - - {ok, Listen, NewPort} = orber_socket:listen(Type, Port, Options2, true), - {ok, Pid} = orber_iiop_socketsup:start_accept(Type, Listen, 0), - link(Pid), - ets:insert(?CONNECTION_DB, #listen{pid = Pid, socket = Listen, - port = NewPort, type = Type, - options = Options2}), - parse_options(Rest, State); -parse_options([], State) -> - State. - -ssl_server_extra_options([], Acc) -> - Acc; -ssl_server_extra_options([{_Type, []}|T], Acc) -> - ssl_server_extra_options(T, Acc); -ssl_server_extra_options([{_Type, infinity}|T], Acc) -> - ssl_server_extra_options(T, Acc); -ssl_server_extra_options([{Type, Value}|T], Acc) -> - ssl_server_extra_options(T, [{Type, Value}|Acc]). - -filter_options([], Acc) -> - Acc; -filter_options([{verify, _}|T], Acc) -> - filter_options(T, Acc); -filter_options([{depth, _}|T], Acc) -> - filter_options(T, Acc); -filter_options([{certfile, _}|T], Acc) -> - filter_options(T, Acc); -filter_options([{cacertfile, _}|T], Acc) -> - filter_options(T, Acc); -filter_options([{password, _}|T], Acc) -> - filter_options(T, Acc); -filter_options([{keyfile, _}|T], Acc) -> - filter_options(T, Acc); -filter_options([{ciphers, _}|T], Acc) -> - filter_options(T, Acc); -filter_options([{cachetimeout, _}|T], Acc) -> - filter_options(T, Acc); -filter_options([H|T], Acc) -> - filter_options(T, [H|Acc]). - -%%----------------------------------------------------------------- -%% Func: handle_call/3 -%%----------------------------------------------------------------- -handle_call({remove, Ref}, _From, State) -> - case do_select([{#listen{ref = Ref, pid = '$1', socket = '$2', - type = '$3', _='_'}, [], [{{'$1', '$2', '$3'}}]}]) of - [{Pid, Listen, Type}|_] when is_pid(Pid) -> - unlink(Pid), - ets:delete(?CONNECTION_DB, Pid), - %% Just close the listen socket. Will cause the accept processs - %% to terminate. - orber_socket:close(Type, Listen), - stop_proxies(do_select([{#connection{ref = Ref, pid = '$1', _='_'}, - [], ['$1']}])), - {reply, ok, - State#state{queue = - from_list( - lists:keydelete(Pid, 1, - queue:to_list(State#state.queue)))}}; - _ -> - {reply, ok, State} - end; -handle_call({add, IP, Type, Port, AllOptions}, _From, State) -> - Family = orber_tb:keysearch(ip_family, AllOptions, orber_env:ip_version()), - IPFamilyOptions = - case Family of - inet -> [inet]; - inet6 -> [inet6, {ipv6_v6only, true}] - end, - case inet:getaddr(IP, Family) of - {ok, IPTuple} -> - try - Options = IPFamilyOptions ++ [{ip, IPTuple} |get_options(Type, AllOptions)], - Ref = make_ref(), - ProxyOptions = filter_options(AllOptions, []), - case orber_socket:listen(Type, Port, Options, false) of - {ok, Listen, NewPort} -> - {ok, Pid} = orber_iiop_socketsup:start_accept(Type, Listen, Ref, - ProxyOptions), - link(Pid), - ets:insert(?CONNECTION_DB, #listen{pid = Pid, - socket = Listen, - port = NewPort, - type = Type, ref = Ref, - options = Options, - proxy_options = ProxyOptions}), - {reply, {ok, Ref}, State}; - Error -> - {reply, Error, State} - end - catch - error:Reason -> - {reply, {error, Reason}, State} - end; - Other -> - {reply, Other, State} - end; -handle_call({connect, Type, Socket, _AcceptPid, AccepRef, ProxyOptions}, _From, State) - when State#state.max_connections == infinity; - State#state.max_connections > State#state.counter -> - case catch access_allowed(Type, Socket, Type) of - true -> - case orber_iiop_insup:start_connection(Type, Socket, - AccepRef, ProxyOptions) of - {ok, Pid} when is_pid(Pid) -> - link(Pid), - {reply, {ok, Pid, true}, update_counter(State, 1)}; - Other -> - {reply, Other, State} - end; - _ -> - {H, P} = orber_socket:peerdata(Type, Socket), - orber_tb:info("Blocked connect attempt from ~s - ~p", [H, P]), - {reply, denied, State} - end; -handle_call({connect, Type, Socket, AcceptPid, AccepRef, ProxyOptions}, _From, - #state{queue = Q} = State) -> - case catch access_allowed(Type, Socket, Type) of - true -> - case orber_iiop_insup:start_connection(Type, Socket, - AccepRef, ProxyOptions) of - {ok, Pid} when is_pid(Pid) -> - link(Pid), - Ref = erlang:make_ref(), - {reply, {ok, Pid, Ref}, - update_counter(State#state{queue = - queue:in({AcceptPid, Ref}, Q)}, 1)}; - Other -> - {reply, Other, State} - end; - _ -> - {H, P} = orber_socket:peerdata(Type, Socket), - orber_tb:info("Blocked connect attempt from ~s - ~p", [H, P]), - {reply, denied, State} - end; -handle_call(_, _, State) -> - {noreply, State}. - -stop_proxies([H|T]) -> - catch orber_iiop_inproxy:stop(H), - stop_proxies(T); -stop_proxies([]) -> - ok. - -access_allowed(Type, Socket, Type) -> - Flags = orber:get_flags(), - case ?ORB_FLAG_TEST(Flags, ?ORB_ENV_USE_ACL_INCOMING) of - false -> - true; - true -> - SearchFor = - case Type of - normal -> - tcp_in; - ssl -> - ssl_in - end, - {ok, {Host, Port}} = orber_socket:peername(Type, Socket), - case orber_acl:match(Host, SearchFor, true) of - {true, [], 0} -> - true; - {true, [], Port} -> - true; - {true, [], {Min, Max}} when Port >= Min, Port =< Max -> - true; - {true, Interfaces, 0} -> - get_sockethost(Type, Socket), - lists:member(get_sockethost(Type, Socket), Interfaces); - {true, Interfaces, Port} -> - lists:member(get_sockethost(Type, Socket), Interfaces); - {true, Interfaces, {Min, Max}} when Port >= Min, Port =< Max -> - lists:member(get_sockethost(Type, Socket), Interfaces); - _ -> - false - end - end. - -get_sockethost(Type, Socket) -> - case orber_socket:peername(Type, Socket) of - {ok, {Addr, _Port}} -> - orber_env:addr2str(Addr); - _ -> - false - end. - -%%------------------------------------------------------------ -%% Standard gen_server cast handle -%%------------------------------------------------------------ -handle_cast(_, State) -> - {noreply, State}. - -%%------------------------------------------------------------ -%% Standard gen_server handles -%%------------------------------------------------------------ -handle_info({'EXIT', Pid, _Reason}, State) when is_pid(Pid) -> - case ets:lookup(?CONNECTION_DB, Pid) of - [#listen{pid = Pid, socket = Listen, port = Port, type = Type, - ref = Ref, options = Options, proxy_options = POpts}] -> - ets:delete(?CONNECTION_DB, Pid), - unlink(Pid), - {ok, NewPid} = orber_iiop_socketsup:start_accept(Type, Listen, - Ref, POpts), - link(NewPid), - ets:insert(?CONNECTION_DB, #listen{pid = NewPid, socket = Listen, - port = Port, type = Type, - ref = Ref, options = Options, - proxy_options = POpts}), - %% Remove the connection if it's in the queue. - {noreply, - State#state{queue = - from_list( - lists:keydelete(Pid, 1, - queue:to_list(State#state.queue)))}}; - [#connection{pid = Pid}] -> - ets:delete(?CONNECTION_DB, Pid), - unlink(Pid), - case queue:out(State#state.queue) of - {empty, _} -> - {noreply, update_counter(State, -1)}; - {{value, {AcceptPid, Ref}}, Q} -> - AcceptPid ! {Ref, ok}, - {noreply, update_counter(State#state{queue = Q}, -1)} - end; - [] -> - {noreply, State} - end; -handle_info(_, State) -> - {noreply, State}. - -from_list(List) -> - from_list(List, queue:new()). - -from_list([], Q) -> - Q; -from_list([H|T], Q) -> - NewQ = queue:in(H, Q), - from_list(T, NewQ). - - -%%----------------------------------------------------------------- -%% Func: code_change/3 -%%----------------------------------------------------------------- -code_change(_OldVsn, State, _Extra) -> - {ok, State}. - -%%----------------------------------------------------------------- -%% Internal Functions -%%----------------------------------------------------------------- -update_counter(#state{max_connections = infinity} = State, _) -> - State; -update_counter(State, Value) -> - State#state{counter = State#state.counter + Value}. - - -check_old_ssl_server_options(Options) -> - try - 0 = orber_tb:keysearch(ssl_server_verify, Options, - orber_env:ssl_server_verify()), - 1 = orber_tb:keysearch(ssl_server_depth, Options, - orber_env:ssl_server_depth()), - [] = orber_tb:keysearch(ssl_server_certfile, Options, - orber_env:ssl_server_certfile()), - [] = orber_tb:keysearch(ssl_server_cacertfile, Options, - orber_env:ssl_server_cacertfile()), - [] = orber_tb:keysearch(ssl_server_password, Options, - orber_env:ssl_server_password()), - [] = orber_tb:keysearch(ssl_server_keyfile, Options, - orber_env:ssl_server_keyfile()), - [] = orber_tb:keysearch(ssl_server_ciphers, Options, - orber_env:ssl_server_ciphers()), - infinity = orber_tb:keysearch(ssl_server_cachetimeout, Options, - orber_env:ssl_server_cachetimeout()), - false = orber_tb:keysearch(iiop_ssl_in_keepalive, Options, - orber_env:iiop_ssl_in_keepalive()) - catch - _:_ -> - io:format("hej\n",[]), - error_logger:warning_report([{application, orber}, - "Ignoring deprecated ssl server options used together with the ssl_server_options"]) - end. - |