diff options
author | Rory Byrne <[email protected]> | 2015-04-16 18:01:23 +0100 |
---|---|---|
committer | Rory Byrne <[email protected]> | 2015-06-09 21:51:29 +0100 |
commit | eed21b4fd99c8ab71dcefd3802104186af1cb6b0 (patch) | |
tree | f4191a382894c67ee002c2087749a251e5316b05 /erts/preloaded/src | |
parent | 0098eed847516cc6760d961421c83527816e35ae (diff) | |
download | otp-eed21b4fd99c8ab71dcefd3802104186af1cb6b0.tar.gz otp-eed21b4fd99c8ab71dcefd3802104186af1cb6b0.tar.bz2 otp-eed21b4fd99c8ab71dcefd3802104186af1cb6b0.zip |
Fix socket option {linger, {true, 0}} to abort TCP connections
Up until now, if {linger, {true, 0}} is set on the socket and there is
data in the port driver queue, the connection is not aborted until
the port queue is empty and close() is called on the underlying file
descriptor. This bug allows an idle TCP client to prevent a server
from terminating the connection and freeing resources. This patch
fixes the problem by discarding the port queue if the socket is closed
when {linger, {true, 0}} is set.
Diffstat (limited to 'erts/preloaded/src')
-rw-r--r-- | erts/preloaded/src/prim_inet.erl | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl index fb0f67aa8a..5e0b38aa68 100644 --- a/erts/preloaded/src/prim_inet.erl +++ b/erts/preloaded/src/prim_inet.erl @@ -146,11 +146,16 @@ shutdown_1(S, How) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% close(S) when is_port(S) -> - case subscribe(S, [subs_empty_out_q]) of - {ok, [{subs_empty_out_q,N}]} when N > 0 -> - close_pend_loop(S, N); %% wait for pending output to be sent + case getopt(S, linger) of + {ok,{true,0}} -> + close_port(S); _ -> - close_port(S) + case subscribe(S, [subs_empty_out_q]) of + {ok, [{subs_empty_out_q,N}]} when N > 0 -> + close_pend_loop(S, N); %% wait for pending output to be sent + _ -> + close_port(S) + end end. close_pend_loop(S, N) -> |