aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2004-02-13 09:50:23 +0000
committerDaniel Stenberg <daniel@haxx.se>2004-02-13 09:50:23 +0000
commitfa57a8a78ef52328129b23029ca375a1e809d029 (patch)
tree79d29d0a394803e3dbbb3cd7818aeefcc311f4c9 /lib
parenteb4d65d0ba02131f111a4f272a4c28520ae0d1c8 (diff)
Ben Greear's SO_BINDTODEVICE patch that binds to a network interface "even
more" when the previous approach. Known to work on Linux, possibly on other platforms as well.
Diffstat (limited to 'lib')
-rw-r--r--lib/connect.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/lib/connect.c b/lib/connect.c
index 9c140c9f9..c9578c178 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -228,6 +228,7 @@ static CURLcode bindlocal(struct connectdata *conn,
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 @@ static CURLcode bindlocal(struct connectdata *conn,
*/
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 @@ static CURLcode bindlocal(struct connectdata *conn,
*/
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,37 @@ static CURLcode bindlocal(struct connectdata *conn,
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 %s failed\n",
+ data->set.device);
+ /* This is typiclally "errno 1, error: Operation not permitted" if
+ you're not running as root or another suitable privileged user */
+ }
+ }
+#endif
+
in=inet_addr(myhost);
if (CURL_INADDR_NONE != in) {