aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2014-11-03 00:12:58 +0100
committerAnders Svensson <[email protected]>2014-11-03 12:16:57 +0100
commit66d67762be1cf0a3b9ac068d597c6d8bdaf2e3d7 (patch)
tree95485009ba0a503c5dfe24ff8af8f474c8da77c0
parent3b51661f1f9f70cf820026cb345523c05aad2dfa (diff)
downloadotp-66d67762be1cf0a3b9ac068d597c6d8bdaf2e3d7.tar.gz
otp-66d67762be1cf0a3b9ac068d597c6d8bdaf2e3d7.tar.bz2
otp-66d67762be1cf0a3b9ac068d597c6d8bdaf2e3d7.zip
Fix ignored connect timer
There are two timers governing the establishment of peer connections: connect_timer and watchdog_timer. The former is the RFC 6733 Tc timer and is used by diameter_service to establish an initial connection. The latter is RFC 3539 TwInit and is used by diameter_watchdog for connection reestablishment after the watchdog leaves state INITIAL. A connecting transport ignored the connect timer since the watchdog process never died, regardless of the watchdog state, causing the watchdog timer to handle reconnection. This seems to have been broken for some time.
-rw-r--r--lib/diameter/src/base/diameter_watchdog.erl36
1 files changed, 17 insertions, 19 deletions
diff --git a/lib/diameter/src/base/diameter_watchdog.erl b/lib/diameter/src/base/diameter_watchdog.erl
index eff5096745..b7f2d24941 100644
--- a/lib/diameter/src/base/diameter_watchdog.erl
+++ b/lib/diameter/src/base/diameter_watchdog.erl
@@ -255,11 +255,15 @@ close({'DOWN', _, process, TPid, {shutdown, Reason}},
close(_, _) ->
ok.
-event(_, #watchdog{status = T}, #watchdog{status = T}) ->
- ok;
-
-event(_, #watchdog{transport = undefined}, #watchdog{transport = undefined}) ->
+event(_,
+ #watchdog{status = From, transport = F},
+ #watchdog{status = To, transport = T})
+ when F == undefined, T == undefined; %% transport not started
+ From == initial, To == down; %% never really left INITIAL
+ From == To -> %% no state transition
ok;
+%% Note that there is no INITIAL -> DOWN transition in RFC 3539: ours
+%% is just a consequence of stop.
event(Msg,
#watchdog{status = From, transport = F, parent = Pid},
@@ -411,7 +415,7 @@ transition({'DOWN', _, process, TPid, _Reason},
stop;
%% ... or not.
-transition({'DOWN', _, process, TPid, _Reason},
+transition({'DOWN', _, process, TPid, _Reason} = D,
#watchdog{transport = TPid,
status = T,
restrict = {_,R}}
@@ -422,20 +426,14 @@ transition({'DOWN', _, process, TPid, _Reason},
%% Close an accepting watchdog immediately if there's no
%% restriction on the number of connections to the same peer: the
- %% state machine never enters state REOPEN in this case. The
- %% 'close' message (instead of stop) is so as not to bypass the
- %% sending of messages to the service process in handle_info/2.
-
- if T /= initial, M == accept, not R ->
- send(self(), close),
- S#watchdog{status = down};
- T /= initial ->
- set_watchdog(S#watchdog{status = down});
- M == connect ->
- set_watchdog(S);
- M == accept ->
- send(self(), close),
- S
+ %% state machine never enters state REOPEN in this case.
+
+ if T == initial;
+ M == accept, not R ->
+ close(D, S0),
+ stop;
+ true ->
+ set_watchdog(S#watchdog{status = down})
end;
%% Incoming message.