diff options
author | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
commit | 84adefa331c4159d432d22840663c38f155cd4c1 (patch) | |
tree | bff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/ssl/src/ssl_prim.erl | |
download | otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2 otp-84adefa331c4159d432d22840663c38f155cd4c1.zip |
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/ssl/src/ssl_prim.erl')
-rw-r--r-- | lib/ssl/src/ssl_prim.erl | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/lib/ssl/src/ssl_prim.erl b/lib/ssl/src/ssl_prim.erl new file mode 100644 index 0000000000..e3140a89d1 --- /dev/null +++ b/lib/ssl/src/ssl_prim.erl @@ -0,0 +1,173 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. 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% +%% + +%% + +%% 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, send/3, 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(#st{} = ListenSt0) -> + case transport_accept(ListenSt0) of + {ok, ListenSt1} -> + ssl_accept(ListenSt0, ListenSt1); + Error -> + Error + end. + +transport_accept(#st{opts = ListenOpts, thissock = ListenSocket}) -> + NewSt = newstate(acceptor), + ListenFd = ListenSocket#sslsocket.fd, + ?filter(ssl_broker:transport_accept_prim(ssl_server_prim, ListenFd, + ListenOpts, infinity, NewSt)). + +ssl_accept(#st{opts = LOpts}, ListenSt1) -> + ?filter(ssl_broker:ssl_accept_prim(ssl_server_prim, gen_tcp, self(), + LOpts, infinity, ListenSt1)). + +close(#st{fd = Fd}) when is_integer(Fd) -> + ssl_server:close_prim(ssl_server_prim, Fd), + ok; +close(_) -> + ok. + +send(St, Data) -> + send(St, Data, []). + +send(#st{proxysock = Proxysock, status = open}, Data, Opts) -> + case inet_tcp:send(Proxysock, Data, Opts) of + ok -> + ok; + {error, _} -> + {error, closed} + end; +send(#st{}, _Data, _Opts) -> + {error, closed}. + +recv(St, Length) -> + recv(St, Length, infinity). + +recv(#st{proxysock = Proxysock, status = open}, Length, Tmo) -> + inet_tcp:recv(Proxysock, Length, Tmo); +recv(#st{}, _Length, _Tmo) -> + {error, closed}. + +getll(#st{proxysock = Proxysock, status = open}) -> + inet:getll(Proxysock); +getll(#st{}) -> + {error, closed}. + +getstat(#st{proxysock = Proxysock, status = open}, Opts) -> + inet:getstat(Proxysock, Opts); +getstat(#st{}, _Opts) -> + {error, closed}. + +setopts(#st{proxysock = Proxysock, status = open}, Opts) -> + case remove_supported(Opts) of + [] -> + inet:setopts(Proxysock, Opts); + _ -> + {error, enotsup} + end; +setopts(#st{}, _Opts) -> + {error, closed}. + + +controlling_process(#st{proxysock = Proxysock, status = open}, Pid) + when is_pid(Pid) -> + inet_tcp:controlling_process(Proxysock, Pid); +controlling_process(#st{}, Pid) when is_pid(Pid) -> + {error, closed}. + +peername(#st{fd = Fd, status = open}) -> + case ssl_server:peername_prim(ssl_server_prim, Fd) of + {ok, {Address, Port}} -> + {ok, At} = inet_parse:ipv4_address(Address), + {ok, {At, Port}}; + Error -> + Error + end; +peername(#st{}) -> + {error, closed}. + +sockname(#st{fd = Fd, status = open}) -> + case ssl_server:sockname_prim(ssl_server_prim, Fd) of + {ok, {Address, Port}} -> + {ok, At} = inet_parse:ipv4_address(Address), + {ok, {At, Port}}; + Error -> + Error + end; +sockname(#st{}) -> + {error, closed}. + +getif(#st{proxysock = Proxysock, status = open}) -> + inet:getif(Proxysock); +getif(#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} + 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}. |