24
1
mirror of https://github.com/processone/ejabberd.git synced 2024-08-14 01:38:09 +02:00

Improved behaviour on SSL handshake failure

This commit is contained in:
Alexey Shchepin 2010-10-14 15:59:23 +03:00
parent a93991bef2
commit c10e43f95f

View File

@ -22,6 +22,7 @@
-include("ejabberd.hrl"). -include("ejabberd.hrl").
-include("jlib.hrl"). -include("jlib.hrl").
-include_lib("kernel/include/file.hrl").
-record(state, {host, -record(state, {host,
socket, socket,
@ -32,6 +33,8 @@
feedback_port, feedback_port,
feedback_buf = <<>>, feedback_buf = <<>>,
certfile, certfile,
certfile_mtime,
failure_script,
queue, queue,
soundfile, soundfile,
cmd_id = 0, cmd_id = 0,
@ -41,6 +44,7 @@
-define(PROCNAME, ejabberd_mod_applepush_service). -define(PROCNAME, ejabberd_mod_applepush_service).
-define(RECONNECT_TIMEOUT, 5000). -define(RECONNECT_TIMEOUT, 5000).
-define(FEEDBACK_RECONNECT_TIMEOUT, 30000). -define(FEEDBACK_RECONNECT_TIMEOUT, 30000).
-define(HANDSHAKE_TIMEOUT, 60000).
-define(MAX_QUEUE_SIZE, 1000). -define(MAX_QUEUE_SIZE, 1000).
-define(CACHE_SIZE, 4096). -define(CACHE_SIZE, 4096).
-define(MAX_PAYLOAD_SIZE, 255). -define(MAX_PAYLOAD_SIZE, 255).
@ -116,6 +120,7 @@ init([MyHost, Opts]) ->
Feedback = gen_mod:get_opt(feedback, Opts, undefined), Feedback = gen_mod:get_opt(feedback, Opts, undefined),
Port = gen_mod:get_opt(port, Opts, 2195), Port = gen_mod:get_opt(port, Opts, 2195),
FeedbackPort = gen_mod:get_opt(feedback_port, Opts, 2196), FeedbackPort = gen_mod:get_opt(feedback_port, Opts, 2196),
FailureScript = gen_mod:get_opt(failure_script, Opts, undefined),
%MyHost = gen_mod:get_opt_host(Host, Opts, "applepush.@HOST@"), %MyHost = gen_mod:get_opt_host(Host, Opts, "applepush.@HOST@"),
self() ! connect, self() ! connect,
case Feedback of case Feedback of
@ -131,6 +136,7 @@ init([MyHost, Opts]) ->
feedback = Feedback, feedback = Feedback,
feedback_port = FeedbackPort, feedback_port = FeedbackPort,
certfile = CertFile, certfile = CertFile,
failure_script = FailureScript,
queue = {0, queue:new()}, queue = {0, queue:new()},
soundfile = SoundFile}}. soundfile = SoundFile}}.
@ -171,6 +177,11 @@ handle_info({route, From, To, Packet}, State) ->
end; end;
handle_info(connect, State) -> handle_info(connect, State) ->
connect(State); connect(State);
handle_info(connect_feedback, #state{certfile_mtime = MTime} = State)
when MTime /= undefined ->
erlang:send_after(?FEEDBACK_RECONNECT_TIMEOUT, self(),
connect_feedback),
{noreply, State};
handle_info(connect_feedback, State) handle_info(connect_feedback, State)
when State#state.feedback /= undefined, when State#state.feedback /= undefined,
State#state.feedback_socket == undefined -> State#state.feedback_socket == undefined ->
@ -447,7 +458,7 @@ make_payload(State, Msg, Badge, Sound, Sender) ->
Payload Payload
end. end.
connect(#state{socket = undefined} = State) -> connect(#state{socket = undefined, certfile_mtime = undefined} = State) ->
Gateway = State#state.gateway, Gateway = State#state.gateway,
Port = State#state.port, Port = State#state.port,
CertFile = State#state.certfile, CertFile = State#state.certfile,
@ -457,16 +468,56 @@ connect(#state{socket = undefined} = State) ->
{ok, Socket} -> {ok, Socket} ->
{noreply, resend_messages(State#state{socket = Socket})}; {noreply, resend_messages(State#state{socket = Socket})};
{error, Reason} -> {error, Reason} ->
{Timeout, State2} =
case Reason of
esslconnect ->
MTime = get_mtime(CertFile),
case State#state.failure_script of
undefined ->
ok;
FailureScript ->
os:cmd(FailureScript ++ " " ++ Gateway)
end,
{?HANDSHAKE_TIMEOUT,
State#state{certfile_mtime = MTime}};
_ ->
{?RECONNECT_TIMEOUT, State}
end,
?ERROR_MSG("(~p) Connection to ~p:~p failed: ~p, " ?ERROR_MSG("(~p) Connection to ~p:~p failed: ~p, "
"retrying after ~p seconds",
[State2#state.host, Gateway, Port,
Reason, Timeout div 1000]),
erlang:send_after(Timeout, self(), connect),
{noreply, State2}
end;
connect(#state{socket = undefined, certfile_mtime = MTime} = State) ->
CertFile = State#state.certfile,
case get_mtime(CertFile) of
MTime ->
Gateway = State#state.gateway,
Port = State#state.port,
Timeout = ?HANDSHAKE_TIMEOUT,
?ERROR_MSG("(~p) Connection to ~p:~p postponed: "
"waiting for ~p update, "
"retrying after ~p seconds", "retrying after ~p seconds",
[State#state.host, Gateway, Port, [State#state.host, Gateway, Port,
Reason, ?RECONNECT_TIMEOUT div 1000]), CertFile, Timeout div 1000]),
erlang:send_after(?RECONNECT_TIMEOUT, self(), connect), erlang:send_after(Timeout, self(), connect),
{noreply, State} {noreply, State};
_ ->
connect(State#state{certfile_mtime = undefined})
end; end;
connect(State) -> connect(State) ->
{noreply, State}. {noreply, State}.
get_mtime(File) ->
case file:read_file_info(File) of
{ok, FileInfo} ->
FileInfo#file_info.mtime;
{error, _} ->
no_certfile
end.
bounce_message(From, To, Packet, Reason) -> bounce_message(From, To, Packet, Reason) ->
{xmlelement, _, Attrs, _} = Packet, {xmlelement, _, Attrs, _} = Packet,
Type = xml:get_attr_s("type", Attrs), Type = xml:get_attr_s("type", Attrs),