mirror of
https://github.com/moparisthebest/curl
synced 2024-08-13 17:03:50 -04:00
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.
This commit is contained in:
parent
eb4d65d0ba
commit
fa57a8a78e
@ -228,6 +228,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
char myhost[256] = "";
|
char myhost[256] = "";
|
||||||
in_addr_t in;
|
in_addr_t in;
|
||||||
int rc;
|
int rc;
|
||||||
|
bool was_iface = FALSE;
|
||||||
|
|
||||||
/* First check if the given name is an IP address */
|
/* First check if the given name is an IP address */
|
||||||
in=inet_addr(data->set.device);
|
in=inet_addr(data->set.device);
|
||||||
@ -239,7 +240,10 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
*/
|
*/
|
||||||
rc = Curl_resolv(conn, myhost, 0, &h);
|
rc = Curl_resolv(conn, myhost, 0, &h);
|
||||||
if(rc == 1)
|
if(rc == 1)
|
||||||
rc = Curl_wait_for_resolv(conn, &h);
|
(void)Curl_wait_for_resolv(conn, &h);
|
||||||
|
|
||||||
|
if(h)
|
||||||
|
was_iface = TRUE;
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -250,7 +254,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
*/
|
*/
|
||||||
rc = Curl_resolv(conn, data->set.device, 0, &h);
|
rc = Curl_resolv(conn, data->set.device, 0, &h);
|
||||||
if(rc == 1)
|
if(rc == 1)
|
||||||
rc = Curl_wait_for_resolv(conn, &h);
|
(void)Curl_wait_for_resolv(conn, &h);
|
||||||
|
|
||||||
if(h)
|
if(h)
|
||||||
/* we know data->set.device is shorter than the myhost array */
|
/* we know data->set.device is shorter than the myhost array */
|
||||||
@ -266,11 +270,37 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
hostent_buf,
|
hostent_buf,
|
||||||
sizeof(hostent_buf));
|
sizeof(hostent_buf));
|
||||||
*/
|
*/
|
||||||
|
failf(data, "Couldn't bind to '%s'", data->set.device);
|
||||||
return CURLE_HTTP_PORT_FAILED;
|
return CURLE_HTTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
infof(data, "We bind local end to %s\n", myhost);
|
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);
|
in=inet_addr(myhost);
|
||||||
if (CURL_INADDR_NONE != in) {
|
if (CURL_INADDR_NONE != in) {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user