[erlang-questions] Strange SSL transport_accept behaviour

Trevor Woollacott trevorw@REDACTED
Fri May 4 17:21:14 CEST 2012


Hi,

I've noticed strange behaviour when ssl:transport_accept/2 returns with a
timeout. It appears that certain inet options are reset to internal values
and are never changed back if accept encounters an error (such as timeout).

In my case, I had set inet option {packet, http}, and after the accept timed
out it had changed to 0 (raw). 

For example:
> ssl:setopts( ListenSocket, [{packet, http}] ).
ok
> ssl:transport_accept( ListenSocket, Timeout ).
{error, timeout}
> ssl:getopts( ListenSocket, [packet] ).
{ok, [{packet,0}]}

The problem seems to have been introduced in Erlang R14B. Looking at the
source code below, we can see that the initial inet options are stored in
InetValues, and then the inet options are reset to internal_inet_values
(which includes {packet,0}) and the inet options are only set back to
InetValues if the accept was successful. 

Is this the correct behaviour? I'm thinking that for timeout (and possibly
certain other errors) the listener socket should be reset with the user
defined inet options?

transport_accept(#sslsocket{pid = {ListenSocket, #config{cb=CbInfo,
ssl=SslOpts}},
                            fd = new_ssl}, Timeout) ->
    
    %% The setopt could have been invoked on the listen socket
    %% and options should be inherited.
    EmOptions = emulated_options(),
    {ok, InetValues} = inet:getopts(ListenSocket, EmOptions),
    ok = inet:setopts(ListenSocket, internal_inet_values()),
    {CbModule,_,_, _} = CbInfo,    
    case CbModule:accept(ListenSocket, Timeout) of
    {ok, Socket} ->
        ok = inet:setopts(ListenSocket, InetValues),
        {ok, Port} = inet:port(Socket),
        ConnArgs = [server, "localhost", Port, Socket,
            {SslOpts, socket_options(InetValues)}, self(), CbInfo],
        case ssl_connection_sup:start_child(ConnArgs) of
        {ok, Pid} ->
            ssl_connection:socket_control(Socket, Pid, CbModule);
        {error, Reason} ->
            {error, Reason}
        end;
    {error, Reason} ->
        {error, Reason}
    end;

Regards,
Trevor





More information about the erlang-questions mailing list