cURL / Mailing Lists / curl-library / Single Mail

curl-library

binding to --interface

From: Gisle Vanem <gvanem_at_broadpark.no>
Date: Tue, 23 Mar 2004 15:19:33 +0100

The use of the Curl_if2ip() function looks fishy. On Windows it simply
returns NULL so "curl --interface eth0 .." fails with "Couldn't bind to 'eth0'".
Fair enough.

But on Linux it just prints a warning if setsockopt(..SO_BINDTODEVICE)
fails. This seems inconsistent. IMHO, the bindlocal() function should just fail.

On the other hand "curl --interface <my-ip>..." works fine, but
"curl --interface <dummy-ip> ..." fails with:
  * We bind local end to ...
  * errno 0
  * Closing connection #0
  curl: (45) errno 0

My Win-XP box is not multihomed, so I can't test this to the full.
But below is a patch to give meaningful errno handling for all.

BTW. Is the use of strerror (fortunately only in ftp.c) thread-safe on
most platforms? Can't we just print the value from Curl_ourerrno() as
we do most other places?

----------------------------------------
--- CVS-latest/lib/connect.c Wed Mar 17 13:46:45 2004
+++ lib/connect.c Tue Mar 23 14:53:04 2004
@@ -295,10 +295,10 @@
       if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
                      data->set.device, strlen(data->set.device)+1) != 0) {
         /* printf("Failed to BINDTODEVICE, socket: %d device: %s error: %s\n",
- sockfd, data->set.device, strerror(errno)); */
+ sockfd, data->set.device, strerror(Curl_ourerrno())); */
         infof(data, "SO_BINDTODEVICE %s failed\n",
               data->set.device);
- /* This is typiclally "errno 1, error: Operation not permitted" if
+ /* This is typically "errno 1, error: Operation not permitted" if
            you're not running as root or another suitable privileged user */
       }
     }
@@ -353,34 +353,36 @@
         }
 #endif
         if(!bindworked) {
- switch(errno) {
+ int err = Curl_ourerrno();
+
+ switch(err) {
           case EBADF:
- failf(data, "Invalid descriptor: %d", errno);
+ failf(data, "Invalid descriptor: %d", err);
             break;
           case EINVAL:
- failf(data, "Invalid request: %d", errno);
+ failf(data, "Invalid request: %d", err);
             break;
           case EACCES:
- failf(data, "Address is protected, user not superuser: %d", errno);
+ failf(data, "Address is protected, user not superuser: %d", err);
             break;
           case ENOTSOCK:
             failf(data,
                   "Argument is a descriptor for a file, not a socket: %d",
- errno);
+ err);
             break;
           case EFAULT:
- failf(data, "Inaccessable memory error: %d", errno);
+ failf(data, "Inaccessable memory error: %d", err);
             break;
           case ENAMETOOLONG:
- failf(data, "Address too long: %d", errno);
+ failf(data, "Address too long: %d", err);
             break;
           case ENOMEM:
- failf(data, "Insufficient kernel memory was available: %d", errno);
+ failf(data, "Insufficient kernel memory was available: %d", err);
             break;
           default:
- failf(data, "errno %d", errno);
+ failf(data, "errno %d", err);
             break;
- } /* end of switch(errno) */
+ } /* end of switch(err) */
  
           return CURLE_HTTP_PORT_FAILED;
         } /* end of else */

----------------------------------------

--gv
Received on 2004-03-23