From 2d52141e145f2cde00612aabf4d6835b998c2f60 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felix=20Paul=20K=C3=BChne?= <felix@feepk.net>
Date: Wed, 6 Apr 2022 16:16:31 +0200
Subject: [PATCH] bonjour SD: resolve hostname to IP for SMB

The SMB modules cannot do the Bonjour lookup, so resolve the hostname
and forward the first IP, which typically is the preferred value.

This fixes vlc-ios#1319
---
 modules/services_discovery/bonjour.m | 45 +++++++++++++++++++++++++++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/modules/services_discovery/bonjour.m b/modules/services_discovery/bonjour.m
index f7db4d2f01c0..60ee1b5f8b2c 100644
--- a/modules/services_discovery/bonjour.m
+++ b/modules/services_discovery/bonjour.m
@@ -32,6 +32,7 @@
 #include <vlc_renderer_discovery.h>
 
 #import <Foundation/Foundation.h>
+#import <arpa/inet.h>
 
 #pragma mark Function declarations
 
@@ -120,6 +121,43 @@ NSString *const VLCBonjourRendererDemux         = @"VLCBonjourRendererDemux";
 
 @end
 
+static NSString * ipAddressAsStringForData(NSData * data)
+{
+    char addressBuffer[INET6_ADDRSTRLEN] = { 0 };
+    NSString *returnValue = nil;
+
+    if (data == nil) {
+        return returnValue;
+    }
+
+    typedef union {
+        struct sockaddr sa;
+        struct sockaddr_in ipv4;
+        struct sockaddr_in6 ipv6;
+    } ip_socket_address;
+
+    ip_socket_address *socketAddress = (ip_socket_address *)[data bytes];
+
+    if (socketAddress) {
+        const char *addressStr;
+        if (socketAddress->sa.sa_family == AF_INET) {
+            addressStr = inet_ntop(socketAddress->sa.sa_family,
+                                           (void *)&(socketAddress->ipv4.sin_addr),
+                                           addressBuffer,
+                                           sizeof(addressBuffer));
+        } else if (socketAddress->sa.sa_family == AF_INET6) {
+            addressStr = inet_ntop(socketAddress->sa.sa_family,
+                                           (void *)&(socketAddress->ipv6.sin6_addr),
+                                           addressBuffer,
+                                           sizeof(addressBuffer));
+        }
+        if (addressStr != NULL) {
+            returnValue = [NSString stringWithUTF8String:addressStr];
+        }
+    }
+    return returnValue;
+}
+
 @implementation VLCNetServiceDiscoveryController
 
 - (instancetype)initWithRendererDiscoveryObject:(vlc_renderer_discovery_t *)p_rd
@@ -374,8 +412,13 @@ NSString *const VLCBonjourRendererDemux         = @"VLCBonjourRendererDemux";
 - (void)addResolvedInputItem:(NSNetService *)netService withProtocol:(NSString *)protocol
 {
     services_discovery_t *p_sd = (services_discovery_t *)_p_this;
+    NSString *host = netService.hostName;
+
+    if ([protocol isEqualToString:@"smb"]) {
+        host = ipAddressAsStringForData(netService.addresses.firstObject);
+    }
+    NSString *uri = [NSString stringWithFormat:@"%@://%@:%ld", protocol, host, netService.port];
 
-    NSString *uri = [NSString stringWithFormat:@"%@://%@:%ld", protocol, netService.hostName, netService.port];
     input_item_t *p_input_item = input_item_NewDirectory([uri UTF8String], [netService.name UTF8String], ITEM_NET );
     if (p_input_item != NULL) {
         services_discovery_AddItem(p_sd, p_input_item);
-- 
GitLab