25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-26 16:26:24 +01:00

LDAP bind attempts: log warnings and increase timeout after reject.

Merged from trunk SVN r2086:
Log warnings on unsuccessful LDAP bind attempts.
Increase timeout before the next LDAP bind attempt up to
five seconds if the last bind attempt was rejected by the
LDAP server ("soft" error) (thanks to Konstantin Khomoutov)

SVN Revision: 2087
This commit is contained in:
Badlop 2009-05-18 11:41:53 +00:00
parent 5bd67495ed
commit 0a9581a375

View File

@ -91,6 +91,8 @@
-define(SEND_TIMEOUT, 30000). -define(SEND_TIMEOUT, 30000).
-define(MAX_TRANSACTION_ID, 65535). -define(MAX_TRANSACTION_ID, 65535).
-define(MIN_TRANSACTION_ID, 0). -define(MIN_TRANSACTION_ID, 0).
%% Grace period after "soft" LDAP bind errors:
-define(GRACEFUL_RETRY_TIMEOUT, 5000).
-record(eldap, {version = ?LDAP_VERSION, -record(eldap, {version = ?LDAP_VERSION,
hosts, % Possible hosts running LDAP servers hosts, % Possible hosts running LDAP servers
@ -474,11 +476,14 @@ handle_info({tcp, _Socket, Data}, wait_bind_response, S) ->
case catch recvd_wait_bind_response(Data, S) of case catch recvd_wait_bind_response(Data, S) of
bound -> bound ->
dequeue_commands(S); dequeue_commands(S);
{fail_bind, _Reason} -> {fail_bind, Reason} ->
report_bind_failure(S#eldap.host, S#eldap.port, Reason),
{next_state, connecting, close_and_retry(S, ?GRACEFUL_RETRY_TIMEOUT)};
{'EXIT', Reason} ->
report_bind_failure(S#eldap.host, S#eldap.port, Reason),
{next_state, connecting, close_and_retry(S)}; {next_state, connecting, close_and_retry(S)};
{'EXIT', _Reason} -> {error, Reason} ->
{next_state, connecting, close_and_retry(S)}; report_bind_failure(S#eldap.host, S#eldap.port, Reason),
{error, _Reason} ->
{next_state, connecting, close_and_retry(S)} {next_state, connecting, close_and_retry(S)}
end; end;
@ -790,7 +795,7 @@ check_tag(Data) ->
_ -> throw({error,decoded_tag}) _ -> throw({error,decoded_tag})
end. end.
close_and_retry(S) -> close_and_retry(S, Timeout) ->
catch gen_tcp:close(S#eldap.fd), catch gen_tcp:close(S#eldap.fd),
Queue = dict:fold( Queue = dict:fold(
fun(_Id, [{Timer, Command, From, _Name}|_], Q) -> fun(_Id, [{Timer, Command, From, _Name}|_], Q) ->
@ -799,9 +804,16 @@ close_and_retry(S) ->
(_, _, Q) -> (_, _, Q) ->
Q Q
end, S#eldap.req_q, S#eldap.dict), end, S#eldap.req_q, S#eldap.dict),
erlang:send_after(?RETRY_TIMEOUT, self(), {timeout, retry_connect}), erlang:send_after(Timeout, self(), {timeout, retry_connect}),
S#eldap{fd=null, req_q=Queue, dict=dict:new()}. S#eldap{fd=null, req_q=Queue, dict=dict:new()}.
close_and_retry(S) ->
close_and_retry(S, ?RETRY_TIMEOUT).
report_bind_failure(Host, Port, Reason) ->
?WARNING_MSG("LDAP bind failed on ~s:~p~nReason: ~p",
[Host, Port, Reason]).
%%----------------------------------------------------------------------- %%-----------------------------------------------------------------------
%% Sort out timed out commands %% Sort out timed out commands
%%----------------------------------------------------------------------- %%-----------------------------------------------------------------------
@ -864,8 +876,7 @@ connect_bind(S) ->
host = Host, host = Host,
bind_timer = Timer}}; bind_timer = Timer}};
{error, Reason} -> {error, Reason} ->
?ERROR_MSG("LDAP bind failed on ~s:~p~nReason: ~p", report_bind_failure(Host, S#eldap.port, Reason),
[Host, S#eldap.port, Reason]),
NewS = close_and_retry(S), NewS = close_and_retry(S),
{ok, connecting, NewS#eldap{host = Host}} {ok, connecting, NewS#eldap{host = Host}}
end; end;