SSL in Erlang/OTP

Alexey Shchepin alexey@REDACTED
Thu Nov 20 22:11:54 CET 2003

Hello, Peter!

On Wed, 19 Nov 2003 20:37:35 +0100 (MET), you said:

 >> Can anyone help with following issues with SSL application?
 >> * ssl:accept locks when when one TCP connection is established, but SSL
 >> handshake is not finished.  E.g. if Yaws is listen for SSL connections on
 >> port 443 and someone runs "telnet this.server 443" (note that this is not
 >> SSL-enabled telnet), then noone will be able to retreive web pages via this
 >> port until this connection will be closed.  As temporary solution I use
 >> ssl:accept with small timeout value, but this is just workaround.  IMHO
 >> ssl:accept should not have such behaviour.

 PH> In Erlang/OTP SSL you can have several processes, each waiting for an
 PH> ssl:accept/N on one and the the same port. That is needed to obtain
 PH> acceptable (no pun intended) parallellism.

I.e. I need to run several such processess?:

accept(ListenSocket, Opts) ->
    case ssl:accept(ListenSocket) of
	{ok, Socket} ->
            % Start new process for Socket
	    accept(ListenSocket, Opts);
	{error, Reason} -> ...

But even if I run e.g. 1000 such parallell accepts, malicious user still can
open 1000 connections with the way I describe above (with ssl:accept locking),
which will make service unaccessible for other users.

So IMHO ssl:accept should return immediately after TCP connection to listened
port will be established with new socket in "handshaking" state.  In this state
must be possible to know sockname (e.g. to prevent many conections from one
host), and data sended with ssl:send will be writed to queue, which will be
sended after handshaking.

 PH> That it not practically possible with gen_tcp:accept/N (if you try it you
 PH> will get an error return). I think gen_tcp should accept multiple accepts
 PH> as well.

 >> * ssl:send locks if another process runs ssl:recv on the same port.  And I
 >> can't use "{active, true}" option, because I need flow control.  Again, as
 >> a temporary solution I use timeout value in ssl:recv/3, so ssl:send can
 >> work several times in second.  But this makes notable increase of CPU load:
 >> e.g. with ejabberd on (~440 connected users, ~100 using SSL) with
 >> 20ms timeout -- CPU load is ~40%, with 200ms -- 9-12%, with SSL switched
 >> off -- 3-4%.

 PH> When an SSL-connection has been established all data flow through gen_tcp
 PH> to/from the SSL portprogram, which is then just a multiplexer of data
 PH> (slow connections will not impair fast connections).

 PH> Seems as if your problem is really a gen_tcp problem?

I think this is ssl_broker problem, look:

%% recv - passive mode
handle_call({recv, Client, Length, Timeout}, From, St) 
  when St#st.status =/= closed, == false ->
    debug(St, "recv: client = ~w~n", [Client]),
    Reply = gen_tcp:recv(St#st.proxysock, Length, Timeout),
    {reply, Reply, St};

(This is part of ssl_broker.erl from R8B, but R9C do almost the same)

After ssl:recv call, appropriate ssl_broker process hangs inside gen_tcp:recv,
and can't process other requests (including ssl:send).  It seems this can be
solved by moving gen_tcp:recv call to another process...  What about something
like this:

recv(Socket, Length, Timeout) when record(Socket, sslsocket) ->
    Req = {recv, self()}, 
    ProxySock = gen_server:call(, Req, infinity),
    case gen_tcp:recv(St#st.proxysock, Length, Timeout) of
        {ok, _} = Result -> Result;
        {error, timeout} -> {error, timeout};
        {error, Reason} = Error ->
            gen_server:call(, {switch to closing state}, infinity),

handle_call({recv, Client}, From, St) 
  when St#st.status =/= closed, == false ->
    debug(St, "recv: client = ~w~n", [Client]),
    Reply = St#st.proxysock,
    {reply, Reply, St};

I.e. gen_tcp:recv will be executed in process that calls ssl:recv.

 >> * (Feature Request) Many protocols have some kinds of STARTTLS command
 >> (e.g. IMAP, POP3 (RFC2595), Jabber/XMPP).  So this would be great to have
 >> ability to convert gen_tcp sockets to ssl ones.

 PH> Ok, I am not familiar with STARTTLS or similar, but I will investigate it.


More information about the erlang-questions mailing list