diff options
author | Daniil Fedotov <[email protected]> | 2016-05-03 13:28:09 +0100 |
---|---|---|
committer | Daniil Fedotov <[email protected]> | 2016-05-05 09:41:35 +0100 |
commit | 33b282356b786b831fe8f5414fa60397c4c7eaf9 (patch) | |
tree | 3a4dd0ad35248b88f8d26468c9e89ab83a83ec67 | |
parent | 6a1290f534164d1a5771dba37c23124652b9f7c9 (diff) | |
download | otp-33b282356b786b831fe8f5414fa60397c4c7eaf9.tar.gz otp-33b282356b786b831fe8f5414fa60397c4c7eaf9.tar.bz2 otp-33b282356b786b831fe8f5414fa60397c4c7eaf9.zip |
Ignore tcp errors during close request to eldap
If underlying tcp connection is closed and LDAP operation returned tcp error,
then client applications tend to close ldap handle with eldap:close.
This will cause do_unbind to throw gen_tcp_error, which is unhandled
and will be sent to linked process as {nocatch, {gen_tcp_error, ...}}.
eldap should ignore gen_tcp_error during close, because it will be closing anyway.
-rw-r--r-- | lib/eldap/src/eldap.erl | 7 | ||||
-rw-r--r-- | lib/eldap/test/eldap_basic_SUITE.erl | 27 |
2 files changed, 32 insertions, 2 deletions
diff --git a/lib/eldap/src/eldap.erl b/lib/eldap/src/eldap.erl index dc236f8a44..8994df10eb 100644 --- a/lib/eldap/src/eldap.erl +++ b/lib/eldap/src/eldap.erl @@ -564,7 +564,12 @@ loop(Cpid, Data) -> ?MODULE:loop(Cpid, NewData); {_From, close} -> - {no_reply,_NewData} = do_unbind(Data), + % Ignore tcp error if connection is already closed. + try do_unbind(Data) of + {no_reply,_NewData} -> ok + catch + throw:{gen_tcp_error, _TcpErr} -> ok + end, unlink(Cpid), exit(closed); diff --git a/lib/eldap/test/eldap_basic_SUITE.erl b/lib/eldap/test/eldap_basic_SUITE.erl index 9a23f74e22..536e891a1e 100644 --- a/lib/eldap/test/eldap_basic_SUITE.erl +++ b/lib/eldap/test/eldap_basic_SUITE.erl @@ -94,7 +94,8 @@ connection_tests() -> client_side_start_tls_timeout, client_side_bind_timeout, client_side_add_timeout, - client_side_search_timeout + client_side_search_timeout, + close_after_tcp_error ]. @@ -312,6 +313,30 @@ tcp_connection(Config) -> end. %%%---------------------------------------------------------------- + +close_after_tcp_error(Config) -> + Host = proplists:get_value(listen_host, Config), + Port = proplists:get_value(listen_port, Config), + Opts = proplists:get_value(tcp_connect_opts, Config), + T = 1000, + case eldap:open([Host], [{timeout,T},{port,Port}|Opts]) of + {ok,H} -> + Sl = proplists:get_value(listen_socket, Config), + gen_tcp:close(Sl), + {error,{gen_tcp_error,closed}} = eldap:simple_bind(H, anon, anon), + ok = eldap:close(H), + wait_for_close(H); + Other -> ct:fail("eldap:open failed: ~p",[Other]) + end. + +wait_for_close(H) -> + case erlang:is_process_alive(H) of + true -> timer:sleep(100), + wait_for_close(H); + false -> ok + end. + +%%%---------------------------------------------------------------- ssl_connection(Config) -> Host = proplists:get_value(listen_host, Config), Port = proplists:get_value(ssl_listen_port, Config), |