diff --git a/CHANGES b/CHANGES index da333ea35..660229884 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,11 @@ Changelog +Daniel (26 March 2006) +- Tor Arntsen figured out that TFTP was broken on a lot of systems since we + called bind() with a too big argument in the 3rd parameter and at least + Tru64, AIX and IRIX seem to be very picky about it. + Daniel (21 March 2006) - David McCreedy added CURLINFO_FTP_ENTRY_PATH. diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 91ee4e229..aad60791d 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -16,6 +16,7 @@ This release includes the following changes: This release includes the following bugfixes: + o TFTP works on more systems o generates a fine AIX Toolbox RPM spec o treat FTP AUTH failures properly o TFTP transfers could trash data diff --git a/lib/tftp.c b/lib/tftp.c index 9af1cf9b5..711bf1720 100644 --- a/lib/tftp.c +++ b/lib/tftp.c @@ -559,14 +559,28 @@ CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done) #ifdef WIN32 /* AF_UNSPEC == 0 (from above calloc) doesn't work on Winsock */ - ((struct sockaddr_in*)&state->local_addr)->sin_family = conn->ip_addr->ai_family; + + /* NOTE: this blatantly assumes IPv4. This should be fixed! */ + ((struct sockaddr_in*)&state->local_addr)->sin_family = + conn->ip_addr->ai_family; #endif tftp_set_timeouts(state); - /* Bind to any interface, random UDP port */ + /* Bind to any interface, random UDP port. + * + * 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, + * but we learned that at least Tru64, AIX and IRIX *requires* the size of + * that argument to match the exact size of a 'sockaddr_in' struct when + * running IPv4-only. + * + * Therefore we use the size from the address we connected to, which we + * assume uses the same IP version and thus hopefully this works for both + * IPv4 and IPv6... + */ rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr, - sizeof(state->local_addr)); + conn->ip_addr->ai_addrlen); if(rc) { failf(conn->data, "bind() failed; %s\n", Curl_strerror(conn,Curl_ourerrno()));