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

* src/eldap/eldap.erl: 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: 2086
This commit is contained in:
Evgeniy Khramtsov 2009-05-16 13:18:15 +00:00
parent 08ba5346db
commit 5f67072e06

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;