Tor Arntsen figured out that TFTP was broken on a lot of systems since we
authorDaniel Stenberg <daniel@haxx.se>
Sun, 26 Mar 2006 08:52:43 +0000 (08:52 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Sun, 26 Mar 2006 08:52:43 +0000 (08:52 +0000)
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.

CHANGES
RELEASE-NOTES
lib/tftp.c

diff --git a/CHANGES b/CHANGES
index da333ea..6602298 100644 (file)
--- 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.
 
index 91ee4e2..aad6079 100644 (file)
@@ -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
index 9af1cf9..711bf17 100644 (file)
@@ -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()));