From eb546e2b4b21d2f7bb2f7d3258dbf87daae97d1f Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 4 Feb 2010 18:45:28 -0500 Subject: [PATCH] Time out and start a new login/connection attempt if libpurple doesn't respond. --- perl/lib/Thrasher/Protocol/Purple.pm | 50 ++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/perl/lib/Thrasher/Protocol/Purple.pm b/perl/lib/Thrasher/Protocol/Purple.pm index 8fd5195..52ceb15 100644 --- a/perl/lib/Thrasher/Protocol/Purple.pm +++ b/perl/lib/Thrasher/Protocol/Purple.pm @@ -301,6 +301,7 @@ sub _connection { } $session->{'purple_connection_created'} = 1; + delete($protocol->{'connection_started_at'}->{$jid}); my $continuation = delete($session->{'connection_cb'}); if ($continuation) { $continuation->($session); @@ -349,6 +350,15 @@ sub _connection_error { return 0; } my $protocol = $session->{protocol}; + if ($protocol) { + # Clear connection state. + delete($session->{'connection_cb'}); + delete($protocol->{'connection_started_at'}->{$jid}); + } + else { + log("_connection($jid): No protocol?!!"); + return 0; + } my $attempt_reconnect = 0; my $error = ''; @@ -545,19 +555,37 @@ sub create_login_session { return; } - # 0 => no thrasher_action_login error. - my $login_error = THPPW::thrasher_action_login({ - jid => Encode::encode("UTF-8", $jid), + my $jid_enc = Encode::encode('UTF-8', $jid); + my %login_args = ( + jid => $jid_enc, proto => $self->prpl, %$registration_info, %{ $self->{'configuration'}->{'extra_login_args'} || {} }, - }); - if ($login_error == 2) { - # PurpleAccount already exists. But if component called here, - # the session must already be gone. Thus, must have logged out - # during the async libpurple connection attempt and now trying - # to log back in. + ); + my $login_error = THPPW::thrasher_action_login(\%login_args); + my $last_connection_started_at = $self->{'connection_started_at'}->{$jid}; + + # PurpleAccount already exists. But if component called here, + # the session must already be gone. Thus, must have logged out + # during the async libpurple connection attempt and now trying + # to re-log in. + if ($login_error == 2 + && $last_connection_started_at + && time() - $last_connection_started_at > 600) { + # Async libpurple login started more than 10 minutes ago but + # _connection{,_error} has still not come back. Destroy the + # old login attempt and start a new one. # + # E.g. the PURPLE_CONNECTED state was never reached due to a + # MSN ADL/FQY counting bug? + debug('Discarding aged PurpleAccount attempt from ' + . $last_connection_started_at); + THPPW::thrasher_action_logout($jid_enc); + $login_error = THPPW::thrasher_action_login(\%login_args); + # In theory, logout removed the PurpleAccount so the new + # $login_error can't be 2. But--don't risk it! + } + if ($login_error == 2) { # Reject for now. Eventually _connection or _connection_error # will come back and login attempts will be possible again. # @@ -566,11 +594,12 @@ sub create_login_session { # logins until the registration changes. # # Could have this session "take over" the PurpleAccount, but - # what if credentials differ? + # what if credentials differ? Or if libpurple never finishes? $continuation->('conflict'); $component->logout($session); return; } + elsif ($login_error != 0) { # Rejected before we're even trying to connect pretty # much means syntactically invalid credentials @@ -579,6 +608,7 @@ sub create_login_session { return; } + $self->{'connection_started_at'}->{$jid} = time(); $session->{'connection_cb'} = $continuation; } -- 2.11.4.GIT