25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-12-22 17:28:25 +01:00

implement lifetime for broken hashes

This commit is contained in:
Evgeniy Khramtsov 2010-10-05 21:27:28 +10:00
parent 58a5ed9cdc
commit 36df8c9035

View File

@ -62,6 +62,7 @@
-include("jlib.hrl"). -include("jlib.hrl").
-define(PROCNAME, ejabberd_mod_caps). -define(PROCNAME, ejabberd_mod_caps).
-define(BAD_HASH_LIFETIME, 600). %% in seconds
-record(caps, {node, version, hash, exts}). -record(caps, {node, version, hash, exts}).
-record(caps_features, {node_pair, features = []}). -record(caps_features, {node_pair, features = []}).
@ -104,10 +105,10 @@ get_features(#caps{node = Node, version = Version, exts = Exts}) ->
BinaryNode = node_to_binary(Node, SubNode), BinaryNode = node_to_binary(Node, SubNode),
case cache_tab:lookup(caps_features, BinaryNode, case cache_tab:lookup(caps_features, BinaryNode,
caps_read_fun(BinaryNode)) of caps_read_fun(BinaryNode)) of
error -> {ok, Features} when is_list(Features) ->
Acc; binary_to_features(Features) ++ Acc;
{ok, Features} -> _ ->
binary_to_features(Features) ++ Acc Acc
end end
end, [], SubNodes). end, [], SubNodes).
@ -358,7 +359,16 @@ feature_request(Host, From, Caps, [SubNode | Tail] = SubNodes) ->
BinaryNode = node_to_binary(Node, SubNode), BinaryNode = node_to_binary(Node, SubNode),
case cache_tab:lookup(caps_features, BinaryNode, case cache_tab:lookup(caps_features, BinaryNode,
caps_read_fun(BinaryNode)) of caps_read_fun(BinaryNode)) of
error -> {ok, Fs} when is_list(Fs) ->
feature_request(Host, From, Caps, Tail);
Other ->
NeedRequest = case Other of
{ok, TS} ->
now_ts() >= TS + ?BAD_HASH_LIFETIME;
_ ->
true
end,
if NeedRequest ->
IQ = #iq{type = get, IQ = #iq{type = get,
xmlns = ?NS_DISCO_INFO, xmlns = ?NS_DISCO_INFO,
sub_el = [{xmlelement, "query", sub_el = [{xmlelement, "query",
@ -371,8 +381,9 @@ feature_request(Host, From, Caps, [SubNode | Tail] = SubNodes) ->
end, end,
ejabberd_local:route_iq( ejabberd_local:route_iq(
jlib:make_jid("", Host, ""), From, IQ, F); jlib:make_jid("", Host, ""), From, IQ, F);
_ -> true ->
feature_request(Host, From, Caps, Tail) feature_request(Host, From, Caps, Tail)
end
end; end;
feature_request(_Host, _From, _Caps, []) -> feature_request(_Host, _From, _Caps, []) ->
ok. ok.
@ -394,18 +405,19 @@ feature_response(#iq{type = result,
caps_features, BinaryNode, BinaryFeatures, caps_features, BinaryNode, BinaryFeatures,
caps_write_fun(BinaryNode, BinaryFeatures)); caps_write_fun(BinaryNode, BinaryFeatures));
false -> false ->
cache_tab:insert(caps_features, BinaryNode, [], %% We cache current timestamp and will probe the client
caps_write_fun(BinaryNode, [])) %% after BAD_HASH_LIFETIME seconds.
cache_tab:insert(caps_features, BinaryNode, now_ts(),
caps_write_fun(BinaryNode, now_ts()))
end, end,
feature_request(Host, From, Caps, SubNodes); feature_request(Host, From, Caps, SubNodes);
feature_response(timeout, _Host, _From, _Caps, _SubNodes) ->
ok;
feature_response(_IQResult, Host, From, Caps, [SubNode | SubNodes]) -> feature_response(_IQResult, Host, From, Caps, [SubNode | SubNodes]) ->
%% We got type=error or invalid type=result stanza, so %% We got type=error or invalid type=result stanza or timeout,
%% we cache empty feature not to probe the client permanently %% so we cache current timestamp and will probe the client
%% after BAD_HASH_LIFETIME seconds.
BinaryNode = node_to_binary(Caps#caps.node, SubNode), BinaryNode = node_to_binary(Caps#caps.node, SubNode),
cache_tab:insert(caps_features, BinaryNode, [], cache_tab:insert(caps_features, BinaryNode, now_ts(),
caps_write_fun(BinaryNode, [])), caps_write_fun(BinaryNode, now_ts())),
feature_request(Host, From, Caps, SubNodes). feature_request(Host, From, Caps, SubNodes).
node_to_binary(Node, SubNode) -> node_to_binary(Node, SubNode) ->
@ -611,3 +623,7 @@ gb_trees_fold_iter(F, Acc, Iter) ->
_ -> _ ->
Acc Acc
end. end.
now_ts() ->
{MegaSecs, Secs, _} = now(),
MegaSecs*1000000 + Secs.