gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnurl] 69/116: --interface: add support for Linux VRF


From: gnunet
Subject: [GNUnet-SVN] [gnurl] 69/116: --interface: add support for Linux VRF
Date: Tue, 05 Dec 2017 14:51:39 +0100

This is an automated email from the git hooks/post-receive script.

ng0 pushed a commit to branch master
in repository gnurl.

commit 32828cc4fb241aca01913424aa1781af0acd6aee
Author: Luca Boccassi <address@hidden>
AuthorDate: Thu Oct 26 19:42:55 2017 +0100

    --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
---
 docs/cmdline-opts/interface.d |  4 ++++
 lib/connect.c                 | 52 +++++++++++++++++++++++--------------------
 2 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/docs/cmdline-opts/interface.d b/docs/cmdline-opts/interface.d
index da84cd2b6..bd0817618 100644
--- a/docs/cmdline-opts/interface.d
+++ b/docs/cmdline-opts/interface.d
@@ -10,3 +10,7 @@ name, IP address or host name. An example could look like:
  curl --interface eth0:1 https://www.example.com/
 
 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
diff --git a/lib/connect.c b/lib/connect.c
index 28c6e9ed2..d47c1b996 100755
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -285,6 +285,34 @@ static CURLcode bindlocal(struct connectdata *conn,
 
     /* interface */
     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,
                         myhost, sizeof(myhost))) {
         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",
                 dev, myhost, af);
           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;
       }
     }

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]