From 67d94514b0d1501832a52fd42db8f5a41151d7f5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 4 Oct 2007 10:01:41 +0000 Subject: [PATCH] Kim Rinnewitz reported that --local-port didn't work with TFTP transfers. This happened because the tftp code always uncondionally did a bind() without caring if one already had been done and then it failed. I wrote a test case (1009) to verify this, but it is a bit error-prone since it will have to pick a fixed local port number and since the tests are run on so many different hosts in different situations I add it in disabled state. --- CHANGES | 12 +++++++++++- RELEASE-NOTES | 3 ++- lib/connect.c | 1 + lib/tftp.c | 7 ++++--- lib/urldata.h | 2 ++ tests/data/DISABLED | 3 +-- tests/data/Makefile.am | 2 +- tests/data/test1009 | 43 ++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 tests/data/test1009 diff --git a/CHANGES b/CHANGES index ebda3001b..9fedb041f 100644 --- a/CHANGES +++ b/CHANGES @@ -6,8 +6,18 @@ Changelog +Daniel S (4 October 2007) +- Kim Rinnewitz reported that --local-port didn't work with TFTP transfers. + This happened because the tftp code always uncondionally did a bind() + without caring if one already had been done and then it failed. I wrote a + test case (1009) to verify this, but it is a bit error-prone since it will + have to pick a fixed local port number and since the tests are run on so + many different hosts in different situations I'll add it in disabled state. + +Yang Tse (3 October 2007) +- Fixed issue related with the use of ares_timeout() result. + Daniel S (3 October 2007) -- Yang Tse, fix issue related with the use of ares_timeout() result. - Alexey Pesternikov introduced CURLOPT_OPENSOCKETFUNCTION and CURLOPT_OPENSOCKETDATA to set a callback that allows an application to diff --git a/RELEASE-NOTES b/RELEASE-NOTES index be84ebd33..29748f115 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -34,6 +34,7 @@ This release includes the following bugfixes: o curl_easy_escape() problem with byte values >= 128 o handles chunked-encoded CONNECT responses o misuse of ares_timeout() result + o --local-port on TFTP transfers This release includes the following known bugs: @@ -52,6 +53,6 @@ advice from friends like these: Dan Fandrich, Michal Marek, Günter Knauf, Rob Crittenden, Immanuel Gregoire, Mark Davies, Max Katsev, Philip Langdale, Alex Fishman, Johnny Luong, - Alexey Pesternikov, Yang Tse + Alexey Pesternikov, Yang Tse, Kim Rinnewitz Thanks! (and sorry if I forgot to mention someone) diff --git a/lib/connect.c b/lib/connect.c index d386a1bc5..918602c2d 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -380,6 +380,7 @@ static CURLcode bindlocal(struct connectdata *conn, port = ntohs(((struct sockaddr_in6 *)&add)->sin6_port); #endif infof(data, "Local port: %d\n", port); + conn->bits.bound = TRUE; return CURLE_OK; } if(--portnum > 0) { diff --git a/lib/tftp.c b/lib/tftp.c index a3a69cf6c..938c2e239 100644 --- a/lib/tftp.c +++ b/lib/tftp.c @@ -598,9 +598,9 @@ CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done) tftp_set_timeouts(state); - if(!conn->bits.reuse) { - /* If not reused, bind to any interface, random UDP port. If it is reused, - * this has already been done! + if(!conn->bits.bound) { + /* If not already bound, bind to any interface, random UDP port. If it is + * reused or a custom local port was desired, this has already been done! * * We once used the size of the local_addr struct as the third argument for * bind() to better work with IPv6 or whatever size the struct could have, @@ -619,6 +619,7 @@ CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done) Curl_strerror(conn, SOCKERRNO)); return CURLE_COULDNT_CONNECT; } + conn->bits.bound = TRUE; } Curl_pgrsStartNow(conn->data); diff --git a/lib/urldata.h b/lib/urldata.h index 51844c4ba..52647a1cb 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -609,6 +609,8 @@ struct ConnectBits { bool proxy_connect_closed; /* set true if a proxy disconnected the connection in a CONNECT request with auth, so that libcurl should reconnect and continue. */ + bool bound; /* set true if bind() has already been done on this socket/ + connection */ }; struct hostname { diff --git a/tests/data/DISABLED b/tests/data/DISABLED index ce6dc9556..4bbaaffaa 100644 --- a/tests/data/DISABLED +++ b/tests/data/DISABLED @@ -3,5 +3,4 @@ # test cases are run by runtests.pl. Just add the plain test case numbers, one # per line. # Lines starting with '#' letters are treated as comments. -#230 - +1009 diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 6ecdb2bd9..a63206785 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -45,7 +45,7 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \ test706 test707 test350 test351 test352 test353 test289 test540 test354 \ test231 test1000 test1001 test1002 test1003 test1004 test1005 test1006 \ test615 test1007 test541 test1010 test1011 test1012 test542 test543 \ - test536 test1008 + test536 test1008 test1009 filecheck: @mkdir test-place; \ diff --git a/tests/data/test1009 b/tests/data/test1009 new file mode 100644 index 000000000..86470ff74 --- /dev/null +++ b/tests/data/test1009 @@ -0,0 +1,43 @@ + + + +TFTP +TFTP RRQ + + + +# +# Server-side + + +a chunk of +data +returned + to client + + + +# +# Client-side + + +tftp + + +TFTP retrieve + + +tftp://%HOSTIP:%TFTPPORT//1009 --local-port 44444 + + + +# +# Verify pseudo protocol after the test has been "shot" + + +opcode: 1 +filename: /1009 +mode: octet + + +