Expose multicast service type (#165)
Motivation As we've rolled out support for multicast on Linux, it makes sense to add equivalent configuration for swift-nio-transport-services. The two features aren't one-to-one, as Network.framework has substantially more capability than the Linux functionality. Modifications - Expose a multipathServiceType channel option - Add a test to confirm we use it properly Result Multicast service types are available.
This commit is contained in:
parent
d3345ffc2a
commit
e676b1f044
|
|
@ -46,6 +46,9 @@ public struct NIOTSChannelOptions {
|
|||
/// See: ``Types/NIOTSDataTransferReportOption``.
|
||||
@available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
|
||||
public static let dataTransferReport = NIOTSChannelOptions.Types.NIOTSDataTransferReportOption()
|
||||
|
||||
/// See: ``Types/NIOTSMultipathOption``
|
||||
public static let multipathServiceType = NIOTSChannelOptions.Types.NIOTSMultipathOption()
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -135,6 +138,15 @@ extension NIOTSChannelOptions {
|
|||
|
||||
public init() {}
|
||||
}
|
||||
|
||||
/// ``NIOTSMultipathOption`` sets the multipath behaviour for a given `NWConnection`
|
||||
/// or `NWListener`.
|
||||
@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)
|
||||
public struct NIOTSMultipathOption: ChannelOption, Equatable {
|
||||
public typealias Value = NWParameters.MultipathServiceType
|
||||
|
||||
public init() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -200,6 +200,9 @@ internal final class NIOTSConnectionChannel {
|
|||
/// Whether to use peer-to-peer connectivity when connecting to Bonjour services.
|
||||
private var enablePeerToPeer = false
|
||||
|
||||
/// The default multipath service type.
|
||||
private var multipathServiceType = NWParameters.MultipathServiceType.disabled
|
||||
|
||||
/// The cache of the local and remote socket addresses. Must be accessed using _addressCacheLock.
|
||||
private var _addressCache = AddressCache(local: nil, remote: nil)
|
||||
|
||||
|
|
@ -322,6 +325,8 @@ extension NIOTSConnectionChannel: Channel {
|
|||
self.enablePeerToPeer = value as! NIOTSChannelOptions.Types.NIOTSEnablePeerToPeerOption.Value
|
||||
case is NIOTSChannelOptions.Types.NIOTSAllowLocalEndpointReuse:
|
||||
self.allowLocalEndpointReuse = value as! NIOTSChannelOptions.Types.NIOTSEnablePeerToPeerOption.Value
|
||||
case is NIOTSChannelOptions.Types.NIOTSMultipathOption:
|
||||
self.multipathServiceType = value as! NIOTSChannelOptions.Types.NIOTSMultipathOption.Value
|
||||
default:
|
||||
fatalError("option \(type(of: option)).\(option) not supported")
|
||||
}
|
||||
|
|
@ -378,6 +383,8 @@ extension NIOTSConnectionChannel: Channel {
|
|||
throw NIOTSErrors.NoCurrentConnection()
|
||||
}
|
||||
return nwConnection.metadata(definition: optionValue.definition) as! Option.Value
|
||||
case is NIOTSChannelOptions.Types.NIOTSMultipathOption:
|
||||
return self.multipathServiceType as! Option.Value
|
||||
default:
|
||||
// watchOS 6.0 availability is covered by the @available on this extension.
|
||||
if #available(OSX 10.15, iOS 13.0, tvOS 13.0, *) {
|
||||
|
|
@ -493,6 +500,8 @@ extension NIOTSConnectionChannel: StateManagedChannel {
|
|||
|
||||
parameters.includePeerToPeer = self.enablePeerToPeer
|
||||
|
||||
parameters.multipathServiceType = self.multipathServiceType
|
||||
|
||||
let connection = NWConnection(to: target, using: parameters)
|
||||
connection.stateUpdateHandler = self.stateUpdateHandler(newState:)
|
||||
connection.betterPathUpdateHandler = self.betterPathHandler
|
||||
|
|
|
|||
|
|
@ -85,6 +85,9 @@ internal final class NIOTSListenerChannel {
|
|||
/// Whether to enable peer-to-peer connectivity when using Bonjour services.
|
||||
private var enablePeerToPeer = false
|
||||
|
||||
/// The default multipath service type.
|
||||
private var multipathServiceType = NWParameters.MultipathServiceType.disabled
|
||||
|
||||
/// The event loop group to use for child channels.
|
||||
private let childLoopGroup: EventLoopGroup
|
||||
|
||||
|
|
@ -220,6 +223,8 @@ extension NIOTSListenerChannel: Channel {
|
|||
self.enablePeerToPeer = value as! NIOTSChannelOptions.Types.NIOTSEnablePeerToPeerOption.Value
|
||||
case is NIOTSChannelOptions.Types.NIOTSAllowLocalEndpointReuse:
|
||||
self.allowLocalEndpointReuse = value as! NIOTSChannelOptions.Types.NIOTSEnablePeerToPeerOption.Value
|
||||
case is NIOTSChannelOptions.Types.NIOTSMultipathOption:
|
||||
self.multipathServiceType = value as! NIOTSChannelOptions.Types.NIOTSMultipathOption.Value
|
||||
default:
|
||||
fatalError("option \(option) not supported")
|
||||
}
|
||||
|
|
@ -257,6 +262,8 @@ extension NIOTSListenerChannel: Channel {
|
|||
return self.enablePeerToPeer as! Option.Value
|
||||
case is NIOTSChannelOptions.Types.NIOTSAllowLocalEndpointReuse:
|
||||
return self.allowLocalEndpointReuse as! Option.Value
|
||||
case is NIOTSChannelOptions.Types.NIOTSMultipathOption:
|
||||
return self.multipathServiceType as! Option.Value
|
||||
default:
|
||||
fatalError("option \(option) not supported")
|
||||
}
|
||||
|
|
@ -349,6 +356,8 @@ extension NIOTSListenerChannel: StateManagedChannel {
|
|||
|
||||
parameters.includePeerToPeer = self.enablePeerToPeer
|
||||
|
||||
parameters.multipathServiceType = self.multipathServiceType
|
||||
|
||||
let listener: NWListener
|
||||
do {
|
||||
listener = try NWListener(using: parameters)
|
||||
|
|
|
|||
|
|
@ -117,5 +117,27 @@ class NIOTSChannelOptionsTests: XCTestCase {
|
|||
collectGroup.wait()
|
||||
}
|
||||
|
||||
func testMultipathOptions() throws {
|
||||
let listener = try NIOTSListenerBootstrap(group: self.group)
|
||||
.serverChannelOption(NIOTSChannelOptions.multipathServiceType, value: .handover)
|
||||
.bind(host: "localhost", port: 0).wait()
|
||||
defer {
|
||||
XCTAssertNoThrow(try listener.close().wait())
|
||||
}
|
||||
|
||||
let connection = try NIOTSConnectionBootstrap(group: self.group)
|
||||
.channelOption(NIOTSChannelOptions.multipathServiceType, value: .interactive)
|
||||
.connect(to: listener.localAddress!)
|
||||
.wait()
|
||||
defer {
|
||||
XCTAssertNoThrow(try connection.close().wait())
|
||||
}
|
||||
|
||||
let listenerValue = try assertNoThrowWithValue(listener.getOption(NIOTSChannelOptions.multipathServiceType).wait())
|
||||
let connectionValue = try assertNoThrowWithValue(connection.getOption(NIOTSChannelOptions.multipathServiceType).wait())
|
||||
|
||||
XCTAssertEqual(listenerValue, .handover)
|
||||
XCTAssertEqual(connectionValue, .interactive)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue