%% ``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 via the world wide web 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. %% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB. %% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings %% AB. All Rights Reserved.'' %% %% $Id$ %% %% Purpose: Primitive interface to SSL, without broker process (used by %% SSL distribution). -module(ssl_prim). -export([listen/2, connect/3, accept/1, close/1, send/2, recv/2, recv/3, getll/1, getstat/2, setopts/2, controlling_process/2, peername/1, sockname/1, getif/1]). -include("ssl_int.hrl"). -include("ssl_broker_int.hrl"). %-define(filter(Call), filter((catch Call))). -define(filter(Call), filter(Call)). listen(Port, Opts) -> St = newstate(listener), ?filter(ssl_broker:listen_prim(ssl_server_prim, self(), Port, nonactive(Opts), St)). connect(Address, Port, Opts) -> St = newstate(connector), ?filter(ssl_broker:connect_prim(ssl_server_prim, inet_tcp, self(), Address, Port, nonactive(Opts), infinity, St)). accept(ListenSt0) when record(ListenSt0, st) -> case transport_accept(ListenSt0) of {ok, ListenSt1} -> ssl_accept(ListenSt0, ListenSt1); Error -> Error end. transport_accept(ListenSt) when record(ListenSt, st) -> NewSt = newstate(acceptor), ListenSocket=ListenSt#st.thissock, ListenFd = ListenSocket#sslsocket.fd, ListenOpts = ListenSt#st.opts, ?filter(ssl_broker:transport_accept_prim( ssl_server_prim, ListenFd, ListenOpts, infinity, NewSt)). ssl_accept(ListenSt0, ListenSt1) when is_record(ListenSt0, st) -> LOpts = ListenSt0#st.opts, A = ?filter(ssl_broker:ssl_accept_prim( ssl_server_prim, gen_tcp, self(), LOpts, infinity, ListenSt1)), A. close(_St = #st{fd = Fd}) when integer(Fd) -> ssl_server:close_prim(ssl_server_prim, Fd), ok; close(_) -> ok. send(St, Data) when record(St, st), St#st.status =:= open -> case inet_tcp:send(St#st.proxysock, Data) of ok -> ok; {error, _} -> {error, closed} end; send(St, _Data) when record(St, st) -> {error, closed}. recv(St,Length) -> recv(St,Length,infinity). recv(St, Length, Tmo) when record(St, st), St#st.status =:= open -> inet_tcp:recv(St#st.proxysock, Length, Tmo); recv(St, _Length, _Tmo) when record(St, st) -> {error, closed}. getll(St) when record(St, st), St#st.status =:= open -> inet:getll(St#st.proxysock); getll(St) when record(St, st) -> {error, closed}. getstat(St, Opts) when record(St, st), St#st.status =:= open -> inet:getstat(St#st.proxysock, Opts); getstat(St, _Opts) when record(St, st) -> {error, closed}. setopts(St, Opts) when record(St, st), St#st.status =:= open -> case remove_supported(Opts) of [] -> inet:setopts(St#st.proxysock, Opts); _ -> {error, enotsup} end; setopts(St, _Opts) when record(St, st) -> {error, closed}. controlling_process(St, Pid) when record(St, st), St#st.status =:= open, pid(Pid) -> inet_tcp:controlling_process(St#st.proxysock, Pid); controlling_process(St, Pid) when record(St, st), pid(Pid) -> {error, closed}. peername(St) when record(St, st), St#st.status =:= open -> case ssl_server:peername_prim(ssl_server_prim, St#st.fd) of {ok, {Address, Port}} -> {ok, At} = inet_parse:ipv4_address(Address), {ok, {At, Port}}; Error -> Error end; peername(St) when record(St, st) -> {error, closed}. sockname(St) when record(St, st), St#st.status =:= open -> case ssl_server:sockname_prim(ssl_server_prim, St#st.fd) of {ok, {Address, Port}} -> {ok, At} = inet_parse:ipv4_address(Address), {ok, {At, Port}}; Error -> Error end; sockname(St) when record(St, st) -> {error, closed}. getif(St) when record(St, st), St#st.status =:= open -> inet:getif(St#st.proxysock); getif(St) when record(St, st) -> {error, closed}. remove_supported([{active, _}|T]) -> remove_supported(T); remove_supported([{packet,_}|T]) -> remove_supported(T); remove_supported([{deliver,_}|T]) -> remove_supported(T); remove_supported([H|T]) -> [H | remove_supported(T)]; remove_supported([]) -> []. filter(Result) -> case Result of {ok, _Sock,St} -> {ok, St}; {error, Reason, _St} -> {error,Reason}; Else -> {error, Else} end. nonactive([{active,_}|T]) -> nonactive(T); nonactive([H|T]) -> [H | nonactive(T)]; nonactive([]) -> [{active, false}]. newstate(Type) -> #st{brokertype = Type, server = whereis(ssl_server_prim), client = undefined, collector = undefined, debug = false}.