Subject: | Net-BGP-0.14 not able to restart a session with a peer after hold timer expires. |
Date: | Wed, 30 May 2012 16:03:51 -0400 |
To: | bug-Net-BGP [...] rt.cpan.org |
From: | Stuart Pearlman <cpan-bug-reporter [...] kaloram.com> |
Module version: Net-BGP-0.14
Perl version: 5.10.1
OS version: RedHat 6.1 (Linux <my-hostname> 2.6.32-131.0.15.el6.x86_64 #1 SMP Tue May 10 15:42:40 EDT 2011 x86_64 x86_64 x86_64 GNU/Linux)
Short Description:
It appears it is possible for Net::BGP::Transport to get in a state
where old messages from previously closed sessions remain at the
front of the message queue (@{%this->{_message_queue}}), resulting
in the inability to restart a peer. Below is a description of what
I did to trigger the bug and a patch that seems to fix it.
Long Description:
I have Net::BGP talking to a Quagga bgpd process. My Net::BGP
process includes the following code:
$peer->add_timer(
sub {
my $peer = shift;
my $peer_id = $peer->peer_id( );
logmsg "$peer_id timer callback\n";
# XXX - We seem to need this to get reconnects
# to work.
if ( not $peer->is_established( ) ) {
logmsg "$peer_id: attempting restart\n";
$peer->start( );
return;
}
...
},
60,
);
If I send a SIGSTOP to the Quagga bgpd process and wait for the
Hold Timer in my Net::BGP process to expire AND for the above timer
callback to attempt restarting the connection multiple times before
I send a SIGCONT to the Quagga bgpd the session never recovers.
It alternates between "OPEN Message Error / Unsupported Version
Number" errors and "UPDATE Message Error / Malformed Attribute
List" errors.
What appears to be happening is that messages are being left in
@{$this->{_message_queue}} when Net::BGP::Transport::_close_session()
is called. As I understand the code, it does not make sense for
@{$this->{_message_queue}} to retain messages across a session
close/session restart. Adding the line:
$this->{_message_queue} = [];
to Net::BGP::Transport::_close_session() fixes the problem, allowing
the session to be restarted correctly. Here is a patch:
diff -N -u -r Net-BGP-0.14.orig/lib/Net/BGP/Transport.pm Net-BGP-0.14/lib/Net/BGP/Transport.pm
--- Net-BGP-0.14.orig/lib/Net/BGP/Transport.pm 2010-09-18 10:12:51.000000000 -0400
+++ Net-BGP-0.14/lib/Net/BGP/Transport.pm 2012-05-30 15:38:45.534481684 -0400
@@ -714,6 +714,7 @@
$this->{_hold_timer} = undef;
$this->{_keep_alive_timer} = undef;
$this->{_connect_retry_timer} = undef;
+ $this->{_message_queue} = [];
return ( BGP_STATE_IDLE );
}