cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: [Fwd: Patch for SO_BINDTODEVICE]

From: Ben Greear <greearb_at_candelatech.com>
Date: Thu, 12 Feb 2004 07:01:42 -0800

Daniel Stenberg wrote:
> On Wed, 11 Feb 2004, Ben Greear wrote:
>
>
>>I have a patch here that should allow CURL to bind more tightly to an
>>interface. It's use may be somewhat limited in scope, but it does fix a
>>problem for me :)
>
>
> Cool. I just have a few questions on this!
>
>
>>+ 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)); */
>>+ failf(data, "SO_BINDTODEVICE failed");
>
>
> When this operation fails, what is the significance?

It should be OK unless someone is doing some very specific
things and running very strange routing conditions, so as I
am.

>
> I experimented to bind to 'lo' and it failed to SO_BINDTODEVICE, but it could
> still continue and bind the good old fashioned way... In fact, it fails for
> eth0 as well on my linux 2.4.23 dev machine. Shouldn't it be possible to bind
> to the only network interface? Sorry for being so clueless about this.

Can you show me the error (errno?)

>
> I take it failf() should rather be infof() in this case?

I had a hard time testing this so far, and mainly just wanted it
take the code branch in gdb. That is most likely due to my program
that uses libcurl. How did you test this?

It should probably be infof.

>
> BTW, attached to this mail is my modified patch that applies fine on the CVS
> code.

good trick with the #ifdef SO_BINDTODEVICE, I hadn't thought of that :)

Ben

>
>
>
> ------------------------------------------------------------------------
>
> Index: lib/connect.c
> ===================================================================
> RCS file: /repository/curl/lib/connect.c,v
> retrieving revision 1.75
> diff -u -r1.75 connect.c
> --- lib/connect.c 9 Feb 2004 11:40:00 -0000 1.75
> +++ lib/connect.c 12 Feb 2004 13:37:51 -0000
> @@ -228,6 +228,7 @@
> char myhost[256] = "";
> in_addr_t in;
> int rc;
> + bool was_iface = FALSE;
>
> /* First check if the given name is an IP address */
> in=inet_addr(data->set.device);
> @@ -239,7 +240,10 @@
> */
> rc = Curl_resolv(conn, myhost, 0, &h);
> if(rc == 1)
> - rc = Curl_wait_for_resolv(conn, &h);
> + (void)Curl_wait_for_resolv(conn, &h);
> +
> + if(h)
> + was_iface = TRUE;
>
> }
> else {
> @@ -250,7 +254,7 @@
> */
> rc = Curl_resolv(conn, data->set.device, 0, &h);
> if(rc == 1)
> - rc = Curl_wait_for_resolv(conn, &h);
> + (void)Curl_wait_for_resolv(conn, &h);
>
> if(h)
> /* we know data->set.device is shorter than the myhost array */
> @@ -266,11 +270,34 @@
> hostent_buf,
> sizeof(hostent_buf));
> */
> + failf(data, "Couldn't bind to '%s'", data->set.device);
> return CURLE_HTTP_PORT_FAILED;
> }
>
> infof(data, "We bind local end to %s\n", myhost);
>
> +#ifdef SO_BINDTODEVICE
> + /* I am not sure any other OSs than Linux that provide this feature, and
> + * at the least I cannot test. --Ben
> + *
> + * This feature allows one to tightly bind the local socket to a
> + * particular interface. This will force even requests to other local
> + * interfaces to go out the external interface.
> + *
> + */
> + if (was_iface) {
> + /* Only bind to the interface when specified as interface, not just as a
> + * hostname or ip address.
> + */
> + 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)); */
> + infof(data, "SO_BINDTODEVICE failed\n");
> + }
> + }
> +#endif
> +
> in=inet_addr(myhost);
> if (CURL_INADDR_NONE != in) {
>

-- 
Ben Greear <greearb_at_candelatech.com>
Candela Technologies Inc  http://www.candelatech.com
Received on 2004-02-12