mirror of
https://github.com/moparisthebest/curl
synced 2025-03-11 07:39:50 -04:00
--interface: add support for Linux VRF
The --interface command (CURLOPT_INTERFACE option) already uses SO_BINDTODEVICE on Linux, but it tries to parse it as an interface or IP address first, which fails in case the user passes a VRF. Try to use the socket option immediately and parse it as a fallback instead. Update the documentation to mention this feature, and that it requires the binary to be ran by root or with CAP_NET_RAW capabilities for this to work. Closes #2024
This commit is contained in:
parent
b78dce2526
commit
32828cc4fb
@ -10,3 +10,7 @@ name, IP address or host name. An example could look like:
|
|||||||
curl --interface eth0:1 https://www.example.com/
|
curl --interface eth0:1 https://www.example.com/
|
||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
|
|
||||||
|
On Linux it can be used to specify a VRF, but the binary needs to either
|
||||||
|
have CAP_NET_RAW or to be ran as root. More information about Linux VRF:
|
||||||
|
https://www.kernel.org/doc/Documentation/networking/vrf.txt
|
||||||
|
@ -285,6 +285,34 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
|
|
||||||
/* interface */
|
/* interface */
|
||||||
if(!is_host) {
|
if(!is_host) {
|
||||||
|
#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.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Only bind to the interface when specified as interface, not just
|
||||||
|
* as a hostname or ip address.
|
||||||
|
*
|
||||||
|
* interface might be a VRF, eg: vrf-blue, which means it cannot be
|
||||||
|
* converted to an IP address and would fail Curl_if2ip. Simply try
|
||||||
|
* to use it straight away.
|
||||||
|
*/
|
||||||
|
if(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
|
||||||
|
dev, (curl_socklen_t)strlen(dev) + 1) == 0) {
|
||||||
|
/* This is typically "errno 1, error: Operation not permitted" if
|
||||||
|
* you're not running as root or another suitable privileged
|
||||||
|
* user.
|
||||||
|
* If it succeeds it means the parameter was a valid interface and
|
||||||
|
* not an IP address. Return immediately.
|
||||||
|
*/
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
switch(Curl_if2ip(af, scope, conn->scope_id, dev,
|
switch(Curl_if2ip(af, scope, conn->scope_id, dev,
|
||||||
myhost, sizeof(myhost))) {
|
myhost, sizeof(myhost))) {
|
||||||
case IF2IP_NOT_FOUND:
|
case IF2IP_NOT_FOUND:
|
||||||
@ -305,30 +333,6 @@ static CURLcode bindlocal(struct connectdata *conn,
|
|||||||
infof(data, "Local Interface %s is ip %s using address family %i\n",
|
infof(data, "Local Interface %s is ip %s using address family %i\n",
|
||||||
dev, myhost, af);
|
dev, myhost, af);
|
||||||
done = 1;
|
done = 1;
|
||||||
|
|
||||||
#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.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Only bind to the interface when specified as interface, not just
|
|
||||||
* as a hostname or ip address.
|
|
||||||
*/
|
|
||||||
if(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
|
|
||||||
dev, (curl_socklen_t)strlen(dev) + 1) != 0) {
|
|
||||||
error = SOCKERRNO;
|
|
||||||
infof(data, "SO_BINDTODEVICE %s failed with errno %d: %s;"
|
|
||||||
" will do regular bind\n",
|
|
||||||
dev, error, Curl_strerror(conn, error));
|
|
||||||
/* This is typically "errno 1, error: Operation not permitted" if
|
|
||||||
you're not running as root or another suitable privileged
|
|
||||||
user */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user