Skip Menu |

This queue is for tickets about the Net-FTPSSL CPAN distribution.

Report information
The Basics
Id: 118418
Status: resolved
Priority: 0/
Queue: Net-FTPSSL

People
Owner: Nobody in particular
Requestors: MARKF [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.33
Fixed in: 0.35



Subject: SIGPIPE causing silent death
I was testing how well Net::FTPSSL 0.33 handles bad server behavior. The answer is currently, not very well. So, I was running this test script: use Net::FTPSSL; $f=Net::FTPSSL->new("127.0.0.1", Debug => 2, Croak => 1); $f->login($username, $password); eval { $result=$f->put("test.img","test2.img") }; print STDERR "Upload stopped\n"; And I was killing the server the script was connecting to with "kill -9" to simulate it going away half way through the upload. Sometimes I would see the expected "Uploaded stopped". Other times nothing - the process would unexpectedly exit. With the help of strace and a million debug statements in the code I discovered: 1) A SIGPIPE was causing the failure to occur. 2) This only happens when Croak is enabled. 3) The resulting code path was happening here: https://metacpan.org/source/CLEACH/Net-FTPSSL-0.33/FTPSSL.pm#L3100 Which was reached after the error handling was re-entered here: https://metacpan.org/source/CLEACH/Net-FTPSSL-0.33/FTPSSL.pm#L2949 In short it looks like the module is trying to gracefully close the connection by sending commands down the already closed connection and this is causing a SIGPIPE. The code should probably be corrected so it doesn't do this, but the issue might be better handled on a bigger scale with the use of SO_NOSIGPIPE or send rather than write with the appropriate flag. FWIW, doing a "local $SIG{PIPE} = 'IGNORE'" before the above script seems to totally address the issue. ######################################################### perl -v This is perl 5, version 20, subversion 2 (v5.20.2) built for x86_64-linux (with 1 registered patch, see perl -V for more detail) Copyright 1987-2015, Larry Wall Perl may be copied only under the terms of either the Artistic License or the GNU General Public License, which may be found in the Perl 5 source kit. Complete documentation for Perl, including FAQ lists, should be found on this system using "man perl" or "perldoc perl". If you have access to the Internet, point your browser at http://www.perl.org/, the Perl Home Page.
Hi Mark, Thank you for using my module. That's quite an interesting use case scenario. It's not one I've considered before. The code you are examining was meant for something far less catastrophic. But you are right that I should avoid cases where things silently fail. I'll see if I can get a fix out soon. I'll put in a 'local $SIG{PIPE} = "IGNORE";' right before the offending call to _abort() on L2949 for the graceful exit code block. Curtis On Mon Oct 17 16:24:56 2016, MARKF wrote: Show quoted text
> I was testing how well Net::FTPSSL 0.33 handles bad server behavior. > The answer is currently, not very well. > > So, I was running this test script: > > use Net::FTPSSL; > $f=Net::FTPSSL->new("127.0.0.1", Debug => 2, Croak => 1); > $f->login($username, $password); > eval { $result=$f->put("test.img","test2.img") }; > print STDERR "Upload stopped\n"; > > And I was killing the server the script was connecting to with "kill > -9" to simulate it going away half way through the upload. > > Sometimes I would see the expected "Uploaded stopped". Other times > nothing - the process would unexpectedly exit. > > With the help of strace and a million debug statements in the code I > discovered: > > 1) A SIGPIPE was causing the failure to occur. > 2) This only happens when Croak is enabled. > 3) The resulting code path was happening here: > > https://metacpan.org/source/CLEACH/Net-FTPSSL-0.33/FTPSSL.pm#L3100 > > Which was reached after the error handling was re-entered here: > > https://metacpan.org/source/CLEACH/Net-FTPSSL-0.33/FTPSSL.pm#L2949 > > In short it looks like the module is trying to gracefully close the > connection by sending commands down the already closed connection and > this is causing a SIGPIPE. > > The code should probably be corrected so it doesn't do this, but the > issue might be better handled on a bigger scale with the use of > SO_NOSIGPIPE or send rather than write with the appropriate flag. > > FWIW, doing a "local $SIG{PIPE} = 'IGNORE'" before the above script > seems to totally address the issue. > > > ######################################################### > > perl -v > > This is perl 5, version 20, subversion 2 (v5.20.2) built for x86_64- > linux > (with 1 registered patch, see perl -V for more detail) > > Copyright 1987-2015, Larry Wall > > Perl may be copied only under the terms of either the Artistic License > or the > GNU General Public License, which may be found in the Perl 5 source > kit. > > Complete documentation for Perl, including FAQ lists, should be found > on > this system using "man perl" or "perldoc perl". If you have access to > the > Internet, point your browser at http://www.perl.org/, the Perl Home > Page.
Hi Mark, Sorry about forgetting about this ticket, but I fell sick soon after I had originally replied to you. I've uploaded v0.35 for you with the fix listed below. Curtis On Mon Oct 17 18:24:47 2016, CLEACH wrote: Show quoted text
> Hi Mark, > > Thank you for using my module. That's quite an interesting use case > scenario. It's not one I've considered before. The code you are > examining was meant for something far less catastrophic. But you are > right that I should avoid cases where things silently fail. > > I'll see if I can get a fix out soon. I'll put in a 'local $SIG{PIPE} > = "IGNORE";' right before the offending call to _abort() on L2949 for > the graceful exit code block. > > Curtis > > On Mon Oct 17 16:24:56 2016, MARKF wrote:
> > I was testing how well Net::FTPSSL 0.33 handles bad server behavior. > > The answer is currently, not very well. > > > > So, I was running this test script: > > > > use Net::FTPSSL; > > $f=Net::FTPSSL->new("127.0.0.1", Debug => 2, Croak => 1); > > $f->login($username, $password); > > eval { $result=$f->put("test.img","test2.img") }; > > print STDERR "Upload stopped\n"; > > > > And I was killing the server the script was connecting to with "kill > > -9" to simulate it going away half way through the upload. > > > > Sometimes I would see the expected "Uploaded stopped". Other times > > nothing - the process would unexpectedly exit. > > > > With the help of strace and a million debug statements in the code I > > discovered: > > > > 1) A SIGPIPE was causing the failure to occur. > > 2) This only happens when Croak is enabled. > > 3) The resulting code path was happening here: > > > > https://metacpan.org/source/CLEACH/Net-FTPSSL-0.33/FTPSSL.pm#L3100 > > > > Which was reached after the error handling was re-entered here: > > > > https://metacpan.org/source/CLEACH/Net-FTPSSL-0.33/FTPSSL.pm#L2949 > > > > In short it looks like the module is trying to gracefully close the > > connection by sending commands down the already closed connection and > > this is causing a SIGPIPE. > > > > The code should probably be corrected so it doesn't do this, but the > > issue might be better handled on a bigger scale with the use of > > SO_NOSIGPIPE or send rather than write with the appropriate flag. > > > > FWIW, doing a "local $SIG{PIPE} = 'IGNORE'" before the above script > > seems to totally address the issue. > > > > > > ######################################################### > > > > perl -v > > > > This is perl 5, version 20, subversion 2 (v5.20.2) built for x86_64- > > linux > > (with 1 registered patch, see perl -V for more detail) > > > > Copyright 1987-2015, Larry Wall > > > > Perl may be copied only under the terms of either the Artistic > > License > > or the > > GNU General Public License, which may be found in the Perl 5 source > > kit. > > > > Complete documentation for Perl, including FAQ lists, should be found > > on > > this system using "man perl" or "perldoc perl". If you have access > > to > > the > > Internet, point your browser at http://www.perl.org/, the Perl Home > > Page.