aboutsummaryrefslogtreecommitdiffstats
path: root/erts/preloaded/src/prim_inet.erl
diff options
context:
space:
mode:
authorRory Byrne <[email protected]>2015-04-16 18:01:23 +0100
committerRory Byrne <[email protected]>2015-06-09 21:51:29 +0100
commiteed21b4fd99c8ab71dcefd3802104186af1cb6b0 (patch)
treef4191a382894c67ee002c2087749a251e5316b05 /erts/preloaded/src/prim_inet.erl
parent0098eed847516cc6760d961421c83527816e35ae (diff)
downloadotp-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/prim_inet.erl')
-rw-r--r--erts/preloaded/src/prim_inet.erl13
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) ->