Subject: | Net::Cmd->dataend might fail for non-blocking IO |
Date: | Fri, 21 Nov 2014 17:54:41 +0100 |
To: | bug-libnet [...] rt.cpan.org |
From: | Jan-Pieter Cornet <johnpc [...] xs4all.nl> |
I've spotted (and patched) a rather hard to replicate bug in Net::Cmd.
The problem is this, suppose:
$smtp = Net::SMTP->new(...);
$smtp->blocking(0);
[...]
$smtp->dataend(); # <-- this might fail.
If the send buffer is full, the syswrite() inside dataend() will fail, because it doesn't wait for the socket to be available (like Net::Cmd->datasend() does).
In newer versions of libnet, it will notice the failure (because syswrite will return undef with $! == EAGAIN or $! == EWOULDBLOCK), and terminate the connection.
In older versions of libnet, it will fail silently and simply not send the closing "."... causing the remote mail server to time out eventually because of a data block timeout (which was happening to us in sporadic circumstances).
Sorry, I don't have a testcase handy. Creating one would be non-trivial, given that this depends on network buffer overloads.
The patch is relatively easy, and attached. A workaround would be to make sure never to pass a non-blocking IO handle to Net::Cmd->dataend.
Hope this helps,
--
Jan-Pieter Cornet <johnpc@xs4all.nl>
"Any sufficiently advanced incompetence is indistinguishable from malice."
- Grey's Law
Message body is not shown because sender requested not to inline it.
Message body not shown because it is not plain text.