diff options
Diffstat (limited to 'lib/orber/src/orber_iiop_inproxy.erl')
-rw-r--r-- | lib/orber/src/orber_iiop_inproxy.erl | 399 |
1 files changed, 0 insertions, 399 deletions
diff --git a/lib/orber/src/orber_iiop_inproxy.erl b/lib/orber/src/orber_iiop_inproxy.erl deleted file mode 100644 index b595586f84..0000000000 --- a/lib/orber/src/orber_iiop_inproxy.erl +++ /dev/null @@ -1,399 +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_inproxy.erl -%% -%% Description: -%% This file contains the IIOP "proxy" for incomming connections -%% -%%----------------------------------------------------------------- --module(orber_iiop_inproxy). - --behaviour(gen_server). - --include_lib("orber/src/orber_iiop.hrl"). --include_lib("orber/include/corba.hrl"). - -%%----------------------------------------------------------------- -%% External exports -%%----------------------------------------------------------------- --export([start/0, start/1]). - -%%----------------------------------------------------------------- -%% Internal exports -%%----------------------------------------------------------------- --export([init/1, handle_call/3, handle_cast/2, handle_info/2, - code_change/3, terminate/2, post_accept/3, stop/1]). - -%%----------------------------------------------------------------- -%% Macros -%%----------------------------------------------------------------- --define(DEBUG_LEVEL, 7). - --record(state, {stype, socket, db, timeout, max_fragments, - max_requests, request_counter = 1, giop_env, peer}). - -%%----------------------------------------------------------------- -%% External interface functions -%%----------------------------------------------------------------- -%%----------------------------------------------------------------- -%% Func: start/0 -%%----------------------------------------------------------------- -start() -> - ignore. - -%%----------------------------------------------------------------- -%% Func: start/1 -%%----------------------------------------------------------------- -start(Opts) -> - gen_server:start_link(orber_iiop_inproxy, Opts, []). - -post_accept(Pid, ssl, Socket) -> - (catch gen_server:cast(Pid, {post_accept, ssl, Socket})), - ok; -post_accept(_, _, _) -> - ok. - -%%----------------------------------------------------------------- -%% Internal interface functions -%%----------------------------------------------------------------- -%%----------------------------------------------------------------- -%% Func: stop/1 -%%----------------------------------------------------------------- -stop(Pid) -> - gen_server:cast(Pid, stop). - -%%----------------------------------------------------------------- -%% Server functions -%%----------------------------------------------------------------- -%%----------------------------------------------------------------- -%% Func: init/1 -%%----------------------------------------------------------------- -init({connect, Type, Socket, Ref, Options}) -> - process_flag(trap_exit, true), - Flags = orber_tb:keysearch(flags, Options, orber_env:get_flags()), - {Address, Port} = PeerData = orber_socket:peerdata(Type, Socket), - {LAddress, LPort} = LocalData = orber_socket:sockdata(Type, Socket), - case {?ORB_FLAG_TEST(Flags, ?ORB_ENV_LOCAL_INTERFACE), LPort} of - {true, 0} -> - orber_tb:info("Unable to lookup the local address and port number.~n" - "Closing the incoming connection.", []), - ignore; - _ -> - orber_iiop_net:add_connection(Socket, Type, PeerData, LocalData, Ref), - Interceptors = - case orber_tb:keysearch(interceptors, Options, - orber_env:get_interceptors()) of - {native, PIs} -> - {native, orber_pi:new_in_connection(PIs, Address, Port, - LAddress, LPort), PIs}; - Other -> - Other - end, - Env = - case ?ORB_FLAG_TEST(Flags, ?ORB_ENV_LOCAL_INTERFACE) of - true when Type == ssl -> - #giop_env{interceptors = Interceptors, - flags = Flags, host = [LAddress], - iiop_port = - orber_tb:keysearch(iiop_port, Options, - orber_env:iiop_port()), - iiop_ssl_port = LPort, - domain = orber:domain(), - partial_security = orber:partial_security()}; - true -> - #giop_env{interceptors = Interceptors, - flags = Flags, host = [LAddress], - iiop_port = LPort, - iiop_ssl_port = - orber_tb:keysearch(iiop_ssl_port, Options, - orber_env:iiop_ssl_port()), - domain = orber:domain(), - partial_security = orber:partial_security()}; - false -> - case ?ORB_FLAG_TEST(Flags, ?ORB_ENV_ENABLE_NAT) of - false -> - #giop_env{interceptors = Interceptors, - flags = Flags, host = orber:host(), - iiop_port = orber:iiop_port(), - iiop_ssl_port = orber:iiop_ssl_port(), - domain = orber:domain(), - partial_security = orber:partial_security()}; - true -> - #giop_env{interceptors = Interceptors, - flags = Flags, - host = - orber_tb:keysearch(nat_ip_address, Options, - orber_env:nat_host()), - iiop_port = - orber_tb:keysearch(nat_iiop_port, Options, - orber_env:nat_iiop_port()), - iiop_ssl_port = - orber_tb:keysearch(nat_iiop_ssl_port, Options, - orber_env:nat_iiop_ssl_port()), - domain = orber:domain(), - partial_security = orber:partial_security()} - end - end, - Timeout = orber_tb:keysearch(iiop_in_connection_timeout, Options, - orber_env:iiop_in_connection_timeout()), - MaxFrags = orber_tb:keysearch(iiop_max_fragments, Options, - orber_env:iiop_max_fragments()), - MaxRequests = orber_tb:keysearch(iiop_max_in_requests, Options, - orber_env:iiop_max_in_requests()), - {ok, #state{stype = Type, - socket = Socket, - db = ets:new(orber_incoming_requests, [set]), - timeout = Timeout, - max_fragments = MaxFrags, - max_requests = MaxRequests, - giop_env = Env, peer = PeerData}, Timeout} - end. - - -%%----------------------------------------------------------------- -%% Func: terminate/2 -%%----------------------------------------------------------------- -%% We may want to kill all proxies before terminating, but the best -%% option should be to let the requests complete (especially for one-way -%% functions it's a better alternative. -terminate(_Reason, #state{db = IncRequests, giop_env = Env}) -> - ets:delete(IncRequests), - case Env#giop_env.interceptors of - false -> - ok; - {native, Ref, PIs} -> - orber_pi:closed_in_connection(PIs, Ref); - {_Type, _PIs} -> - ok - end. - -%%----------------------------------------------------------------- -%% Func: handle_call/3 -%%----------------------------------------------------------------- -handle_call(stop, _From, State) -> - {stop, normal, ok, State}; -handle_call(_, _, State) -> - {noreply, State, State#state.timeout}. - -%%----------------------------------------------------------------- -%% Func: handle_cast/2 -%%----------------------------------------------------------------- -handle_cast({post_accept, Type, Socket}, State) -> - Timeout = orber_env:iiop_ssl_accept_timeout(), - case catch orber_socket:post_accept(Type, Socket, Timeout) of - ok -> - {noreply, State}; - _Failed -> - orber_socket:close(Type, Socket), - {stop, normal, State} - end; -handle_cast(stop, State) -> - {stop, normal, State}; -handle_cast(_, State) -> - {noreply, State, State#state.timeout}. - -%%----------------------------------------------------------------- -%% Func: handle_info/2 -%%----------------------------------------------------------------- -%% Normal invocation -handle_info({tcp, Socket, Bytes}, State) -> - handle_msg(normal, Socket, Bytes, State); -handle_info({ssl, Socket, Bytes}, State) -> - handle_msg(ssl, Socket, Bytes, State); -%% Errors, closed connection -handle_info({tcp_closed, _Socket}, State) -> - {stop, normal, State}; -handle_info({tcp_error, _Socket, _Reason}, State) -> - {stop, normal, State}; -handle_info({ssl_closed, _Socket}, State) -> - {stop, normal, State}; -handle_info({ssl_error, _Socket, _Reason}, State) -> - {stop, normal, State}; -%% Servant termination. -handle_info({'EXIT', Pid, normal}, State) -> - ets:delete(State#state.db, Pid), - {noreply, decrease_counter(State), State#state.timeout}; -handle_info({message_error, _Pid, ReqId}, State) -> - ets:delete(State#state.db, ReqId), - {noreply, State, State#state.timeout}; -handle_info(timeout, State) -> - case ets:info(State#state.db, size) of - 0 -> - %% No pending requests, close the connection. - {stop, normal, State}; - _Amount -> - %% Still pending request, cannot close the connection. - {noreply, State, State#state.timeout} - end; -handle_info({reconfigure, Options}, State) -> - {noreply, update_state(State, Options), State#state.timeout}; -handle_info(_X,State) -> - {noreply, State, State#state.timeout}. - -handle_msg(Type, Socket, Bytes, #state{stype = Type, socket = Socket, - giop_env = Env} = State) -> - case catch cdr_decode:dec_giop_message_header(Bytes) of - %% Only when using IIOP-1.2 may the client send this message. - %% Introduced in CORBA-2.6 - #giop_message{message_type = ?GIOP_MSG_CLOSE_CONNECTION, - giop_version = {1,2}} -> - {stop, normal, State}; - #giop_message{message_type = ?GIOP_MSG_CLOSE_CONNECTION} -> - {noreply, State, State#state.timeout}; - #giop_message{message_type = ?GIOP_MSG_CANCEL_REQUEST} = GIOPHdr -> - ReqId = cdr_decode:peek_request_id(GIOPHdr#giop_message.byte_order, - GIOPHdr#giop_message.message), - case ets:lookup(State#state.db, ReqId) of - [{RId, PPid}] -> - ets:delete(State#state.db, RId), - PPid ! {self(), cancel_request_header}; - [] -> - send_msg_error(Type, Socket, Bytes, - Env#giop_env{version = - GIOPHdr#giop_message.giop_version}, - "No such request id") - end, - {noreply, State, State#state.timeout}; - %% A fragment; we must have received a Request or LocateRequest - %% with fragment-flag set to true. - %% We need to decode the header to get the request-id. - #giop_message{message_type = ?GIOP_MSG_FRAGMENT, - giop_version = {1,2}} = GIOPHdr -> - ReqId = cdr_decode:peek_request_id(GIOPHdr#giop_message.byte_order, - GIOPHdr#giop_message.message), - case ets:lookup(State#state.db, ReqId) of - [{_RId, PPid}] when GIOPHdr#giop_message.fragments == true -> - PPid ! {self(), GIOPHdr}; - [{RId, PPid}] -> - ets:delete(State#state.db, RId), - PPid ! {self(), GIOPHdr}; - [] -> - send_msg_error(Type, Socket, Bytes, - Env#giop_env{version = - GIOPHdr#giop_message.giop_version}, - "No such fragment id") - end, - {noreply, State, State#state.timeout}; - %% Must be a Request or LocateRequest which have been fragmented. - %% We need to decode the header to get the request-id. - #giop_message{fragments = true, - giop_version = {1,2}} = GIOPHdr -> - ReqId = cdr_decode:peek_request_id(GIOPHdr#giop_message.byte_order, - GIOPHdr#giop_message.message), - Pid = - orber_iiop_inrequest: - start_fragment_collector(GIOPHdr, Bytes, - Type, Socket, - ReqId, self(), - State#state.max_fragments, - Env#giop_env{version = {1,2}, - request_id = ReqId}), - ets:insert(State#state.db, {Pid, ReqId}), - ets:insert(State#state.db, {ReqId, Pid}), - {noreply, increase_counter(State), State#state.timeout}; - GIOPHdr when is_record(GIOPHdr, giop_message) -> - Pid = orber_iiop_inrequest:start(GIOPHdr, Bytes, Type, Socket, - Env#giop_env{version = - GIOPHdr#giop_message.giop_version}), - ets:insert(State#state.db, {Pid, undefined}), - {noreply, increase_counter(State), State#state.timeout}; - {'EXIT', message_error} -> - send_msg_error(Type, Socket, Bytes, - Env#giop_env{version = orber_env:giop_version()}, - "Unable to decode the GIOP-header"), - {noreply, State, State#state.timeout} - end; -handle_msg(Type, _, Bytes, State) -> - orber:dbg("[~p] orber_iiop_inproxy:handle_msg(~p);~n" - "Received a message from a socket of a different type.~n" - "Should be ~p but was ~p.", - [?LINE, Bytes, State#state.stype, Type], ?DEBUG_LEVEL), - {noreply, State, State#state.timeout}. - -send_msg_error(Type, Socket, Data, Env, Msg) -> - orber:dbg("[~p] orber_iiop_inproxy:handle_msg(~p); ~p.", - [?LINE, Data, Msg], ?DEBUG_LEVEL), - Reply = cdr_encode:enc_message_error(Env), - orber_socket:write(Type, Socket, Reply). - -increase_counter(#state{max_requests = infinity} = State) -> - State; -increase_counter(#state{max_requests = Max, - request_counter = Counter} = State) when Max > Counter -> - orber_socket:setopts(State#state.stype, State#state.socket, [{active, once}]), - State#state{request_counter = Counter + 1}; -increase_counter(State) -> - State#state{request_counter = State#state.request_counter + 1}. - -decrease_counter(#state{max_requests = infinity} = State) -> - State; -decrease_counter(#state{max_requests = Max, - request_counter = Counter} = State) when Max =< Counter -> - orber_socket:setopts(State#state.stype, State#state.socket, [{active, once}]), - State#state{request_counter = Counter - 1}; -decrease_counter(State) -> - State#state{request_counter = State#state.request_counter - 1}. - -update_state(#state{giop_env = Env} = State, - [{interceptors, false}|Options]) -> - update_state(State#state{giop_env = - Env#giop_env{interceptors = false}}, Options); -update_state(#state{giop_env = #giop_env{interceptors = false, host = [SH], - iiop_port = SP} = Env, - peer = {PH, PP}, stype = normal} = State, - [{interceptors, {native, LPIs}}|Options]) -> - %% No Interceptor(s). Add the same Ref used by the built in interceptors. - update_state(State#state{giop_env = - Env#giop_env{interceptors = - {native, {PH, PP, SH, SP}, LPIs}}}, - Options); -update_state(#state{giop_env = #giop_env{interceptors = false, host = [SH], - iiop_ssl_port = SP} = Env, - peer = {PH, PP}, stype = ssl} = State, - [{interceptors, {native, LPIs}}|Options]) -> - %% No Interceptor(s). Add the same Ref used by the built in interceptors. - update_state(State#state{giop_env = - Env#giop_env{interceptors = - {native, {PH, PP, SH, SP}, LPIs}}}, - Options); -update_state(#state{giop_env = #giop_env{interceptors = {native, Ref, _}} = Env} = - State, - [{interceptors, {native, LPIs}}|Options]) -> - %% Interceptor(s) already in use. We must use the same Ref as before. - update_state(State#state{giop_env = - Env#giop_env{interceptors = {native, Ref, LPIs}}}, - Options); -update_state(State, [H|T]) -> - orber:dbg("[~p] orber_iiop_inproxy:update_state(~p, ~p)~n" - "Couldn't change the state.", - [?LINE, H, State], ?DEBUG_LEVEL), - update_state(State, T); -update_state(State, []) -> - State. - -%%----------------------------------------------------------------- -%% Func: code_change/3 -%%----------------------------------------------------------------- -code_change(_OldVsn, State, _Extra) -> - {ok, State}. - |