From 4319d23a331fadd5bd515d4a78154cc829d13981 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Mon, 20 Feb 2012 14:40:30 -0500 Subject: [PATCH] Detect remote disconnect in Perl XMPP reader When the jabber server severs the connection, it leaves the Perl libs with a socket that perpetually appears ready for reading, but always returns 0 bytes. This produces a loop in the client code. This change detects this situation, logs an error, and throws an exception. Signed-off-by: Bill Erickson Signed-off-by: Dan Scott --- .../OpenSRF/Transport/SlimJabber/XMPPReader.pm | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/perl/lib/OpenSRF/Transport/SlimJabber/XMPPReader.pm b/src/perl/lib/OpenSRF/Transport/SlimJabber/XMPPReader.pm index 556f597..b8a5da1 100644 --- a/src/perl/lib/OpenSRF/Transport/SlimJabber/XMPPReader.pm +++ b/src/perl/lib/OpenSRF/Transport/SlimJabber/XMPPReader.pm @@ -5,6 +5,7 @@ use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); use Time::HiRes qw/time/; use OpenSRF::Transport::SlimJabber::XMPPMessage; use OpenSRF::Utils::Logger qw/$logger/; +use OpenSRF::EX; # ----------------------------------------------------------- # Connect, disconnect, and authentication messsage templates @@ -211,15 +212,25 @@ sub wait { my $buf; my $read_size = 1024; my $nonblock = 0; + my $nbytes; + my $first_read = 1; - while(my $n = sysread($socket, $buf, $read_size)) { + while($nbytes = sysread($socket, $buf, $read_size)) { $self->{parser}->parse_more($buf) if $buf; - if($n < $read_size or $self->peek_msg) { + if($nbytes < $read_size or $self->peek_msg) { set_block($socket) if $nonblock; last; } set_nonblock($socket) unless $nonblock; $nonblock = 1; + $first_read = 0; + } + + if ($nbytes == 0 and $first_read) { + # if the first read on an active socket is 0 bytes, + # the socket has been disconnected from the remote end. + $logger->error("Disconnected from Jabber server"); + throw OpenSRF::EX::Jabber("Disconnected from Jabber server"); } return $self->next_msg; -- 2.43.2