RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
Bug 651592 - Curl does not handle FTP server timeout gracefully
Summary: Curl does not handle FTP server timeout gracefully
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 6
Classification: Red Hat
Component: curl
Version: 6.1
Hardware: All
OS: Linux
medium
medium
Target Milestone: rc
: ---
Assignee: Kamil Dudka
QA Contact: BaseOS QE Security Team
URL:
Whiteboard:
Depends On: 650255
Blocks: 720253
TreeView+ depends on / blocked
 
Reported: 2010-11-09 21:15 UTC by Kamil Dudka
Modified: 2018-09-04 09:11 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
libcurl FTP protocol implementation was unable to handle server session timeouts correctly. This is now fixed so that libcurl drops the connection when a 421 timeout response is received.
Clone Of: 650255
: 720253 (view as bug list)
Environment:
Last Closed: 2011-05-19 13:12:29 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
upstream patches applied on el6 code (11.99 KB, patch)
2011-01-05 17:47 UTC, Kamil Dudka
ovasik: review+
Details | Diff
a reproducer (1.13 KB, text/plain)
2011-04-13 14:26 UTC, Kamil Dudka
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2011:0573 0 normal SHIPPED_LIVE curl bug fix update 2011-05-18 17:57:02 UTC

Description Kamil Dudka 2010-11-09 21:15:10 UTC
+++ This bug was initially created as a clone of Bug #650255 +++

Description of problem:
If a Curl connection to an FTP server remains idle for a long time, the server may send a "421 Timeout". This should prompt Curl to drop the connection and re-connect for any subsequent transfers.

At the moment, Curl seems to ignore the 421 and gets confused when later trying to send request to the previous command channel.


Version-Release number of selected component (if applicable):


How reproducible:
Always

Steps to Reproduce:
1. If possible, adjust timeout for FTP server. E.g vsftpd has an idle_session_timeout. Make this small e.g. 60 seconds.

2. Start a Fedora 14 installation via an FTP server. Wait at the package selection page for longer than the timeout.

3.
  
Actual results:
Installer fails to download filelists.xml.gz due to timeout problem.

Expected results:
Curl re-connects after server error.


Additional info:

--- Additional comment from kdudka on 2010-11-09 14:20:26 CET ---

I was playing with that and it seems to work in most cases.  I set up a testing FTP server (proftpd) with idle timeout set to 10:

# grep Idle /etc/proftpd.conf
TimeoutIdle 10

Then I prepared a testing client to repeat the issue.  It performs two FTP downloads using a specified delay between them.  If the delay is 8 or 12, it works fine.  If the delay is 10, it does not.  Am I observing the same issue as you with Anaconda?

--- Additional comment from kdudka on 2010-11-09 14:22:41 CET ---

Created attachment 459098 [details]
a testing client

--- Additional comment from kdudka on 2010-11-09 14:30:22 CET ---

Created attachment 459099 [details]
output of the testing client

taken as;

$ curl -sJO 'https://bugzilla.redhat.com/attachment.cgi?id=459098'
$ sh bz650255.c 2>&1 | tee bz650255.log

--- Additional comment from kdudka on 2010-11-09 14:32:27 CET ---

Comment on attachment 459098 [details]
a testing client

Oops, one typo in there, but it still works:

s/exho/echo/

--- Additional comment from kdudka on 2010-11-09 14:42:58 CET ---

Comment on attachment 459099 [details]
output of the testing client

The following part of the log is interesting for us:

