[vlc-devel] [PATCH 1/2] smb2: favor IPv4 over IPv6

Thomas Guillem thomas at gllm.fr
Fri Nov 6 20:35:47 CET 2020


Let the module resolve the address and favor IPv4 over IPv6.

It seems that lot of servers or NAS have IPv6 support but have firewall
dropping the 445 port connection via IPv6 resulting on a long timeout
when trying to connect.
---
 modules/access/smb2.c | 37 ++++++++++++++++++++++++++++++++++---
 1 file changed, 34 insertions(+), 3 deletions(-)

diff --git a/modules/access/smb2.c b/modules/access/smb2.c
index 0b7f75906a0..53f960efeac 100644
--- a/modules/access/smb2.c
+++ b/modules/access/smb2.c
@@ -609,7 +609,6 @@ vlc_smb2_resolve(stream_t *access, const char *host, unsigned port)
     if (!host)
         return NULL;
 
-#ifdef HAVE_DSM
     /* Test if the host is an IP */
     struct in_addr addr;
     if (inet_pton(AF_INET, host, &addr) == 1)
@@ -619,11 +618,43 @@ vlc_smb2_resolve(stream_t *access, const char *host, unsigned port)
     struct addrinfo *info = NULL;
     if (vlc_getaddrinfo_i11e(host, port, NULL, &info) == 0)
     {
+        struct addrinfo *ai_selected = NULL;
+        for (struct addrinfo *ai = info; ai != NULL; ai = ai->ai_next)
+        {
+            /* For SMB, use IPV4 in priority as lot of servers have firewall
+             * droping 445 in IPv6. */
+            if (ai_selected == NULL || ai->ai_family == AF_INET)
+                ai_selected = ai;
+        }
+        assert(ai_selected != NULL);
+
+        char *out_host = NULL;
+        size_t out_host_size;
+        void *sin_addr;
+        if (ai_selected->ai_family == AF_INET)
+        {
+            out_host_size = INET_ADDRSTRLEN;
+            out_host = malloc(out_host_size);
+            sin_addr = &((struct sockaddr_in *)ai_selected->ai_addr)->sin_addr;
+        }
+        else if (ai_selected->ai_family == AF_INET6)
+        {
+            out_host_size = INET6_ADDRSTRLEN;
+            out_host = malloc(out_host_size);
+            sin_addr = &((struct sockaddr_in6 *)ai_selected->ai_addr)->sin6_addr;
+        }
+        if (out_host != NULL
+         && inet_ntop(ai_selected->ai_family, sin_addr, out_host, out_host_size) == NULL)
+        {
+            free(out_host);
+            out_host = NULL;
+        }
+
         freeaddrinfo(info);
-        /* Let smb2 resolve it */
-        return NULL;
+        return out_host;
     }
 
+#ifdef HAVE_DSM
     /* Test if the host is a netbios name */
     char *out_host = NULL;
     netbios_ns *ns = netbios_ns_new();
-- 
2.28.0



More information about the vlc-devel mailing list