summaryrefslogtreecommitdiff
path: root/src/tcp_acceptor.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/tcp_acceptor.erl')
-rw-r--r--src/tcp_acceptor.erl34
1 files changed, 25 insertions, 9 deletions
diff --git a/src/tcp_acceptor.erl b/src/tcp_acceptor.erl
index 0248f878..2725be31 100644
--- a/src/tcp_acceptor.erl
+++ b/src/tcp_acceptor.erl
@@ -55,21 +55,30 @@ handle_info({inet_async, LSock, Ref, {ok, Sock}},
inet_db:register_socket(Sock, Mod),
%% handle
- file_handle_cache:transfer(apply(M, F, A ++ [Sock])),
- ok = file_handle_cache:obtain(),
+ case tune_buffer_size(Sock) of
+ ok -> file_handle_cache:transfer(
+ apply(M, F, A ++ [Sock])),
+ ok = file_handle_cache:obtain();
+ {error, enotconn} -> catch port_close(Sock);
+ {error, Err} -> {ok, {IPAddress, Port}} = inet:sockname(LSock),
+ error_logger:error_msg(
+ "failed to tune buffer size of "
+ "connection accepted on ~s:~p - ~p (~s)~n",
+ [rabbit_misc:ntoab(IPAddress), Port,
+ Err, rabbit_misc:format_inet_error(Err)]),
+ catch port_close(Sock)
+ end,
%% accept more
accept(State);
-handle_info({inet_async, LSock, Ref, {error, closed}},
- State=#state{sock=LSock, ref=Ref}) ->
- %% It would be wrong to attempt to restart the acceptor when we
- %% know this will fail.
- {stop, normal, State};
-
handle_info({inet_async, LSock, Ref, {error, Reason}},
State=#state{sock=LSock, ref=Ref}) ->
- {stop, {accept_failed, Reason}, State};
+ case Reason of
+ closed -> {stop, normal, State}; %% listening socket closed
+ econnaborted -> accept(State); %% client sent RST before we accepted
+ _ -> {stop, {accept_failed, Reason}, State}
+ end;
handle_info(_Info, State) ->
{noreply, State}.
@@ -87,3 +96,10 @@ accept(State = #state{sock=LSock}) ->
{ok, Ref} -> {noreply, State#state{ref=Ref}};
Error -> {stop, {cannot_accept, Error}, State}
end.
+
+tune_buffer_size(Sock) ->
+ case inet:getopts(Sock, [sndbuf, recbuf, buffer]) of
+ {ok, BufSizes} -> BufSz = lists:max([Sz || {_Opt, Sz} <- BufSizes]),
+ inet:setopts(Sock, [{buffer, BufSz}]);
+ Error -> Error
+ end.