diff --git a/NearbyShare/Connection/NearbyOutgoingServiceResolver.swift b/NearbyShare/Connection/NearbyBonjourServiceResolver.swift similarity index 56% rename from NearbyShare/Connection/NearbyOutgoingServiceResolver.swift rename to NearbyShare/Connection/NearbyBonjourServiceResolver.swift index ad64e72..6e02020 100644 --- a/NearbyShare/Connection/NearbyOutgoingServiceResolver.swift +++ b/NearbyShare/Connection/NearbyBonjourServiceResolver.swift @@ -1,40 +1,70 @@ // -// NearbyOutgoingServiceResolver.swift +// NearbyBonjourServiceResolver.swift // QuickDrop // // Created by Leon Böttger on 19.05.26. // +import Darwin import Foundation import Network -final class NearbyOutgoingServiceResolver: NSObject, NetServiceDelegate { +struct NearbyResolvedBonjourEndpoint { + let endpoint: NWEndpoint + /// Numeric host string; IPv6 link-local hosts may include a `%scopeID` suffix for NWEndpoint routing. + let host: String + let port: UInt16 + let interface: NWInterface? + let description: String + let isIPv4: Bool +} + + +final class NearbyBonjourServiceResolver: NSObject, NetServiceDelegate { + private static let defaultWatchdogGracePeriod: TimeInterval = 0.5 + private let service: NetService private let resolveTimeout: TimeInterval + private let watchdogGracePeriod: TimeInterval + private let interface: NWInterface? private var timeoutWorkItem: DispatchWorkItem? - private var completion: (([NearbyResolvedServiceEndpoint]) -> Void)? + private var completion: (([NearbyResolvedBonjourEndpoint]) -> Void)? private var finished = false init?( result: NWBrowser.Result, resolveTimeout: TimeInterval, - completion: @escaping ([NearbyResolvedServiceEndpoint]) -> Void + watchdogGracePeriod: TimeInterval = defaultWatchdogGracePeriod, + completion: @escaping ([NearbyResolvedBonjourEndpoint]) -> Void ) { - guard case let NWEndpoint.service(name: name, type: type, domain: domain, interface: _) = result.endpoint else { + guard let components = Self.serviceEndpointComponents(from: result) else { return nil } self.service = NetService( - domain: Self.normalizedServiceDomain(domain), - type: Self.normalizedServiceType(type), - name: name + domain: Self.normalizedServiceDomain(components.domain), + type: Self.normalizedServiceType(components.type), + name: components.name ) self.resolveTimeout = resolveTimeout + self.watchdogGracePeriod = watchdogGracePeriod + self.interface = components.interface self.completion = completion super.init() } + private static func serviceEndpointComponents( + from result: NWBrowser.Result + ) -> (name: String, type: String, domain: String, interface: NWInterface?)? { + guard case let NWEndpoint.service(name: name, type: type, domain: domain, interface: interface) = result.endpoint else { + return nil + } + + return (name: name, type: type, domain: domain, interface: interface) + } + + func start() { service.delegate = self service.resolve(withTimeout: resolveTimeout) @@ -43,7 +73,7 @@ final class NearbyOutgoingServiceResolver: NSObject, NetServiceDelegate { self?.finish(endpoints: []) } self.timeoutWorkItem = timeoutWorkItem - DispatchQueue.main.asyncAfter(deadline: .now() + resolveTimeout + 0.5, execute: timeoutWorkItem) + DispatchQueue.main.asyncAfter(deadline: .now() + resolveTimeout + watchdogGracePeriod, execute: timeoutWorkItem) } @@ -53,7 +83,7 @@ final class NearbyOutgoingServiceResolver: NSObject, NetServiceDelegate { func netServiceDidResolveAddress(_ sender: NetService) { - finish(endpoints: Self.resolvedEndpoints(from: sender)) + finish(endpoints: Self.resolvedEndpoints(from: sender, interface: interface)) } @@ -62,7 +92,7 @@ final class NearbyOutgoingServiceResolver: NSObject, NetServiceDelegate { } - private func finish(endpoints: [NearbyResolvedServiceEndpoint], notify: Bool = true) { + private func finish(endpoints: [NearbyResolvedBonjourEndpoint], notify: Bool = true) { guard !finished else { return } finished = true timeoutWorkItem?.cancel() @@ -80,9 +110,12 @@ final class NearbyOutgoingServiceResolver: NSObject, NetServiceDelegate { } - private static func resolvedEndpoints(from service: NetService) -> [NearbyResolvedServiceEndpoint] { + private static func resolvedEndpoints( + from service: NetService, + interface: NWInterface? + ) -> [NearbyResolvedBonjourEndpoint] { let endpoints = (service.addresses ?? []) - .compactMap(resolvedEndpoint) + .compactMap { resolvedEndpoint(from: $0, interface: interface) } var seenDescriptions = Set() let uniqueEndpoints = endpoints.filter { endpoint in @@ -98,7 +131,10 @@ final class NearbyOutgoingServiceResolver: NSObject, NetServiceDelegate { } - private static func resolvedEndpoint(from addressData: Data) -> NearbyResolvedServiceEndpoint? { + private static func resolvedEndpoint( + from addressData: Data, + interface: NWInterface? + ) -> NearbyResolvedBonjourEndpoint? { addressData.withUnsafeBytes { rawBuffer in guard let baseAddress = rawBuffer.baseAddress else { return nil } @@ -123,7 +159,11 @@ final class NearbyOutgoingServiceResolver: NSObject, NetServiceDelegate { guard result == 0 else { return nil } - let host = String(cString: hostBuffer) + var host = String(cString: hostBuffer) + if addressFamily == AF_INET6 { + host = scopedIPv6Host(host, addressData: addressData) + } + guard let portRawValue = UInt16(String(cString: portBuffer)), let port = NWEndpoint.Port(rawValue: portRawValue) else { return nil @@ -137,8 +177,13 @@ final class NearbyOutgoingServiceResolver: NSObject, NetServiceDelegate { description = "\(host):\(portRawValue)" } - return NearbyResolvedServiceEndpoint( + let isIPv6LinkLocal = addressFamily == AF_INET6 && host.lowercased().hasPrefix("fe80:") + + return NearbyResolvedBonjourEndpoint( endpoint: endpoint, + host: host, + port: portRawValue, + interface: isIPv6LinkLocal ? interface : nil, description: description, isIPv4: addressFamily == AF_INET ) @@ -146,6 +191,33 @@ final class NearbyOutgoingServiceResolver: NSObject, NetServiceDelegate { } + private static func scopedIPv6Host( + _ host: String, + addressData: Data + ) -> String { + guard !host.contains("%"), + host.lowercased().hasPrefix("fe80:") else { + return host + } + + guard let scopeID = ipv6ScopeID(from: addressData), scopeID != 0 else { + return host + } + + return "\(host)%\(scopeID)" + } + + + private static func ipv6ScopeID(from addressData: Data) -> UInt32? { + addressData.withUnsafeBytes { rawBuffer in + guard let baseAddress = rawBuffer.baseAddress else { return nil } + let sockaddrPointer = baseAddress.assumingMemoryBound(to: sockaddr.self) + guard Int32(sockaddrPointer.pointee.sa_family) == AF_INET6 else { return nil } + return baseAddress.assumingMemoryBound(to: sockaddr_in6.self).pointee.sin6_scope_id + } + } + + private static func normalizedServiceDomain(_ domain: String) -> String { let trimmedDomain = domain.trimmingCharacters(in: .whitespacesAndNewlines) guard !trimmedDomain.isEmpty else { return "local." } @@ -158,10 +230,3 @@ final class NearbyOutgoingServiceResolver: NSObject, NetServiceDelegate { return trimmedType.hasSuffix(".") ? trimmedType : "\(trimmedType)." } } - - -struct NearbyResolvedServiceEndpoint { - let endpoint: NWEndpoint - let description: String - let isIPv4: Bool -} diff --git a/NearbyShare/Connection/NearbyConnectionManager.swift b/NearbyShare/Connection/NearbyConnectionManager.swift index 6fa71bc..7dda623 100644 --- a/NearbyShare/Connection/NearbyConnectionManager.swift +++ b/NearbyShare/Connection/NearbyConnectionManager.swift @@ -10,7 +10,6 @@ import UIKit import DeviceKit #endif -import Darwin import Foundation import Network import System @@ -35,7 +34,7 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb private var inboundAppDelegates: [InboundAppDelegate] = [] private var outgoingTransfers: [String: OutgoingTransferInfo] = [:] private var pendingOutgoingTransferPreparations: [String: UUID] = [:] - private var outgoingServiceResolvers: [String: NearbyOutgoingServiceResolver] = [:] + private var outgoingServiceResolvers: [String: NearbyBonjourServiceResolver] = [:] private let pendingNotificationSyncTrustQueue = DispatchQueue(label: "NearbyConnectionManager.pendingNotificationSyncTrust") private var pendingNotificationSyncTrust: [String: PendingReceiverTrust] = [:] private var startedDeviceDiscovery = false @@ -812,7 +811,7 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb preparationFinished?() - self.resolveOutgoingEndpoint(for: info.service, deviceID: deviceID) { endpoint in + self.resolveOutgoingEndpoint(for: info.service, deviceID: deviceID) { endpoint, requiredInterface in guard let info = self.foundServices[deviceID], self.pendingOutgoingTransferPreparations[deviceID] == preparationID else { return @@ -822,7 +821,9 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb let tcp = NWProtocolTCP.Options() tcp.noDelay = true - let nwconn = NWConnection(to: endpoint, using: NWParameters(tls: .none, tcp: tcp)) + let parameters = NWParameters(tls: .none, tcp: tcp) + parameters.requiredInterface = requiredInterface + let nwconn = NWConnection(to: endpoint, using: parameters) let conn = OutboundNearbyConnection( connection: nwconn, @@ -861,21 +862,21 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb private func resolveOutgoingEndpoint( for service: NWBrowser.Result, deviceID: String, - completion: @escaping (NWEndpoint) -> Void + completion: @escaping (NWEndpoint, NWInterface?) -> Void ) { - guard let resolver = NearbyOutgoingServiceResolver(result: service, resolveTimeout: 2.5, completion: { [weak self] endpoints in + guard let resolver = NearbyBonjourServiceResolver(result: service, resolveTimeout: 2.5, completion: { [weak self] endpoints in guard let self else { return } self.outgoingServiceResolvers.removeValue(forKey: deviceID) if let endpoint = endpoints.first { - completion(endpoint.endpoint) + completion(endpoint.endpoint, endpoint.interface) } else { log("[NearbyConnectionManager] Could not resolve outgoing service for \(deviceID); falling back to Bonjour endpoint \(service.endpoint)") - completion(service.endpoint) + completion(service.endpoint, nil) } }) else { log("[NearbyConnectionManager] Cannot create resolver for outgoing service; falling back to Bonjour endpoint") - completion(service.endpoint) + completion(service.endpoint, nil) return } diff --git a/NearbyShare/Connection/NearbyDeviceNameResolver.swift b/NearbyShare/Connection/NearbyDeviceNameResolver.swift index fe03f62..2b52d40 100644 --- a/NearbyShare/Connection/NearbyDeviceNameResolver.swift +++ b/NearbyShare/Connection/NearbyDeviceNameResolver.swift @@ -10,7 +10,12 @@ import Foundation import Network final class NearbyDeviceNameResolver { - private var hostnameResolvers: [UUID: NearbyNetworkScannerHostnameResolver] = [:] + private static let hostnameLookupQueue = DispatchQueue( + label: "com.leonboettger.quickdrop.deviceNameHostnameLookup", + qos: .utility + ) + + private var hostnameResolvers: [UUID: NearbyBonjourServiceResolver] = [:] private var lookupTokens: [String: UUID] = [:] func needsLookup(for endpointInfo: EndpointInfo?) -> Bool { @@ -47,10 +52,25 @@ final class NearbyDeviceNameResolver { private func resolveAdvertisedHostname(for service: NWBrowser.Result, completion: @escaping (String?) -> Void) { let resolverID = UUID() - guard let resolver = NearbyNetworkScannerHostnameResolver(result: service, resolveTimeout: 0.5, completion: { [weak self] hostname in - self?.hostnameResolvers.removeValue(forKey: resolverID) - completion(hostname) - }) else { + guard let resolver = NearbyBonjourServiceResolver( + result: service, + resolveTimeout: 0.5, + watchdogGracePeriod: 1.0, + completion: { [weak self] endpoints in + self?.hostnameResolvers.removeValue(forKey: resolverID) + guard let ipv4Address = endpoints.first(where: \.isIPv4)?.host else { + completion(nil) + return + } + + Self.hostnameLookupQueue.async { + let hostname = NearbyHostLookup.hostname(forIPv4: ipv4Address) + DispatchQueue.main.async { + completion(hostname) + } + } + } + ) else { completion(nil) return } @@ -61,142 +81,12 @@ final class NearbyDeviceNameResolver { } -private final class NearbyNetworkScannerHostnameResolver: NSObject, NetServiceDelegate { - private static let hostnameLookupQueue = DispatchQueue( - label: "com.leonboettger.quickdrop.networkScannerHostname", - qos: .utility - ) - - private let service: NetService - private let resolveTimeout: TimeInterval - private var timeoutWorkItem: DispatchWorkItem? - private var completion: ((String?) -> Void)? - private var finished = false - - init?( - result: NWBrowser.Result, - resolveTimeout: TimeInterval, - completion: @escaping (String?) -> Void - ) { - guard case let NWEndpoint.service(name: name, type: type, domain: domain, interface: _) = result.endpoint else { - return nil - } - - self.service = NetService( - domain: Self.normalizedServiceDomain(domain), - type: Self.normalizedServiceType(type), - name: name - ) - self.resolveTimeout = resolveTimeout - self.completion = completion - super.init() - } - - - func start() { - service.delegate = self - service.resolve(withTimeout: resolveTimeout) - - let timeoutWorkItem = DispatchWorkItem { [weak self] in - self?.finish(hostname: nil) - } - self.timeoutWorkItem = timeoutWorkItem - DispatchQueue.main.asyncAfter(deadline: .now() + resolveTimeout + 1.0, execute: timeoutWorkItem) - } - - - func cancel() { - finish(hostname: nil, notify: false) - } - - - func netServiceDidResolveAddress(_ sender: NetService) { - let numericAddresses = sender.addresses?.compactMap(Self.numericHostString) ?? [] - guard let ipv4Address = numericAddresses.first(where: NearbyNetworkScannerHostLookup.isIPv4Address) else { - finish(hostname: nil) - return - } - - Self.hostnameLookupQueue.async { [weak self] in - let hostname = NearbyNetworkScannerHostLookup.hostname(forIPv4: ipv4Address) - DispatchQueue.main.async { - self?.finish(hostname: hostname) - } - } - } - - - func netService(_ sender: NetService, didNotResolve errorDict: [String: NSNumber]) { - finish(hostname: nil) - } - - - private func finish(hostname: String?, notify: Bool = true) { - guard !finished else { return } - finished = true - timeoutWorkItem?.cancel() - service.stop() - service.delegate = nil - - let completion = completion - self.completion = nil - - if notify { - completion?(hostname) - } - } - - - private static func normalizedServiceDomain(_ domain: String) -> String { - let trimmedDomain = domain.trimmingCharacters(in: .whitespacesAndNewlines) - guard !trimmedDomain.isEmpty else { return "local." } - return trimmedDomain.hasSuffix(".") ? trimmedDomain : "\(trimmedDomain)." - } - - - private static func normalizedServiceType(_ type: String) -> String { - let trimmedType = type.trimmingCharacters(in: .whitespacesAndNewlines) - return trimmedType.hasSuffix(".") ? trimmedType : "\(trimmedType)." - } - - - private static func numericHostString(from addressData: Data) -> String? { - addressData.withUnsafeBytes { rawBuffer in - guard let baseAddress = rawBuffer.baseAddress else { return nil } - - var hostBuffer = [CChar](repeating: 0, count: Int(NI_MAXHOST)) - let sockaddrPointer = baseAddress.assumingMemoryBound(to: sockaddr.self) - let result = getnameinfo( - sockaddrPointer, - socklen_t(addressData.count), - &hostBuffer, - socklen_t(hostBuffer.count), - nil, - 0, - NI_NUMERICHOST - ) - - guard result == 0 else { return nil } - return String(cString: hostBuffer) - .split(separator: "%") - .first - .map(String.init) - } - } -} - - -private enum NearbyNetworkScannerHostLookup { +private enum NearbyHostLookup { static func hostname(forIPv4 address: String) -> String? { reverseDNSName(forIPv4: address).flatMap(prettifyDisplayName) } - static func isIPv4Address(_ address: String) -> Bool { - !address.contains(":") - } - - private static func reverseDNSName(forIPv4 address: String) -> String? { var socketAddress = sockaddr_in() socketAddress.sin_len = UInt8(MemoryLayout.size) diff --git a/QuickDrop.xcodeproj/project.pbxproj b/QuickDrop.xcodeproj/project.pbxproj index 1c12ee6..d032442 100644 --- a/QuickDrop.xcodeproj/project.pbxproj +++ b/QuickDrop.xcodeproj/project.pbxproj @@ -31,12 +31,12 @@ EB05DFBE2E59FC8900EF567A /* TrustedDevicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB05DFBD2E59FC8000EF567A /* TrustedDevicesView.swift */; }; EB05DFBF2E59FD0A00EF567A /* TrustedDevicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB05DFBD2E59FC8000EF567A /* TrustedDevicesView.swift */; }; EB05DFC02E5A2EAA00EF567A /* TrustedDevicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB05DFBD2E59FC8000EF567A /* TrustedDevicesView.swift */; }; - EB0A22E32FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB0A22E22FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift */; }; - EB0A22E42FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB0A22E22FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift */; }; - EB0A22E52FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB0A22E22FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift */; }; - EB0A22E62FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB0A22E22FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift */; }; - EB0A22E72FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB0A22E22FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift */; }; - EB0A22E82FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB0A22E22FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift */; }; + EB0A22E32FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB0A22E22FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift */; }; + EB0A22E42FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB0A22E22FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift */; }; + EB0A22E52FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB0A22E22FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift */; }; + EB0A22E62FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB0A22E22FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift */; }; + EB0A22E72FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB0A22E22FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift */; }; + EB0A22E82FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB0A22E22FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift */; }; EB1325D32E701D8E00FD749C /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325D22E701D8900FD749C /* Settings.swift */; }; EB1325D42E701D8E00FD749C /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325D22E701D8900FD749C /* Settings.swift */; }; EB1325D52E701D8E00FD749C /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325D22E701D8900FD749C /* Settings.swift */; }; @@ -524,7 +524,7 @@ A1F5B3D82F3A1A0100A1B2C3 /* PairingToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PairingToken.swift; sourceTree = ""; }; A1F5B3D92F3A1A0100A1B2C4 /* PairingQrSheetManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PairingQrSheetManager.swift; sourceTree = ""; }; EB05DFBD2E59FC8000EF567A /* TrustedDevicesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrustedDevicesView.swift; sourceTree = ""; }; - EB0A22E22FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearbyOutgoingServiceResolver.swift; sourceTree = ""; }; + EB0A22E22FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearbyBonjourServiceResolver.swift; sourceTree = ""; }; EB1325D22E701D8900FD749C /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = ""; }; EB1325E72E7025D900FD749C /* ActiveNetworkInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveNetworkInterface.swift; sourceTree = ""; }; EB1325E82E7025D900FD749C /* ApIsolation6Tester.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApIsolation6Tester.swift; sourceTree = ""; }; @@ -808,7 +808,7 @@ isa = PBXGroup; children = ( 69DA9A1E29E0C0B300A442DA /* NearbyConnectionManager.swift */, - EB0A22E22FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift */, + EB0A22E22FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift */, EB3B9F192EF7150400D67050 /* NearbyDeviceNameResolver.swift */, 69DA9A2229E17F0400A442DA /* InboundNearbyConnection.swift */, A1B2C3DA2F33AA0100ABC001 /* MirroredNotificationSupport.swift */, @@ -1320,7 +1320,7 @@ EB5C37C52E377A780052EFD7 /* securemessage.pb.swift in Sources */, EB5C37C62E377A780052EFD7 /* securegcm.pb.swift in Sources */, EB5C37C72E377A780052EFD7 /* wire_format.pb.swift in Sources */, - EB0A22E42FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift in Sources */, + EB0A22E42FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift in Sources */, EB5C37C82E377A780052EFD7 /* ukey.pb.swift in Sources */, EB5C37C92E377A780052EFD7 /* device_to_device_messages.pb.swift in Sources */, EB950B742E520957002D68FA /* Attachments.swift in Sources */, @@ -1399,7 +1399,7 @@ EBC05C822E33B58300EECC18 /* ApIsolationIssueView.swift in Sources */, EBC05C832E33B58300EECC18 /* FirewallIssueView.swift in Sources */, EB1325FA2E70288300FD749C /* SendToExtension.swift in Sources */, - EB0A22E72FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift in Sources */, + EB0A22E72FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift in Sources */, EB1325F42E7025D900FD749C /* ApIsolationTester.swift in Sources */, EB1325F52E7025D900FD749C /* ActiveNetworkInterface.swift in Sources */, EB1325F62E7025D900FD749C /* ApIsolation6Tester.swift in Sources */, @@ -1460,7 +1460,7 @@ EB3B9F272EF7150400D6704E /* ApIsolationIssueView.swift in Sources */, EB3B9F282EF7150400D6704E /* FirewallIssueView.swift in Sources */, EB3B9F292EF7150400D6704E /* SendToExtension.swift in Sources */, - EB0A22E82FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift in Sources */, + EB0A22E82FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift in Sources */, EB3B9F2A2EF7150400D6704E /* ApIsolationTester.swift in Sources */, EB3B9F2B2EF7150400D6704E /* ActiveNetworkInterface.swift in Sources */, EB3B9F2C2EF7150400D6704E /* ApIsolation6Tester.swift in Sources */, @@ -1491,7 +1491,7 @@ EB3B9F592EF7151900D6704E /* securemessage.pb.swift in Sources */, EB3B9F5A2EF7151900D6704E /* securegcm.pb.swift in Sources */, EB3B9F5B2EF7151900D6704E /* wire_format.pb.swift in Sources */, - EB0A22E52FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift in Sources */, + EB0A22E52FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift in Sources */, EB3B9F5C2EF7151900D6704E /* ukey.pb.swift in Sources */, EB3B9F5D2EF7151900D6704E /* device_to_device_messages.pb.swift in Sources */, EB3B9F5F2EF7151900D6704E /* Attachments.swift in Sources */, @@ -1540,7 +1540,7 @@ EB5C37F92E377CE70052EFD7 /* securegcm.pb.swift in Sources */, EB5C37FA2E377CE70052EFD7 /* Helpers.swift in Sources */, EB5C37FB2E377CE70052EFD7 /* InboundNearbyConnection.swift in Sources */, - EB0A22E62FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift in Sources */, + EB0A22E62FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift in Sources */, A1B2C3D82F33AA0100ABC001 /* MirroredNotificationSupport.swift in Sources */, EB9925802E45D53E00357055 /* sharing_enums.pb.swift in Sources */, EB5C37FC2E377CE70052EFD7 /* OutboundNearbyConnection.swift in Sources */, @@ -1585,7 +1585,7 @@ EB16B6132E58B4B9007D9792 /* IdentityManager.swift in Sources */, EB950B4D2E520436002D68FA /* NearbyConnection.swift in Sources */, EB950B502E520436002D68FA /* wire_format.pb.swift in Sources */, - EB0A22E32FBCF59300B78FF5 /* NearbyOutgoingServiceResolver.swift in Sources */, + EB0A22E32FBCF59300B78FF5 /* NearbyBonjourServiceResolver.swift in Sources */, EB950B582E5205B4002D68FA /* Zip.swift in Sources */, EB950B512E520436002D68FA /* securemessage.pb.swift in Sources */, EBA1BB1F2EF1F6030068E46E /* ChangeDeviceNameModifier.swift in Sources */, @@ -1812,7 +1812,7 @@ MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; - SHARED_BUILD = 147; + SHARED_BUILD = 148; SHARED_VERSION = 4.0; STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; @@ -1875,7 +1875,7 @@ MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = macosx; - SHARED_BUILD = 147; + SHARED_BUILD = 148; SHARED_VERSION = 4.0; STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_COMPILATION_MODE = wholemodule;