I am working with an ssl acceptor pool (10 acceptors) and am using the {packet,4} option. The first incoming connection works fine, however the second connection ends up using {packet,0}.<br><div><br></div><div><br></div>
<div>Short version: ssl:transport_accept() is just plain thread-unsafe with respect to ListenSocket.</div><div><br></div><div>Long version:</div><div>In ssl:transport_accept(), options on the underlying listen socket are backed up and then replaced with internal_inet_values() as shown below. When the underlying transport accept() returns, the backup up options are put back into the listen socket and also go on to form options in an ssl process.</div>
<div><br></div><div>The problem is that a second transport_accept() call will backup *internal_inet_values* , and those incorrect values will be passed onto the ssl process.</div><div><br></div><div><br></div><div><br></div>
<div>Thats what it looks like anyway; I haven't traced everything out in detail. My work around for now is to set my acceptor pool to size 1 (can you still call that a pool? ;)</div><div><br></div><div>Dan.</div><div>
<br></div><div><br></div><div><br></div><div>From ssl.erl:</div><div><br></div><div><div>transport_accept(#sslsocket{pid = {ListenSocket, #config{cb=CbInfo, ssl=SslOpts}}}, Timeout) -></div><div> </div><div> %% The setopt could have been invoked on the listen socket</div>
<div> %% and options should be inherited.</div><div> EmOptions = emulated_options(),</div><div> {ok, InetValues} = inet:getopts(ListenSocket, EmOptions),</div><div> ok = inet:setopts(ListenSocket, internal_inet_values()),</div>
<div> {CbModule,_,_, _} = CbInfo, </div><div> case CbModule:accept(ListenSocket, Timeout) of</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>{ok, Socket} -></div><div><span class="Apple-tab-span" style="white-space:pre"> </span> ok = inet:setopts(ListenSocket, InetValues),</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span> {ok, Port} = inet:port(Socket),</div><div><span class="Apple-tab-span" style="white-space:pre"> </span> ConnArgs = [server, "localhost", Port, Socket,</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>{SslOpts, socket_options(InetValues)}, self(), CbInfo],</div><div><span class="Apple-tab-span" style="white-space:pre"> </span> case ssl_connection_sup:start_child(ConnArgs) of</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>{ok, Pid} -></div><div><span class="Apple-tab-span" style="white-space:pre"> </span> ssl_connection:socket_control(Socket, Pid, CbModule);</div><div>
<span class="Apple-tab-span" style="white-space:pre"> </span>{error, Reason} -></div><div><span class="Apple-tab-span" style="white-space:pre"> </span> {error, Reason}</div><div><span class="Apple-tab-span" style="white-space:pre"> </span> end;</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>{error, Reason} -></div><div><span class="Apple-tab-span" style="white-space:pre"> </span> {error, Reason}</div><div> end.</div></div><div><br></div>
<div><br></div><div><div>emulated_options() -></div><div> [mode, packet, active, header, packet_size].</div><div><br></div><div>internal_inet_values() -></div><div> [{packet_size,0},{packet, 0},{header, 0},{active, false},{mode,binary}].</div>
</div><div><br></div>