diff -ur curl-7.17.0/include/curl/curl.h curl-7.17.0.local/include/curl/curl.h
--- curl-7.17.0/include/curl/curl.h	Sun Sep  2 14:53:15 2007
+++ curl-7.17.0.local/include/curl/curl.h	Fri Sep 14 13:26:33 2007
@@ -242,9 +242,16 @@
   CURLSOCKTYPE_LAST   /* never use */
 } curlsocktype;
 
+struct sockaddr;
+
 typedef int (*curl_sockopt_callback)(void *clientp,
                                      curl_socket_t curlfd,
-                                     curlsocktype purpose);
+                                     curlsocktype purpose,
+                                     int* ai_family,
+                                     int* ai_socktype,
+                                     int* ai_protocol,
+                                     struct sockaddr *ai_addr,
+                                     socklen_t* ai_addrlen);
 
 #ifndef CURL_NO_OLDIES
   /* not used since 7.10.8, will be removed in a future release */
diff -ur curl-7.17.0/lib/connect.c curl-7.17.0.local/lib/connect.c
--- curl-7.17.0/lib/connect.c	Thu Sep  6 00:41:45 2007
+++ curl-7.17.0.local/lib/connect.c	Fri Sep 14 13:26:33 2007
@@ -677,31 +677,66 @@
   struct SessionHandle *data = conn->data;
   curl_socket_t sockfd;
   CURLcode res;
+  struct Curl_sockaddr_storage newaddr_storage;
+  struct sockaddr *ai_addr = (struct sockaddr *)&newaddr_storage;
+  socklen_t ai_addrlen = ai->ai_addrlen;
+  int ai_family=ai->ai_family;
+  int ai_socktype=conn->socktype;
+  int ai_protocol=ai->ai_protocol;
+  int need_reopen;
+
+  int saved_ai_family;
+  int saved_ai_socktype;
+  int saved_ai_protocol;
 
-  sockfd = socket(ai->ai_family, conn->socktype, ai->ai_protocol);
-  if (sockfd == CURL_SOCKET_BAD)
-    return CURL_SOCKET_BAD;
+  memcpy(ai_addr, ai->ai_addr, (ai->ai_addrlen<sizeof(newaddr_storage))?ai->ai_addrlen:sizeof(newaddr_storage));
 
   *connected = FALSE; /* default is not connected */
+  do {
+    sockfd = socket(ai_family, ai_socktype, ai_protocol);
+    if (sockfd == CURL_SOCKET_BAD)
+      return CURL_SOCKET_BAD;
 
-  Curl_printable_address(ai, addr_buf, sizeof(addr_buf));
-  infof(data, "  Trying %s... ", addr_buf);
-
-  if(data->set.tcp_nodelay)
-    tcpnodelay(conn, sockfd);
+    if(data->set.tcp_nodelay)
+      tcpnodelay(conn, sockfd);
 
-  nosigpipe(conn, sockfd);
+    nosigpipe(conn, sockfd);
 
-  if(data->set.fsockopt) {
-    /* activate callback for setting socket options */
-    error = data->set.fsockopt(data->set.sockopt_client,
-                               sockfd,
-                               CURLSOCKTYPE_IPCXN);
-    if (error) {
-      sclose(sockfd); /* close the socket and bail out */
-      return CURL_SOCKET_BAD;
+    need_reopen=0;
+    if(data->set.fsockopt) {
+      /* activate callback for setting socket options, check or change the address */
+      saved_ai_family=ai_family;
+      saved_ai_socktype=ai_socktype;
+      saved_ai_protocol=ai_protocol;
+      error = data->set.fsockopt(data->set.sockopt_client,
+				 sockfd,
+				 CURLSOCKTYPE_IPCXN,
+				 &ai_family,
+				 &ai_socktype,
+				 &ai_protocol,
+				 ai_addr,
+				 &ai_addrlen);
+      if (error) {
+	sclose(sockfd); /* close the socket and bail out */
+	return CURL_SOCKET_BAD;
+      }
+      if(saved_ai_family!=ai_family || saved_ai_socktype!=ai_socktype || saved_ai_protocol!=ai_protocol) {
+	/* something just changed, close socket, rinse, repeat */
+	need_reopen=1;
+	sclose(sockfd);
+      }
     }
-  }
+  } while(need_reopen);
+  
+  /* FIXME: do we have Curl_printable_address-like with struct sockaddr* as argument? */
+  const void *iptoprint = &((const struct sockaddr_in*)ai_addr)->sin_addr;
+#ifdef ENABLE_IPV6
+  if(ai_family==AF_INET6)
+    iptoprint= &((const struct sockaddr_in6*)ai_addr)->sin6_addr;
+#endif
+  Curl_inet_ntop(ai_family, iptoprint, addr_buf, sizeof(addr_buf));
+  infof(data, "  Trying %s... ", addr_buf);
+
 
   /* possibly bind the local end to an IP, interface or port */
   res = bindlocal(conn, sockfd);
@@ -714,8 +749,8 @@
   Curl_nonblock(sockfd, TRUE);
 
   /* Connect TCP sockets, bind UDP */
-  if(conn->socktype == SOCK_STREAM)
-    rc = connect(sockfd, ai->ai_addr, ai->ai_addrlen);
+  if(ai_socktype == SOCK_STREAM)
+    rc = connect(sockfd, ai_addr, ai_addrlen);
   else
     rc = 0;
 