> * Re-using existing connection! (#0) with host localhost
> * Connected to localhost (127.0.0.1) port 21 (#0)
> * Request has same path as previous transfer
> > EPSV
> * Connect data stream passively
> < 421 Idle timeout (10 seconds): closing control connection
> * disabling EPSV usage
> > PASV
> * Recv failure: Connection reset by peer
> * Closing connection #0
> * Failure when receiving data from the peer
> + exit 56

--- Additional comment from number.cruncher on 2010-11-09 14:48:04 CET ---

Created attachment 459106 [details]
Client output connecting to VSFTPD server

Output when re-connecting before timeout.

--- Additional comment from kdudka on 2010-11-09 15:07:20 CET ---

Could you please try to adjust the timeout, such that it reflects your FTP server's timeout?

diff --git a/bz650255.c b/bz650255.c
index ca11705..89de371 100644
--- a/bz650255.c
+++ b/bz650255.c
@@ -1,12 +1,12 @@
 #if 0
 gcc -pedantic -Wall -Wextra -O0 -g bz650255.c -lcurl || exit $?
-./a.out 8  || exit $?
-./a.out 12 || exit $?
+./a.out 58 || exit $?
+./a.out 62 || exit $?
 echo
 echo === still OK ===
-exho
+echo
 set -x
-./a.out 10
+./a.out 60
 exit $?
 #endif

--- Additional comment from kdudka on 2010-11-09 17:11:06 CET ---

Created attachment 459170 [details]
proposed fix

--- Additional comment from kdudka on 2010-11-09 17:19:41 CET ---

The attached fix at least helps to return a more appropriate error code in case of the timeout on server's side.  I am not sure if libcurl itself should try to reconnect in that case...

Daniel, what do you think about the issue?

Is the behavior somehow specified in libcurl's API?

--- Additional comment from number.cruncher on 2010-11-09 17:38:04 CET ---

I am having a hard time reproducing this with your client code. Perhaps the anaconda code is taking a different code path? Can't fault the above fix, though!

--- Additional comment from kdudka on 2010-11-09 17:46:42 CET ---

Well, let's fix the issue with proftpd and my reproducer for now.  Then we can retest with Anaconda.

Based on your description, I suspect that Anaconda holds a libcurl handle across all the user interaction during the package selection.  To be honest, I don't know if we are supposed to handle such cases transparently within libcurl and silently reconnect on server's idle timeout ... but the response in case of my reproducer looks wrong to me.

--- Additional comment from daniel on 2010-11-09 18:01:00 CET ---

(In reply to comment #9)
> The attached fix at least helps to return a more appropriate error code in case
> of the timeout on server's side.  I am not sure if libcurl itself should try to
> reconnect in that case...
> 
> Daniel, what do you think about the issue?
> 
> Is the behavior somehow specified in libcurl's API?

I think that's a fair approach. 421 is documented in RFC959 to be exactly "we're closing down the control connection" and it can come at any time so it makes sense to put the logic in the common response reader function.

I don't think libcurl needs to/should reconnect by itself.

Please go ahead and commit this upstream as well!

--- Additional comment from kdudka on 2010-11-09 18:24:51 CET ---

Daniel, thanks for looking at the issue.  I've just pushed the patch upstream:

https://github.com/bagder/curl/commit/12b2412

Anaconda developers have IMO two choices:

1) avoid holding the libcurl handle during packages selection

2) pick up the error code and reconnect on their own responsibility eventually

--- Additional comment from kdudka on 2010-11-09 18:33:16 CET ---

fixed in curl-7.21.2-4.fc15

--- Additional comment from clumens on 2010-11-09 19:12:13 CET ---

Such a change would need to be made somewhere farther down in the pile, like either in yum or python-urlgrabber.  anaconda does not directly work with libcurl in the package downloading portion, aside from resetting the name server cache stuff.

Comment 3 Kamil Dudka 2011-01-05 17:47:18 UTC
Created attachment 471915 [details]
upstream patches applied on el6 code

Comment 4 Ondrej Vasik 2011-01-05 18:56:34 UTC
Comment on attachment 471915 [details]
upstream patches applied on el6 code

Looks sane. However, it modifies API of curl lib - is there some package in RHEL-6 which uses libcurl except curl? I just want to be sure to prevent incompatibilities.

Comment 5 Kamil Dudka 2011-01-05 19:08:54 UTC
The patch is not supposed to change anything in libcurl API/ABI.  It would be a bug if it did.  As far as I understand the code, it changes only internal API of libcurl modules and should not be anyhow visible from outside.  Luckily, we do not distribute lib/url.h and lib/urldata.h with our binary packages.

Comment 6 Ondrej Vasik 2011-01-05 20:31:41 UTC
Ah ok, then everything is ok...

Comment 9 Kamil Dudka 2011-04-13 14:26:06 UTC
Created attachment 491786 [details]
a reproducer

I am able to repeat the bug with proftpd with TimeoutIdle 4 in proftpd.conf.  You need to link the tester with -lcurl and give it the value of TimeoutIdle as the argument.  With the old version of libcurl, it returns CURLE_RECV_ERROR (56), which is wrong.  For some reason, I am no longer able to reproduce it with vsftpd.

Comment 10 Miroslav Vadkerti 2011-04-13 14:34:44 UTC
Thanks Kamil, I will try with proftpd then.

Comment 12 Misha H. Ali 2011-04-20 00:54:07 UTC
    Technical note added. If any revisions are required, please edit the "Technical Notes" field
    accordingly. All revisions will be proofread by the Engineering Content Services team.
    
    New Contents:
libcurl FTP protocol implementation was unable to handle server session timeouts correctly. This is now fixed so that libcurl drops the connection when a 421 timeout response is received.

Comment 13 errata-xmlrpc 2011-05-19 13:12:29 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHBA-2011-0573.html


Note You need to log in before you can comment on or make changes to this bug.