Skip to content

Instantly share code, notes, and snippets.

@tshinnic
Created October 16, 2011 21:43
Show Gist options
  • Save tshinnic/1291458 to your computer and use it in GitHub Desktop.
Save tshinnic/1291458 to your computer and use it in GitHub Desktop.
Additional comments to curl bug report ID: 3421912
I stumbled on this oddity in wanting to use curl as a test tool, as yet another ftp client to test an FTP server. I needed to force use of PORT/EPSV when curl _really_ seemed to want to use ipv6 commands. In all my test cases, only ipv4 connections were used, as the FTP server software disallowed ipv6 connections.
I have struggled figuring out how to illustrate the 'problem', as I am having a hard time describing the weirdness here. It is as though, if curl thinks there is any possibility of ipv6 connections, it 'resists' ipv4-style commands. This could be a problem, the lack of flexibility, in a mixed environment, when curl 'guesses' wrong. Not all software/hardware is ready for ipv6 and curl requiring ipv6 commands could cause problems.
I'll first give the minimum information, my local /etc/hosts and then a table of options vs. actions. And I'll copy much of this to a 'gist' so that the formatting won't be messed up)
On a defaulted Fedora 15 Linux the /etc/hosts file has both ipv4 and ipv6 definitions for 'localhost'. I added a definition for the host name as an ipv4 address. Thus we have one name that has both ipv4 and ipv6, and one name that has only an ipv4 definition:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.57.145 TLSF15A.TLSWG TLSF15A
If I run a series of tests using the ipv4-only name, everything works as expected:
tlsf15a EPSV
tlsf15a --disable-epsv PASV
tlsf15a --ftp-port - EPRT |1|192.168.57.145|38450|
tlsf15a --ftp-port - --disable-eprt PORT 192,168,57,145,181,77
tlsf15a -4 --ftp-port - EPRT |1|192.168.57.145|56256|
tlsf15a -4 --ftp-port - --disable-eprt PORT 192,168,57,145,129,157
When I run the same tests on the name which could be *either* ipv4 or ipv6, we get strange results for some combinations:
localhost EPSV
?? localhost --disable-epsv EPSV
localhost -4 EPSV
ok localhost -4 --disable-epsv PASV
localhost --ftp-port - EPRT |1|127.0.0.1|58913|
?? localhost --ftp-port - --disable-eprt EPRT |1|127.0.0.1|56154|
localhost -4 --ftp-port - EPRT |1|127.0.0.1|59841|
ok localhost -4 --ftp-port - --disable-eprt PORT 127,0,0,1,156,94
The lines marked with '??' are unexpected results.
While I could throw the many test listings in here, let me instead show those for the last two cases marked above:
Here we give all the options correctly to forbid, but EPRT is done anyway; note the display saying that an ipv6 connection was attempted and rejected, followed by a successful ipv4 connection; we *are* using ipv4 but somehow we don't use ipv4 commands;
curl --verbose --ftp-port - --disable-eprt ftp://localhost/
* About to connect() to localhost port 21 (#0)
* Trying ::1... Connection refused
* Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 21 (#0)
< 220 (vsFTPd 2.3.4)
> EPRT |1|127.0.0.1|56154|
< 200 EPRT command successful. Consider using EPSV.
* Connect data stream actively
Here we first disallow attempting ipv6 connections, and then the options work again;
curl --verbose --ftp-port - --disable-eprt -4 ftp://localhost/
* About to connect() to localhost port 21 (#0)
* Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 21 (#0)
< 220 (vsFTPd 2.3.4)
> PORT 127,0,0,1,156,94
< 200 PORT command successful. Consider using PASV.
* Connect data stream actively
It is the situation where curl first attempts an ipv6 connection that seems to confuse curl. It doesn't seem to have noticed that it later actually connected using ipv4. I have to think there is a simple boolean flag stuck somewhere.
Note that tests were done using both 7.21.3 and 7.22.0
curl 7.21.3 (i386-redhat-linux-gnu) libcurl/7.21.3 NSS/3.12.10.0 zlib/1.2.5 libidn/1.19 libssh2/1.2.7
curl 7.22.0 (i686-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.0 zlib/1.2.5
Summary:
- if an ipv6 connection is *possible*, --disable-eprt has no effect
- workaround to disallow EPRT/EPSV is to also use -4 option
- a more unlikely workaround is to use an ipv4-only DNS name
- no documentation of ipv6 vs ipv4 vs options
Because this problem has a user-level workaround, it is therefore not
something that *must* be fixed in code. However, because of the code's
unintuitive actions, something should be noted in the *documentation*
regarding priority of ipv6 connections vs. ipv4-related options.
(I also noticed these typos in the man page for 7.22.0:
/home/Tom/temp/curl-7.22.0/docs
.TH curl 1 "14 April 2009" "Curl 7.21.6" "Curl Manual"
^^^^
vvvv
--epsv can be used to explicitly enable EPRT again and --no-epsv
is an alias for --disable-epsv.
)
After the patch was applied, I retested these cases
[Tom@TLSF15A temp]$ grep "curl\|EPSV\|EPRT\|PASV\|PORT" arf
tlsf15a EPSV
tlsf15a --disable-epsv PASV
tlsf15a --ftp-port - EPRT |1|192.168.57.145|52216|
tlsf15a --ftp-port - --disable-eprt PORT 192,168,57,145,164,18
tlsf15a -4 --ftp-port - EPRT |1|192.168.57.145|36894|
tlsf15a -4 --ftp-port - --disable-eprt PORT 192,168,57,145,231,236
localhost EPSV
!! localhost --disable-epsv PASV
localhost -4 EPSV
localhost -4 --disable-epsv PASV
localhost --ftp-port - EPRT |1|127.0.0.1|51181|
!! localhost --ftp-port - --disable-eprt PORT 127,0,0,1,129,24
localhost -4 --ftp-port - EPRT |1|127.0.0.1|59976|
localhost -4 --ftp-port - --disable-eprt PORT 127,0,0,1,163,94
The two previously marked weirdnesses were corrected. *Thank you.*
But now that I look and think about it, what might be going on here?
tlsf15a --ftp-port - EPRT |1|192.168.57.145|38450|
??? tlsf15a -4 --ftp-port - EPRT |1|192.168.57.145|36894|
Again, this is the ipv4-only DNS name, and while curl _is_ using ipv4 addresses, I'm not following why it is using the EPRT/EPSV commands. Obviously will only be a problem if someone's environment doesn't handled the combination well, but is worrisome?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment