diff --git a/Package.swift b/Package.swift index c64cafe..58952f3 100644 --- a/Package.swift +++ b/Package.swift @@ -14,7 +14,7 @@ let versionNumbers = ["0.1.0"] // Availability Macro Utilities enum _OSAvailability: String { - // This should match the package's deployment target + // The OS versions in which `Network 0.1.0` APIs first became available. case alwaysAvailable = "macOS 26, iOS 26, tvOS 26, watchOS 26, visionOS 26" // Use 10000 for future availability to avoid compiler magic around the 9999 version number but ensure it is greater than 9999 case future = "macOS 10000, iOS 10000, tvOS 10000, watchOS 10000, visionOS 10000" @@ -46,6 +46,7 @@ var settings: [SwiftSetting] = [ .define("SWIFTTLS_CERTIFICATE_VERIFICATION"), .unsafeFlags(["-Xfrontend", "-experimental-spi-only-imports"]), .enableExperimentalFeature("Lifetimes"), + .enableExperimentalFeature("AnyAppleOSAvailability"), .enableUpcomingFeature("ExistentialAny"), ] @@ -88,9 +89,6 @@ settings.append(.define("SHIM_CRYPTO_SPAN_APIS")) let package = Package( name: "swift-network-evolution", - platforms: [ - .macOS("26.0"), .iOS("26.0"), .tvOS("26.0"), .watchOS("26.0"), .visionOS("26.0"), - ], products: [ .library( name: "SwiftNetwork", @@ -143,52 +141,52 @@ let package = Package( .target( name: "SwiftNetworkBenchmarks", dependencies: targetDependencies + ["SwiftNetwork"], - swiftSettings: settings + swiftSettings: availabilityMacros + settings ), .testTarget( name: "SwiftNetworkTests", dependencies: ["SwiftNetwork"], - swiftSettings: settings + swiftSettings: availabilityMacros + settings ), .testTarget( name: "QUICTests", dependencies: ["SwiftNetwork"], - swiftSettings: settings + swiftSettings: availabilityMacros + settings ), .executableTarget( name: "QUICHandshake", dependencies: ["SwiftNetwork", "SwiftNetworkBenchmarks"], path: "Sources/Tools/QUICHandshake", exclude: ["README.md"], - swiftSettings: settings, + swiftSettings: availabilityMacros + settings, ), .executableTarget( name: "IPUDPTransfer", dependencies: ["SwiftNetwork", "SwiftNetworkBenchmarks"], path: "Sources/Tools/IPUDPTransfer", exclude: ["README.md"], - swiftSettings: settings + swiftSettings: availabilityMacros + settings ), .executableTarget( name: "QUICTransfer", dependencies: ["SwiftNetwork", "SwiftNetworkBenchmarks"], path: "Sources/Tools/QUICTransfer", exclude: ["README.md"], - swiftSettings: settings + swiftSettings: availabilityMacros + settings ), .executableTarget( name: "QUICStreamLoad", dependencies: ["SwiftNetwork", "SwiftNetworkBenchmarks"], path: "Sources/Tools/QUICStreamLoad", exclude: ["README.md"], - swiftSettings: settings + swiftSettings: availabilityMacros + settings ), .executableTarget( name: "SocketTransfer", dependencies: ["SwiftNetwork", "SwiftNetworkBenchmarks"], path: "Sources/Tools/SocketTransfer", exclude: ["README.md"], - swiftSettings: settings + swiftSettings: availabilityMacros + settings ), ] ) diff --git a/Sources/SwiftNetwork/Connection/Connection.swift b/Sources/SwiftNetwork/Connection/Connection.swift index aed1dc1..371dd00 100644 --- a/Sources/SwiftNetwork/Connection/Connection.swift +++ b/Sources/SwiftNetwork/Connection/Connection.swift @@ -92,6 +92,7 @@ public protocol NetworkProtocolOptions { func configure(parameters: Parameters) } +@available(Network 0.1.0, *) extension NetworkProtocolOptions { public var belowProtocol: BelowProtocol { fatalError("This should not be called") diff --git a/Sources/SwiftNetwork/Connection/DataTransferSnapshot.swift b/Sources/SwiftNetwork/Connection/DataTransferSnapshot.swift index ebbcc7e..96e0ee8 100644 --- a/Sources/SwiftNetwork/Connection/DataTransferSnapshot.swift +++ b/Sources/SwiftNetwork/Connection/DataTransferSnapshot.swift @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #if !NETWORK_EMBEDDED +@available(Network 0.1.0, *) struct DataTransferSnapshot: Equatable { var interfaceIndex: UInt64? diff --git a/Sources/SwiftNetwork/Context/NetworkContext.swift b/Sources/SwiftNetwork/Context/NetworkContext.swift index 242a4ac..ab012e4 100644 --- a/Sources/SwiftNetwork/Context/NetworkContext.swift +++ b/Sources/SwiftNetwork/Context/NetworkContext.swift @@ -229,6 +229,7 @@ public final class NetworkContext: NetworkContextProtocol, @unchecked Sendable { // MARK: - Globals #if !NETWORK_PRIVATE && !NETWORK_STANDALONE && canImport(Dispatch) && !NETWORK_EMBEDDED +@available(Network 0.1.0, *) extension NetworkContext { struct TimerEntry: ~Copyable, NetworkComparable { var targetTime: DispatchTime @@ -369,6 +370,7 @@ extension NetworkContext { // MARK: - Async +@available(Network 0.1.0, *) extension NetworkContext { var queue: DispatchQueue { @@ -392,6 +394,7 @@ extension NetworkContext { // MARK: - Timers +@available(Network 0.1.0, *) extension NetworkContext { enum FutureTime { diff --git a/Sources/SwiftNetwork/Endpoint/EndpointCommon.swift b/Sources/SwiftNetwork/Endpoint/EndpointCommon.swift index 310a423..71b1aca 100644 --- a/Sources/SwiftNetwork/Endpoint/EndpointCommon.swift +++ b/Sources/SwiftNetwork/Endpoint/EndpointCommon.swift @@ -39,6 +39,7 @@ public struct EndpointEqualityFlags: OptionSet, Sendable { static public let all: EndpointEqualityFlags = [.interface, .parent, .proxyParent, .alternatives, .publicKeys] } +@available(Network 0.1.0, *) extension Endpoint.EndpointType { enum EndpointRawType: UInt32 { case invalid = 0 @@ -81,6 +82,7 @@ extension Endpoint.EndpointType { } } +@available(Network 0.1.0, *) protocol EndpointProtocol: CustomStringConvertible { var interface: Interface? { get } func isEqual(to other: Self, flags: EndpointEqualityFlags) -> Bool @@ -132,6 +134,7 @@ public protocol EndpointCommonProtocol: Hashable, Equatable { } #if !NETWORK_PRIVATE +@available(Network 0.1.0, *) extension EndpointCommonProtocol { var interface: Interface? { get { common.interface } @@ -139,6 +142,7 @@ extension EndpointCommonProtocol { } } +@available(Network 0.1.0, *) extension EndpointCommon { init?(_ data: inout [UInt8]) { self.interface = nil diff --git a/Sources/SwiftNetwork/Endpoint/EthernetAddress.swift b/Sources/SwiftNetwork/Endpoint/EthernetAddress.swift index f8ee628..6b59629 100644 --- a/Sources/SwiftNetwork/Endpoint/EthernetAddress.swift +++ b/Sources/SwiftNetwork/Endpoint/EthernetAddress.swift @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +@available(Network 0.1.0, *) public struct EthernetAddress: Hashable, CustomDebugStringConvertible { public static var broadcast: EthernetAddress { diff --git a/Sources/SwiftNetwork/Endpoint/IPv6Address.swift b/Sources/SwiftNetwork/Endpoint/IPv6Address.swift index 156cc2e..64db1eb 100644 --- a/Sources/SwiftNetwork/Endpoint/IPv6Address.swift +++ b/Sources/SwiftNetwork/Endpoint/IPv6Address.swift @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +@available(Network 0.1.0, *) public struct IPv6Address: IPAddress, Hashable, CustomDebugStringConvertible { /// The IPv6 "any" address. diff --git a/Sources/SwiftNetwork/EndpointFlow/EndpointFlow.swift b/Sources/SwiftNetwork/EndpointFlow/EndpointFlow.swift index 6b9045a..acd6d51 100644 --- a/Sources/SwiftNetwork/EndpointFlow/EndpointFlow.swift +++ b/Sources/SwiftNetwork/EndpointFlow/EndpointFlow.swift @@ -28,6 +28,7 @@ internal import os internal import Synchronization #endif +@available(Network 0.1.0, *) final class EndpointFlow: CustomDebugStringConvertible { /// State used to emit logs on the data path. diff --git a/Sources/SwiftNetwork/EndpointFlow/EndpointFlowExtension.swift b/Sources/SwiftNetwork/EndpointFlow/EndpointFlowExtension.swift index 59d13fc..fdaea88 100644 --- a/Sources/SwiftNetwork/EndpointFlow/EndpointFlowExtension.swift +++ b/Sources/SwiftNetwork/EndpointFlow/EndpointFlowExtension.swift @@ -19,11 +19,13 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) struct EndpointFlowPrivateStorage { func handleStateChange(_ state: EndpointFlow.State) {} mutating func initForReuse(_ flow: EndpointFlow) {} } +@available(Network 0.1.0, *) extension EndpointFlow { internal func startOnQueue() throws(NetworkError) { diff --git a/Sources/SwiftNetwork/EndpointFlow/EndpointFlowProtocols.swift b/Sources/SwiftNetwork/EndpointFlow/EndpointFlowProtocols.swift index 0e64ac1..f063e33 100644 --- a/Sources/SwiftNetwork/EndpointFlow/EndpointFlowProtocols.swift +++ b/Sources/SwiftNetwork/EndpointFlow/EndpointFlowProtocols.swift @@ -19,10 +19,12 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) protocol AbstractEndpointFlowProtocol: InboundDataHandler, LoggableProtocol { func teardown() } +@available(Network 0.1.0, *) class EndpointFlowProtocol: ProtocolInstanceContainer, AbstractEndpointFlowProtocol { typealias LowerProtocol = LinkageType.PairedLinkage @@ -247,6 +249,7 @@ class EndpointFlowProtocol: ProtocolInstanceCon } } +@available(Network 0.1.0, *) final class DatagramEndpointFlowProtocol: EndpointFlowProtocol, InboundDatagramHandler { override var reference: ProtocolInstanceReference { ProtocolInstanceReference(datagramEndpointFlow: self) } @@ -375,6 +378,7 @@ final class DatagramEndpointFlowProtocol: EndpointFlowProtocol, InboundStreamHandler { override var reference: ProtocolInstanceReference { ProtocolInstanceReference(streamEndpointFlow: self) } diff --git a/Sources/SwiftNetwork/EndpointFlow/ReadRequest.swift b/Sources/SwiftNetwork/EndpointFlow/ReadRequest.swift index 9dfe67b..266098d 100644 --- a/Sources/SwiftNetwork/EndpointFlow/ReadRequest.swift +++ b/Sources/SwiftNetwork/EndpointFlow/ReadRequest.swift @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +@available(Network 0.1.0, *) struct ReadRequest { let minimumBytes: Int let maximumBytes: Int diff --git a/Sources/SwiftNetwork/EndpointFlow/WriteRequest.swift b/Sources/SwiftNetwork/EndpointFlow/WriteRequest.swift index d363391..bfe8c22 100644 --- a/Sources/SwiftNetwork/EndpointFlow/WriteRequest.swift +++ b/Sources/SwiftNetwork/EndpointFlow/WriteRequest.swift @@ -23,6 +23,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) struct WriteRequest: ~Copyable { var frame: Frame let completion: (@Sendable (Result) -> Void)? diff --git a/Sources/SwiftNetwork/Parameters/Parameters.swift b/Sources/SwiftNetwork/Parameters/Parameters.swift index 51ebcb3..6ef6a0a 100644 --- a/Sources/SwiftNetwork/Parameters/Parameters.swift +++ b/Sources/SwiftNetwork/Parameters/Parameters.swift @@ -777,6 +777,7 @@ public struct Parameters: Hashable, CustomStringConvertible { // MARK: - Description +@available(Network 0.1.0, *) extension Parameters { public var description: String { #if !NETWORK_EMBEDDED @@ -880,6 +881,7 @@ extension Parameters { // MARK: - Accessors +@available(Network 0.1.0, *) extension Parameters { var processUUID: SystemUUID { get { pathParameters.processPathValue.processUUID } diff --git a/Sources/SwiftNetwork/Parameters/PathParameters.swift b/Sources/SwiftNetwork/Parameters/PathParameters.swift index a87a06b..3114ac7 100644 --- a/Sources/SwiftNetwork/Parameters/PathParameters.swift +++ b/Sources/SwiftNetwork/Parameters/PathParameters.swift @@ -24,6 +24,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) struct PathParameters: Hashable, CustomStringConvertible { struct ProcessPathValue: Hashable { // Parameters that influence path selection for process delegation, by value, that @@ -364,6 +365,7 @@ struct PathParameters: Hashable, CustomStringConvertible { } // MARK: - Copying and comparing +@available(Network 0.1.0, *) extension PathParameters { init(deepCopy other: PathParameters) { self = other @@ -451,6 +453,7 @@ extension PathParameters { } // MARK: - Description and logging +@available(Network 0.1.0, *) extension PathParameters { var description: String { #if !NETWORK_EMBEDDED diff --git a/Sources/SwiftNetwork/Parameters/ProtocolTransform.swift b/Sources/SwiftNetwork/Parameters/ProtocolTransform.swift index aef3600..b4c1be9 100644 --- a/Sources/SwiftNetwork/Parameters/ProtocolTransform.swift +++ b/Sources/SwiftNetwork/Parameters/ProtocolTransform.swift @@ -17,6 +17,7 @@ import BasicContainers internal import DequeModule #endif +@available(Network 0.1.0, *) struct ProtocolTransform: Hashable { var transformStack: ProtocolStack? var trafficClass: UInt32? diff --git a/Sources/SwiftNetwork/Path/Interface.swift b/Sources/SwiftNetwork/Path/Interface.swift index 2190780..951bb95 100644 --- a/Sources/SwiftNetwork/Path/Interface.swift +++ b/Sources/SwiftNetwork/Path/Interface.swift @@ -489,6 +489,7 @@ public struct Interface: Sendable, Hashable, CustomStringConvertible { } #if !NETWORK_EMBEDDED +@available(Network 0.1.0, *) extension Interface: Codable { enum CodingKeys: String, CodingKey { case name @@ -518,6 +519,7 @@ extension Interface: Codable { } } +@available(Network 0.1.0, *) extension InterfaceType: Codable { enum CodingKeys: String, CodingKey { case value @@ -535,6 +537,7 @@ extension InterfaceType: Codable { } } +@available(Network 0.1.0, *) extension InterfaceSubtype: Codable { enum CodingKeys: String, CodingKey { case value diff --git a/Sources/SwiftNetwork/Protocols/BottomProtocol.swift b/Sources/SwiftNetwork/Protocols/BottomProtocol.swift index 450e745..05ad0ec 100644 --- a/Sources/SwiftNetwork/Protocols/BottomProtocol.swift +++ b/Sources/SwiftNetwork/Protocols/BottomProtocol.swift @@ -168,6 +168,7 @@ where UpperProtocol == InboundDatagramLinkage { // MARK: - Bottom Protocol Implementation Details +@available(Network 0.1.0, *) extension BottomProtocolHandler where Self: ~Copyable { var asLower: UpperProtocol.PairedLinkage { .init(reference: reference) } @@ -256,6 +257,7 @@ extension BottomProtocolHandler where Self: ~Copyable { } // Default implementations, to be overridden as necessary +@available(Network 0.1.0, *) extension BottomProtocolHandler where Self: ~Copyable { public func setup( remote: Endpoint?, @@ -281,6 +283,7 @@ extension BottomProtocolHandler where Self: ~Copyable { #endif } +@available(Network 0.1.0, *) extension BottomProtocolHandler where Self: ~Copyable, UpperProtocol == InboundDatagramLinkage { public mutating func attachUpperDatagramProtocol( _ from: ProtocolInstanceReference, @@ -305,6 +308,7 @@ extension BottomProtocolHandler where Self: ~Copyable, UpperProtocol == InboundD } } +@available(Network 0.1.0, *) extension BottomProtocolHandler where Self: ~Copyable, UpperProtocol == InboundStreamLinkage { public mutating func attachUpperStreamProtocol( _ from: ProtocolInstanceReference, @@ -329,6 +333,7 @@ extension BottomProtocolHandler where Self: ~Copyable, UpperProtocol == InboundS } } +@available(Network 0.1.0, *) extension BottomDatagramProtocol where Self: ~Copyable { public mutating func receiveDatagrams( _ from: ProtocolInstanceReference, @@ -366,6 +371,7 @@ extension BottomDatagramProtocol where Self: ~Copyable { } } +@available(Network 0.1.0, *) extension BottomStreamProtocol where Self: ~Copyable { public mutating func receiveStreamData( _ from: ProtocolInstanceReference, diff --git a/Sources/SwiftNetwork/Protocols/Checksum.swift b/Sources/SwiftNetwork/Protocols/Checksum.swift index 9a10ae2..e28dba9 100644 --- a/Sources/SwiftNetwork/Protocols/Checksum.swift +++ b/Sources/SwiftNetwork/Protocols/Checksum.swift @@ -54,6 +54,7 @@ enum ChecksumError: Error { case invalidBuffer } +@available(Network 0.1.0, *) extension IPv6Address { func checksum() -> UInt32 { let address = self.addressValue @@ -66,6 +67,7 @@ extension IPv6Address { } } +@available(Network 0.1.0, *) struct Checksum: ~Copyable { // Compute IPv6 pseudo-header checksum @@ -104,6 +106,7 @@ struct Checksum: ~Copyable { } } +@available(Network 0.1.0, *) extension Frame { func checksum16(offset: Int, length: Int) throws(ChecksumError) -> UInt16 { let frameLength = self.unclaimedLength diff --git a/Sources/SwiftNetwork/Protocols/CustomIPProtocol.swift b/Sources/SwiftNetwork/Protocols/CustomIPProtocol.swift index f864f50..cde5b43 100644 --- a/Sources/SwiftNetwork/Protocols/CustomIPProtocol.swift +++ b/Sources/SwiftNetwork/Protocols/CustomIPProtocol.swift @@ -118,6 +118,7 @@ public struct CustomIPProtocol: NetworkProtocol { } } +@available(Network 0.1.0, *) extension ProtocolOptions { var ipProtocolNumber: UInt8 { get { perProtocolOptions!.ipProtocolNumber } diff --git a/Sources/SwiftNetwork/Protocols/EthernetProtocol.swift b/Sources/SwiftNetwork/Protocols/EthernetProtocol.swift index 4bf36e3..1d5855b 100644 --- a/Sources/SwiftNetwork/Protocols/EthernetProtocol.swift +++ b/Sources/SwiftNetwork/Protocols/EthernetProtocol.swift @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +@available(Network 0.1.0, *) struct EthernetProtocol { struct Properties { let localEthernet: EthernetAddress diff --git a/Sources/SwiftNetwork/Protocols/Frame.swift b/Sources/SwiftNetwork/Protocols/Frame.swift index 9dbec5e..dcf0256 100644 --- a/Sources/SwiftNetwork/Protocols/Frame.swift +++ b/Sources/SwiftNetwork/Protocols/Frame.swift @@ -768,6 +768,7 @@ public struct Frame: ~Copyable { #endif } +@available(Network 0.1.0, *) extension Frame { var serviceClass: Parameters.ServiceClass { get { ipPacketValues?.serviceClass ?? .bestEffort } @@ -780,6 +781,7 @@ extension Frame { } } +@available(Network 0.1.0, *) extension Frame { // Copy length bytes from offset in this Frame into destination Frame. // checking the source offset, length and destination fit. diff --git a/Sources/SwiftNetwork/Protocols/ManyToManyProtocol.swift b/Sources/SwiftNetwork/Protocols/ManyToManyProtocol.swift index 735b6e2..898696b 100644 --- a/Sources/SwiftNetwork/Protocols/ManyToManyProtocol.swift +++ b/Sources/SwiftNetwork/Protocols/ManyToManyProtocol.swift @@ -205,6 +205,7 @@ where UpperProtocol: InboundDataLinkage, ParentProtocol: ManyToManyDatapathProto @_spi(ProtocolProvider) @available(Network 0.1.0, *) public typealias MultiplexingPathIdentifier = Int +@available(Network 0.1.0, *) extension MultiplexingPathIdentifier { static var none: Self { 0 @@ -249,6 +250,7 @@ where LowerProtocol: OutboundDataLinkage, ParentProtocol: ManyToManyDatapathProt // MARK: Implementations +@available(Network 0.1.0, *) extension ManyToManyProtocolHandler { // Default implementations, to be overridden as necessary public func setup( @@ -307,6 +309,7 @@ extension ManyToManyProtocolHandler { ) -> HandleNetworkEventResult { .unconsumed } } +@available(Network 0.1.0, *) extension ManyToManyProtocolHandler { var asListener: UpperProtocol.PairedLinkage { .init(reference: reference) } @@ -428,6 +431,7 @@ extension ManyToManyProtocolHandler { } } +@available(Network 0.1.0, *) extension HomogeneousManyToManyProtocolHandler { public mutating func performInitialSetupIfNeeded( @@ -598,6 +602,7 @@ extension HomogeneousManyToManyProtocolHandler { #endif } +@available(Network 0.1.0, *) extension HeterogeneousManyToManyProtocolHandler { fileprivate var hasNoUpperLinkages: Bool { multiplexedFlows.isEmpty && multiplexedSecondaryFlows.isEmpty && inboundFlowLinkage.isDetached @@ -634,6 +639,7 @@ extension HeterogeneousManyToManyProtocolHandler { } } +@available(Network 0.1.0, *) extension HeterogeneousManyToManyProtocolHandler { var asSecondaryListener: SecondaryUpperProtocol.PairedLinkage { .init(reference: reference) } @@ -916,6 +922,7 @@ extension HeterogeneousManyToManyProtocolHandler { #endif } +@available(Network 0.1.0, *) extension ManyToManyDatapathProtocol where Path.ParentProtocol == Self, Path: InboundDatagramHandler { public mutating func attachLowerDatagramProtocolForNewPath( _ lowerProtocol: ProtocolInstanceReference, @@ -937,6 +944,7 @@ extension ManyToManyDatapathProtocol where Path.ParentProtocol == Self, Path: In } } +@available(Network 0.1.0, *) extension ManyToManyDatapathProtocol where Flow.ParentProtocol == Self, Flow: OutboundStreamHandler { public mutating func attachNewStreamFlowProtocol( _ from: ProtocolInstanceReference, @@ -1000,6 +1008,7 @@ extension ManyToManyDatapathProtocol where Flow.ParentProtocol == Self, Flow: Ou } } +@available(Network 0.1.0, *) extension ManyToManyDatapathProtocol where Flow.ParentProtocol == Self, Flow: OutboundDatagramHandler { public mutating func attachNewDatagramFlowProtocol( _ from: ProtocolInstanceReference, @@ -1063,6 +1072,7 @@ extension ManyToManyDatapathProtocol where Flow.ParentProtocol == Self, Flow: Ou } } +@available(Network 0.1.0, *) extension HeterogeneousManyToManyProtocolHandler where SecondaryFlow.ParentProtocol == Self, SecondaryFlow: OutboundDatagramHandler { public mutating func attachNewDatagramFlowProtocol( @@ -1127,6 +1137,7 @@ where SecondaryFlow.ParentProtocol == Self, SecondaryFlow: OutboundDatagramHandl } } +@available(Network 0.1.0, *) extension MultiplexedFlow { var asLower: UpperProtocol.PairedLinkage { .init(reference: reference) } @@ -1247,6 +1258,7 @@ extension MultiplexedFlow { #endif } +@available(Network 0.1.0, *) extension MultiplexedFlow where ParentProtocol: HeterogeneousManyToManyProtocolHandler { public mutating func detach(_ from: ProtocolInstanceReference) throws(NetworkError) { do { try validate(upper: from, #function) } catch { throw NetworkError.posix(EINVAL) } @@ -1261,6 +1273,7 @@ extension MultiplexedFlow where ParentProtocol: HeterogeneousManyToManyProtocolH } } +@available(Network 0.1.0, *) extension MultiplexedDatapathFlow where Self: AutomaticUpperStreamProcessing { public mutating func receiveStreamData( _ from: ProtocolInstanceReference, @@ -1293,6 +1306,7 @@ extension MultiplexedDatapathFlow where Self: AutomaticUpperStreamProcessing { } } +@available(Network 0.1.0, *) extension MultiplexedDatapathFlow where Self: AutomaticUpperStreamProcessing, Self: OutboundStreamEarlyDataHandler { public mutating func sendEarlyStreamData( _ from: ProtocolInstanceReference, @@ -1306,6 +1320,7 @@ extension MultiplexedDatapathFlow where Self: AutomaticUpperStreamProcessing, Se } } +@available(Network 0.1.0, *) extension ManyToManyApplicationStreamProtocol where Flow: AutomaticUpperStreamProcessing { public func accessStreamDataToSend(flow flowID: MultiplexedFlowIdentifier, _ body: (inout FrameArray) -> Void) { guard var flow = self.flow(for: flowID) else { return } @@ -1413,6 +1428,7 @@ public protocol UnidirectionalAbortingStreamFlow: MultiplexedDatapathFlow, Outbo func abortOutbound(error: NetworkError?) } +@available(Network 0.1.0, *) extension UnidirectionalAbortingStreamFlow { public func deliverInboundAbortedEvent(error: NetworkError?) { if upper.isDetached { @@ -1457,6 +1473,7 @@ extension UnidirectionalAbortingStreamFlow { @available(Network 0.1.0, *) public protocol EarlyDataStreamFlow: MultiplexedDatapathFlow, OutboundStreamEarlyDataHandler {} +@available(Network 0.1.0, *) extension MultiplexedDatapathFlow where Self: AutomaticUpperDatagramProcessing { public mutating func receiveDatagrams( _ from: ProtocolInstanceReference, @@ -1496,6 +1513,7 @@ extension MultiplexedDatapathFlow where Self: AutomaticUpperDatagramProcessing { } } +@available(Network 0.1.0, *) extension ManyToManyApplicationDatagramProtocol where Flow: AutomaticUpperDatagramProcessing { public func accessDatagramsToSend(flow flowID: MultiplexedFlowIdentifier, _ body: (inout FrameArray) -> Void) { guard var flow = self.flow(for: flowID) else { return } @@ -1527,6 +1545,7 @@ extension ManyToManyApplicationDatagramProtocol where Flow: AutomaticUpperDatagr } } +@available(Network 0.1.0, *) extension HeterogeneousManyToManyProtocolHandler where SecondaryFlow: AutomaticUpperDatagramProcessing { public func accessDatagramsToSend(flow flowID: MultiplexedFlowIdentifier, _ body: (inout FrameArray) -> Void) { guard var flow = self.secondaryFlow(for: flowID) else { return } @@ -1621,6 +1640,7 @@ open class MultiplexedDatagramFlow: ~Copyable, ProtocolInstance mutating func handleNetworkProtocolEvent(_ from: ProtocolInstanceReference, event: NetworkProtocolEvent) } +@available(Network 0.1.0, *) extension ProtocolInstanceReference { func handleConnectedEvent(_ from: ProtocolInstanceReference) { switch reference { @@ -144,6 +145,7 @@ public protocol LowerProtocolHandler: ~Copyable, ProtocolInstance func getMetadata(_ from: ProtocolInstanceReference) -> ProtocolMetadata

? } +@available(Network 0.1.0, *) extension ProtocolInstanceReference { func connect(_ from: ProtocolInstanceReference) { guard !isNone else { return } diff --git a/Sources/SwiftNetwork/Protocols/ProtocolDatagramHandlers.swift b/Sources/SwiftNetwork/Protocols/ProtocolDatagramHandlers.swift index c30513a..5d334d6 100644 --- a/Sources/SwiftNetwork/Protocols/ProtocolDatagramHandlers.swift +++ b/Sources/SwiftNetwork/Protocols/ProtocolDatagramHandlers.swift @@ -165,6 +165,7 @@ public protocol OutboundDatagramHandler: ~Copyable, OutboundDataHandler where Up // MARK: Implementation Details +@available(Network 0.1.0, *) extension AutomaticLowerDatagramProcessing where Self: ~Copyable { mutating func _readInboundDatagrams() { var readCount = 0 @@ -195,6 +196,7 @@ extension AutomaticLowerDatagramProcessing where Self: ~Copyable { } } +@available(Network 0.1.0, *) extension AutomaticUpperDatagramProcessing where Self: ~Copyable { internal func newOutboundFrame(_ dataSize: Int) -> Frame { Frame(count: dataSize) @@ -229,6 +231,7 @@ extension AutomaticUpperDatagramProcessing where Self: ~Copyable { } } +@available(Network 0.1.0, *) extension ProtocolInstanceReference { func receiveDatagrams( _ from: ProtocolInstanceReference, diff --git a/Sources/SwiftNetwork/Protocols/ProtocolDatapathHandlers.swift b/Sources/SwiftNetwork/Protocols/ProtocolDatapathHandlers.swift index bb7c126..f0bfeb9 100644 --- a/Sources/SwiftNetwork/Protocols/ProtocolDatapathHandlers.swift +++ b/Sources/SwiftNetwork/Protocols/ProtocolDatapathHandlers.swift @@ -19,6 +19,7 @@ public protocol InboundDataHandler: ~Copyable, UpperProtocolHandler { mutating func handleOutboundRoomAvailableEvent(_ from: ProtocolInstanceReference) } +@available(Network 0.1.0, *) extension ProtocolInstanceReference { func handleInboundDataAvailableEvent(_ from: ProtocolInstanceReference) { switch reference { diff --git a/Sources/SwiftNetwork/Protocols/ProtocolEventManager.swift b/Sources/SwiftNetwork/Protocols/ProtocolEventManager.swift index e4980bf..9e23555 100644 --- a/Sources/SwiftNetwork/Protocols/ProtocolEventManager.swift +++ b/Sources/SwiftNetwork/Protocols/ProtocolEventManager.swift @@ -24,6 +24,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) struct ProtocolEventManagerState: ~Copyable { enum EventState { case idle @@ -301,6 +302,7 @@ public struct ProtocolEventManager: ~Copyable { } } +@available(Network 0.1.0, *) extension NetworkContext { fileprivate func softAssert() { #if DEBUG @@ -590,6 +592,7 @@ extension NetworkContext { } } +@available(Network 0.1.0, *) extension ProtocolInstance where Self: ~Copyable { func connectRequested() { reference.connectRequested() @@ -609,6 +612,7 @@ extension ProtocolInstance where Self: ~Copyable { } } +@available(Network 0.1.0, *) extension ProtocolInstanceReference { func connectRequested() { diff --git a/Sources/SwiftNetwork/Protocols/ProtocolInstance.swift b/Sources/SwiftNetwork/Protocols/ProtocolInstance.swift index 35d1643..55ad28c 100644 --- a/Sources/SwiftNetwork/Protocols/ProtocolInstance.swift +++ b/Sources/SwiftNetwork/Protocols/ProtocolInstance.swift @@ -47,6 +47,7 @@ public protocol ProtocolInstance: ~Copyable { var eventManager: ProtocolEventManager { get set } } +@available(Network 0.1.0, *) extension ProtocolInstance where Self: ~Copyable { /// Schedules an asynchronous block from within a protocol implementation. @@ -327,6 +328,7 @@ public protocol ProtocolInstanceContainer: AnyObject { } #if !NETWORK_EMBEDDED +@available(Network 0.1.0, *) extension ProtocolInstanceContainer { public func accessLower( at index: Int?, @@ -440,6 +442,7 @@ extension ProtocolInstanceContainer { fatalError("Unimplemented container function") } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: ProtocolInstance { var reference: ProtocolInstanceReference { ProtocolInstanceReference(custom: self) } @@ -451,6 +454,7 @@ extension ProtocolInstanceContainer where Self: ProtocolInstance { return try body(&selfAccess) } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: LowerProtocolHandler { public func accessLower( at index: Int?, @@ -460,6 +464,7 @@ extension ProtocolInstanceContainer where Self: LowerProtocolHandler { return try body(&selfAccess) } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: TimerSchedulable { public func accessTimerSchedulable( at index: Int?, @@ -469,6 +474,7 @@ extension ProtocolInstanceContainer where Self: TimerSchedulable { return try body(&selfAccess) } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: UpperProtocolHandler { public func accessUpper( at index: Int?, @@ -478,6 +484,7 @@ extension ProtocolInstanceContainer where Self: UpperProtocolHandler { return try body(&selfAccess) } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: ManyToManyProtocolHandler { public func accessManyToMany( at index: Int?, @@ -487,6 +494,7 @@ extension ProtocolInstanceContainer where Self: ManyToManyProtocolHandler { return try body(&selfAccess) } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: InboundFlowHandler { public func accessInboundFlowHandler( at index: Int?, @@ -496,6 +504,7 @@ extension ProtocolInstanceContainer where Self: InboundFlowHandler { return try body(&selfAccess) } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: ListenerHandler { public func accessListenerHandler( at index: Int?, @@ -505,6 +514,7 @@ extension ProtocolInstanceContainer where Self: ListenerHandler { return try body(&selfAccess) } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: DatagramListenerHandler { public func accessDatagramListenerHandler( at index: Int?, @@ -514,6 +524,7 @@ extension ProtocolInstanceContainer where Self: DatagramListenerHandler { return try body(&selfAccess) } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: StreamListenerHandler { public func accessStreamListenerHandler( at index: Int?, @@ -523,6 +534,7 @@ extension ProtocolInstanceContainer where Self: StreamListenerHandler { return try body(&selfAccess) } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: InboundDataHandler { public func accessInboundDataHandler( at index: Int?, @@ -532,6 +544,7 @@ extension ProtocolInstanceContainer where Self: InboundDataHandler { return try body(&selfAccess) } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: InboundDatagramHandler { public func accessInboundDatagramHandler( at index: Int?, @@ -541,6 +554,7 @@ extension ProtocolInstanceContainer where Self: InboundDatagramHandler { return try body(&selfAccess) } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: InboundStreamHandler { public func accessInboundStreamHandler( at index: Int?, @@ -550,6 +564,7 @@ extension ProtocolInstanceContainer where Self: InboundStreamHandler { return try body(&selfAccess) } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: OutboundDataHandler { public func accessOutboundDataHandler( at index: Int?, @@ -559,6 +574,7 @@ extension ProtocolInstanceContainer where Self: OutboundDataHandler { return try body(&selfAccess) } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: OutboundDatagramHandler { public func accessOutboundDatagramHandler( at index: Int?, @@ -576,6 +592,7 @@ extension ProtocolInstanceContainer where Self: OutboundDatagramHandler { return try body(&selfAccess, value) } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: OutboundStreamHandler { public func accessOutboundStreamHandler( at index: Int?, @@ -593,6 +610,7 @@ extension ProtocolInstanceContainer where Self: OutboundStreamHandler { return try body(&selfAccess, value) } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: OutboundStreamUnidirectionalAbortHandler { public func accessOutboundStreamUnidirectionalAbortHandler( at index: Int?, @@ -602,6 +620,7 @@ extension ProtocolInstanceContainer where Self: OutboundStreamUnidirectionalAbor return try body(&selfAccess) } } +@available(Network 0.1.0, *) extension ProtocolInstanceContainer where Self: OutboundStreamEarlyDataHandler { public func accessOutboundStreamEarlyDataHandler( at index: Int?, diff --git a/Sources/SwiftNetwork/Protocols/ProtocolLinkage.swift b/Sources/SwiftNetwork/Protocols/ProtocolLinkage.swift index e26f2de..7ffa683 100644 --- a/Sources/SwiftNetwork/Protocols/ProtocolLinkage.swift +++ b/Sources/SwiftNetwork/Protocols/ProtocolLinkage.swift @@ -23,6 +23,7 @@ public protocol ProtocolLinkage { var reference: ProtocolInstanceReference { get } } +@available(Network 0.1.0, *) extension ProtocolLinkage { public var isDetached: Bool { self.reference.isNone @@ -41,6 +42,7 @@ public protocol UpperProtocolLinkage: ProtocolLinkage where PairedLinkage: Lower ) } +@available(Network 0.1.0, *) extension UpperProtocolLinkage { public func deliverConnectedEvent(_ from: ProtocolInstanceReference) { from.deliverEventToUpperProtocol(event: .connected(from, self.reference)) @@ -66,6 +68,7 @@ public protocol InboundDataLinkage: UpperProtocolLinkage where PairedLinkage: Ou func deliverOutboundRoomAvailableEvent(_ from: ProtocolInstanceReference) } +@available(Network 0.1.0, *) extension InboundDataLinkage { public func deliverInboundDataAvailableEvent(_ from: ProtocolInstanceReference) { from.deliverEventToUpperProtocol(event: .inboundDataAvailable(from, self.reference)) @@ -86,6 +89,7 @@ public protocol InboundFlowLinkage: UpperProtocolLinkage where PairedLinkage: Li ) } +@available(Network 0.1.0, *) extension InboundFlowLinkage { public func deliverNewInboundFlowEvent( _ from: ProtocolInstanceReference, @@ -117,6 +121,7 @@ public protocol ListenerLinkage: LowerProtocolLinkage where PairedLinkage: Inbou #endif } +@available(Network 0.1.0, *) extension ListenerLinkage { #if !NETWORK_EMBEDDED public func invokeAttachUpperProtocolToNewFlow( @@ -171,6 +176,7 @@ public protocol LowerProtocolLinkage: ProtocolLinkage where PairedLinkage: Upper func invokeGetMetadata(_ from: ProtocolInstanceReference) -> ProtocolMetadata

? } +@available(Network 0.1.0, *) extension LowerProtocolLinkage { public var isConnected: Bool { reference.isConnected diff --git a/Sources/SwiftNetwork/Protocols/ProtocolListenerHandlers.swift b/Sources/SwiftNetwork/Protocols/ProtocolListenerHandlers.swift index c9920ba..2103d1a 100644 --- a/Sources/SwiftNetwork/Protocols/ProtocolListenerHandlers.swift +++ b/Sources/SwiftNetwork/Protocols/ProtocolListenerHandlers.swift @@ -22,6 +22,7 @@ public protocol InboundFlowHandler: ~Copyable, UpperProtocolHandler { ) } +@available(Network 0.1.0, *) extension ProtocolInstanceReference { func handleNewInboundFlowEvent( _ from: ProtocolInstanceReference, @@ -130,6 +131,7 @@ public protocol HeterogeneousListenerHandler: ~Copyable, ListenerHandler { associatedtype SecondaryUpperProtocol: InboundFlowLinkage } +@available(Network 0.1.0, *) extension ProtocolInstanceReference { #if !NETWORK_EMBEDDED func attachUpperProtocolToNewFlow( diff --git a/Sources/SwiftNetwork/Protocols/ProtocolStreamHandlers.swift b/Sources/SwiftNetwork/Protocols/ProtocolStreamHandlers.swift index 8d4b7e8..7494ce5 100644 --- a/Sources/SwiftNetwork/Protocols/ProtocolStreamHandlers.swift +++ b/Sources/SwiftNetwork/Protocols/ProtocolStreamHandlers.swift @@ -199,6 +199,7 @@ public protocol OutboundStreamEarlyDataHandler: ~Copyable, OutboundStreamHandler // MARK: Implementations +@available(Network 0.1.0, *) extension AutomaticLowerStreamProcessing where Self: ~Copyable { mutating func _readInboundStreamData() { var readCount = 0 @@ -224,6 +225,7 @@ extension AutomaticLowerStreamProcessing where Self: ~Copyable { } } +@available(Network 0.1.0, *) extension AutomaticUpperStreamProcessing where Self: ~Copyable { internal func newOutboundFrame(_ dataSize: Int) -> Frame { Frame(count: dataSize) @@ -265,6 +267,7 @@ extension AutomaticUpperStreamProcessing where Self: ~Copyable { } } +@available(Network 0.1.0, *) extension AutomaticUpperStreamProcessing where Self: ~Copyable, Self: OutboundStreamEarlyDataHandler { mutating func sendEarlyStreamData(_ streamData: consuming FrameArray) throws(NetworkError) { upperSendQueue.add(frames: streamData) @@ -272,6 +275,7 @@ extension AutomaticUpperStreamProcessing where Self: ~Copyable, Self: OutboundSt } } +@available(Network 0.1.0, *) extension ProtocolInstanceReference { func receiveStreamData( _ from: ProtocolInstanceReference, diff --git a/Sources/SwiftNetwork/Protocols/QUICStreamProtocol.swift b/Sources/SwiftNetwork/Protocols/QUICStreamProtocol.swift index ded9b05..be6800d 100644 --- a/Sources/SwiftNetwork/Protocols/QUICStreamProtocol.swift +++ b/Sources/SwiftNetwork/Protocols/QUICStreamProtocol.swift @@ -389,6 +389,7 @@ public struct QUICStreamProtocol: NetworkProtocol { } } +@available(Network 0.1.0, *) extension ProtocolOptions { var isDatagram: Bool { get { perProtocolOptions!.isDatagram } @@ -412,6 +413,7 @@ extension ProtocolOptions { #endif } +@available(Network 0.1.0, *) extension ProtocolMetadata { public var streamID: UInt64? { perProtocolMetadata?.streamID } public var datagramFlowID: UInt64? { perProtocolMetadata?.datagramFlowID } diff --git a/Sources/SwiftNetwork/Protocols/SwiftTLSProtocol.swift b/Sources/SwiftNetwork/Protocols/SwiftTLSProtocol.swift index 0228f07..0629d4f 100644 --- a/Sources/SwiftNetwork/Protocols/SwiftTLSProtocol.swift +++ b/Sources/SwiftNetwork/Protocols/SwiftTLSProtocol.swift @@ -49,6 +49,7 @@ internal import SwiftSystem public typealias TLSProtocol = SwiftTLSProtocol #endif +@available(Network 0.1.0, *) protocol SwiftTLSQUICInstance: AnyObject { func getLowerLinkage( for level: SwiftTLSOptions.EncryptionLevel, @@ -66,6 +67,7 @@ let SwiftTLSRecordProtocolMaxOutstandingReadBytes: Int = (8 * 1024 * 1024) // 8 // Wrapper to send a value. Ensures that the value is only accessed // from the context and fails otherwise. +@available(Network 0.1.0, *) private struct ContextBound: @unchecked Sendable { public let context: NetworkContext @@ -863,6 +865,7 @@ public struct SwiftTLSOptions { public init() {} } +@available(Network 0.1.0, *) class SwiftTLSHandshaker { public static func createClientHandshake() -> SwiftTLSHandshaker { SwiftTLSHandshaker() diff --git a/Sources/SwiftNetwork/Protocols/TopProtocol.swift b/Sources/SwiftNetwork/Protocols/TopProtocol.swift index 4a3f98a..45ad4fa 100644 --- a/Sources/SwiftNetwork/Protocols/TopProtocol.swift +++ b/Sources/SwiftNetwork/Protocols/TopProtocol.swift @@ -195,6 +195,7 @@ extension TopDatagramProtocol where Self: ~Copyable, Self: ~Copyable { // MARK: - Top Protocol Implementation Details +@available(Network 0.1.0, *) extension TopProtocolHandler where Self: ~Copyable { var asUpper: LowerProtocol.PairedLinkage { .init(reference: reference) } @@ -248,6 +249,7 @@ extension TopProtocolHandler where Self: ~Copyable { } // Default implementations, to be overridden as necessary +@available(Network 0.1.0, *) extension TopProtocolHandler where Self: ~Copyable { public func handleConnectedEvent() {} @@ -256,6 +258,7 @@ extension TopProtocolHandler where Self: ~Copyable { public func handleNetworkProtocolEvent(_ event: NetworkProtocolEvent) {} } +@available(Network 0.1.0, *) extension TopDatapathProtocol where Self: ~Copyable { public func handleInboundDataAvailableEvent(_ from: ProtocolInstanceReference) { do { try validate(lower: from, #function) } catch { return } @@ -268,6 +271,7 @@ extension TopDatapathProtocol where Self: ~Copyable { } } +@available(Network 0.1.0, *) extension TopDatapathProtocol where Self: ~Copyable { // Default implementations, to be overridden as necessary public func handleInboundDataAvailableEvent() {} @@ -275,6 +279,7 @@ extension TopDatapathProtocol where Self: ~Copyable { public func handleOutboundRoomAvailableEvent() {} } +@available(Network 0.1.0, *) extension TopProtocolHandler where Self: ~Copyable, LowerProtocol == OutboundDatagramLinkage { public mutating func attachLowerDatagramProtocol( _ lowerProtocol: ProtocolInstanceReference, @@ -296,6 +301,7 @@ extension TopProtocolHandler where Self: ~Copyable, LowerProtocol == OutboundDat } } +@available(Network 0.1.0, *) extension TopProtocolHandler where Self: ~Copyable, LowerProtocol == OutboundStreamLinkage { public mutating func attachLowerStreamProtocol( _ lowerProtocol: ProtocolInstanceReference, @@ -317,6 +323,7 @@ extension TopProtocolHandler where Self: ~Copyable, LowerProtocol == OutboundStr } } +@available(Network 0.1.0, *) extension TopStreamProtocol where Self: ~Copyable { public func handleInboundAbortedEvent(_ from: ProtocolInstanceReference, error: NetworkError?) { do { try validate(lower: from, #function) } catch { return } @@ -329,6 +336,7 @@ extension TopStreamProtocol where Self: ~Copyable { } } +@available(Network 0.1.0, *) extension TopStreamProtocol where Self: ~Copyable { // Default implementations, to be overridden as necessary public func handleInboundAbortedEvent(error: NetworkError?) {} diff --git a/Sources/SwiftNetwork/Protocols/UDPProtocol.swift b/Sources/SwiftNetwork/Protocols/UDPProtocol.swift index 9ac4164..3344bed 100644 --- a/Sources/SwiftNetwork/Protocols/UDPProtocol.swift +++ b/Sources/SwiftNetwork/Protocols/UDPProtocol.swift @@ -458,6 +458,7 @@ public struct UDPProtocol: NetworkProtocol { } } +@available(Network 0.1.0, *) extension ProtocolOptions { public var preferNoChecksum: Bool { get { perProtocolOptions!.contains(.preferNoChecksum) } diff --git a/Sources/SwiftNetwork/QUIC/Ack.swift b/Sources/SwiftNetwork/QUIC/Ack.swift index 9984f41..cce0511 100644 --- a/Sources/SwiftNetwork/QUIC/Ack.swift +++ b/Sources/SwiftNetwork/QUIC/Ack.swift @@ -26,9 +26,11 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) typealias AckBlock = (start: PacketNumber, end: PacketNumber) // ACK state per packet number space. +@available(Network 0.1.0, *) struct AckSpace: ~Copyable, PrefixedLoggable { var log: LogPrefixer var blocks: [AckBlock] = [] @@ -339,6 +341,7 @@ struct AckSpace: ~Copyable, PrefixedLoggable { } } +@available(Network 0.1.0, *) struct AckBlockIterator: IteratorProtocol { typealias Element = AckBlock @@ -393,6 +396,7 @@ struct AckBlockIterator: IteratorProtocol { } } +@available(Network 0.1.0, *) struct AckBlockSequence: Sequence { let largest: PacketNumber let oldestPacketNumber: PacketNumber @@ -413,6 +417,7 @@ struct AckBlockSequence: Sequence { } } +@available(Network 0.1.0, *) final class Ack: PrefixedLoggable, TimerUser { var log: LogPrefixer @@ -945,6 +950,7 @@ extension UInt64 { // This is a C bitstring.h inspired ACK bitstring, useful for finding out // which packets are newly acked. +@available(Network 0.1.0, *) struct AckBitstring: ~Copyable { private(set) var initialWord: UInt64 = 0 // Store up to 512 packets @@ -1108,6 +1114,7 @@ struct AckBitstring: ~Copyable { } } +@available(Network 0.1.0, *) struct AckBitstringIterator: IteratorProtocol { typealias Element = PacketNumber @@ -1152,6 +1159,7 @@ struct AckBitstringIterator: IteratorProtocol { } } +@available(Network 0.1.0, *) struct AckBitstringSequence: Sequence { let initialWord: UInt64 let startingWord: UInt64 @@ -1196,6 +1204,7 @@ struct AckBitstringSequence: Sequence { // MARK: - Testing interface +@available(Network 0.1.0, *) extension Ack { // Builds the ACK frame and inserts it in the packetBuilder, otherwise just calculates the size. // This function is only used in testing diff --git a/Sources/SwiftNetwork/QUIC/ArrayExtension.swift b/Sources/SwiftNetwork/QUIC/ArrayExtension.swift index 768e0dc..90f0993 100644 --- a/Sources/SwiftNetwork/QUIC/ArrayExtension.swift +++ b/Sources/SwiftNetwork/QUIC/ArrayExtension.swift @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +@available(Network 0.1.0, *) extension Array { init(copying span: Span, maxCount: Int) { let copyCount = Swift.min(span.count, maxCount) diff --git a/Sources/SwiftNetwork/QUIC/CongestionControl.swift b/Sources/SwiftNetwork/QUIC/CongestionControl.swift index 4b27a66..8a9db65 100644 --- a/Sources/SwiftNetwork/QUIC/CongestionControl.swift +++ b/Sources/SwiftNetwork/QUIC/CongestionControl.swift @@ -21,6 +21,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) enum CongestionControl { case cubic(algorithm: Cubic) #if !NETWORK_EMBEDDED @@ -283,6 +284,7 @@ enum CongestionControl { } } +@available(Network 0.1.0, *) protocol CongestionControlProtocol: PrefixedLoggable { var congestionWindow: UInt64 { get set } var bytesInFlight: UInt64 { get set } @@ -344,6 +346,7 @@ protocol CongestionControlProtocol: PrefixedLoggable { mutating func packetsAcked(bytesAcked: Int, sentTime: NetworkClock.Instant) } +@available(Network 0.1.0, *) extension CongestionControlProtocol { var congestionWindowValidationSamples: Int { 3 diff --git a/Sources/SwiftNetwork/QUIC/Constants.swift b/Sources/SwiftNetwork/QUIC/Constants.swift index ec3f574..991ba9a 100644 --- a/Sources/SwiftNetwork/QUIC/Constants.swift +++ b/Sources/SwiftNetwork/QUIC/Constants.swift @@ -14,6 +14,7 @@ // Constants for QUIC #if !NETWORK_NO_SWIFT_QUIC +@available(Network 0.1.0, *) enum Constants { static let initialMSS = 1200 static let streamIDDatagramMask: UInt64 = 0x8000_0000_0000_0000 diff --git a/Sources/SwiftNetwork/QUIC/Crypto.swift b/Sources/SwiftNetwork/QUIC/Crypto.swift index 1d429bc..7947fda 100644 --- a/Sources/SwiftNetwork/QUIC/Crypto.swift +++ b/Sources/SwiftNetwork/QUIC/Crypto.swift @@ -46,6 +46,7 @@ internal import CryptoKit #endif #endif +@available(Network 0.1.0, *) final class QUICCrypto { var eventManager = ProtocolEventManager() @@ -205,6 +206,7 @@ final class QUICCrypto { #if IMPORT_SWIFTTLS #if canImport(SwiftTLS) +@available(Network 0.1.0, *) extension QUICCrypto: SwiftTLSQUICInstance { func getLowerLinkage( for level: SwiftTLSOptions.EncryptionLevel, @@ -349,6 +351,7 @@ extension QUICCrypto: SwiftTLSQUICInstance { #endif #endif +@available(Network 0.1.0, *) extension QUICCrypto: TopStreamProtocol, ProtocolInstanceContainer { var context: NetworkContext { parentConnection!.context } @@ -472,6 +475,7 @@ extension QUICCrypto: TopStreamProtocol, ProtocolInstanceContainer { } // Per-Level Sending Callbacks +@available(Network 0.1.0, *) extension QUICCrypto: OutboundStreamHandler { #if !NETWORK_EMBEDDED func attachUpperProtocol( diff --git a/Sources/SwiftNetwork/QUIC/Cubic.swift b/Sources/SwiftNetwork/QUIC/Cubic.swift index 363073c..5e597ee 100644 --- a/Sources/SwiftNetwork/QUIC/Cubic.swift +++ b/Sources/SwiftNetwork/QUIC/Cubic.swift @@ -47,6 +47,7 @@ extension CubicLikeProtocol { } } +@available(Network 0.1.0, *) struct Cubic: CongestionControlProtocol, CubicLikeProtocol { var log: LogPrefixer diff --git a/Sources/SwiftNetwork/QUIC/ECN.swift b/Sources/SwiftNetwork/QUIC/ECN.swift index 21d116f..b2b4fff 100644 --- a/Sources/SwiftNetwork/QUIC/ECN.swift +++ b/Sources/SwiftNetwork/QUIC/ECN.swift @@ -26,6 +26,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) enum ECNState { /// The app explicitly asked to disable ECN. case disabled @@ -75,6 +76,7 @@ enum ECNState { } // Global explicit congestion notification state +@available(Network 0.1.0, *) struct ECN: ~Copyable, PrefixedLoggable { let log: LogPrefixer @@ -197,6 +199,7 @@ struct ECN: ~Copyable, PrefixedLoggable { } // Per path explicit congestion notification state +@available(Network 0.1.0, *) struct ECNPathState: ~Copyable, PrefixedLoggable { let log: LogPrefixer @@ -491,6 +494,7 @@ struct ECNPathState: ~Copyable, PrefixedLoggable { } } +@available(Network 0.1.0, *) struct ECNCounter { var ect0: Int var ect1: Int @@ -502,6 +506,7 @@ struct ECNCounter { } // ECN state metadata for a packet number space +@available(Network 0.1.0, *) class ECNCounters { // Number of packets sent with ECT(1) or ECT(0) codepoint var txECNPackets = 0 diff --git a/Sources/SwiftNetwork/QUIC/FlowControl.swift b/Sources/SwiftNetwork/QUIC/FlowControl.swift index 991d323..6927e2d 100644 --- a/Sources/SwiftNetwork/QUIC/FlowControl.swift +++ b/Sources/SwiftNetwork/QUIC/FlowControl.swift @@ -24,6 +24,7 @@ internal import os // MARK: FlowControlGlobals // FlowControlGlobals assumes that it is only setting a static collection of constants. +@available(Network 0.1.0, *) struct FlowControlGlobals: ~Copyable { // Flow Control Constants @@ -131,6 +132,7 @@ struct FlowControlGlobals: ~Copyable { // Storage for flow control state // For streams, these values are per-stream byte counts. // For connections, these values are summed across all streams. +@available(Network 0.1.0, *) struct FlowControlState: ~Copyable { // Inbound values (receiving): @@ -257,6 +259,7 @@ struct FlowControlState: ~Copyable { } } +@available(Network 0.1.0, *) extension QUICConnection { // Offset in the stream from which to next send bytes @@ -353,6 +356,7 @@ extension QUICConnection { } } +@available(Network 0.1.0, *) struct FlowControlStreamState: ~Copyable { // time when the measurement period started fileprivate var receiveHighWaterMarkTime: NetworkClock.Instant = .zero @@ -362,6 +366,7 @@ struct FlowControlStreamState: ~Copyable { fileprivate var receiveHighWaterMarkPreviousCount: UInt64 = 0 } +@available(Network 0.1.0, *) extension QUICStreamInstance { // Offset in the stream from which to next send bytes diff --git a/Sources/SwiftNetwork/QUIC/Ledbat.swift b/Sources/SwiftNetwork/QUIC/Ledbat.swift index 9ac96bd..9606514 100644 --- a/Sources/SwiftNetwork/QUIC/Ledbat.swift +++ b/Sources/SwiftNetwork/QUIC/Ledbat.swift @@ -21,6 +21,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) struct Ledbat: CongestionControlProtocol, CubicLikeProtocol { let log: LogPrefixer diff --git a/Sources/SwiftNetwork/QUIC/Logger+QUIC.swift b/Sources/SwiftNetwork/QUIC/Logger+QUIC.swift index d6b3f86..0c35eac 100644 --- a/Sources/SwiftNetwork/QUIC/Logger+QUIC.swift +++ b/Sources/SwiftNetwork/QUIC/Logger+QUIC.swift @@ -20,6 +20,7 @@ internal import os #endif // This class won't be shared across thread boundaries. +@available(Network 0.1.0, *) final class LogPrefixer: @unchecked Sendable { var log: NetworkLoggerState var logIDString: String { @@ -120,6 +121,7 @@ final class LogPrefixer: @unchecked Sendable { } #if !NETWORK_NO_SWIFT_QUIC +@available(Network 0.1.0, *) protocol PrefixedLoggable: ~Copyable { var log: LogPrefixer { get } } diff --git a/Sources/SwiftNetwork/QUIC/Migration.swift b/Sources/SwiftNetwork/QUIC/Migration.swift index f7a2325..b310ec5 100644 --- a/Sources/SwiftNetwork/QUIC/Migration.swift +++ b/Sources/SwiftNetwork/QUIC/Migration.swift @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #if !NETWORK_NO_SWIFT_QUIC +@available(Network 0.1.0, *) struct Migration: ~Copyable { static let defaultMigrationVersion = 7 static let defaultPTOThreshold = 3 @@ -150,6 +151,7 @@ struct Migration: ~Copyable { } } +@available(Network 0.1.0, *) extension QUICConnection { public func handlePathChanged( path pathID: MultiplexingPathIdentifier, diff --git a/Sources/SwiftNetwork/QUIC/PMTUD.swift b/Sources/SwiftNetwork/QUIC/PMTUD.swift index 8820934..a050e31 100644 --- a/Sources/SwiftNetwork/QUIC/PMTUD.swift +++ b/Sources/SwiftNetwork/QUIC/PMTUD.swift @@ -26,6 +26,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) struct PMTUDState: ~Copyable { static let minimumMTU = 1280 static let maximumMTU = 9216 diff --git a/Sources/SwiftNetwork/QUIC/Pacer.swift b/Sources/SwiftNetwork/QUIC/Pacer.swift index a32b110..595db31 100644 --- a/Sources/SwiftNetwork/QUIC/Pacer.swift +++ b/Sources/SwiftNetwork/QUIC/Pacer.swift @@ -21,6 +21,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) struct Pacer: ~Copyable { var packetSentTime: NetworkClock.Instant = .zero // in nanoseconds and in absolute time, when we last sent a packet var startupRate: UInt64 = 0 // pacing rate during startup (includes reset, after idle etc) diff --git a/Sources/SwiftNetwork/QUIC/Packet.swift b/Sources/SwiftNetwork/QUIC/Packet.swift index 1daefd2..8ff5743 100644 --- a/Sources/SwiftNetwork/QUIC/Packet.swift +++ b/Sources/SwiftNetwork/QUIC/Packet.swift @@ -85,6 +85,7 @@ enum PacketKeyState: Int, CaseIterable, CustomStringConvertible, Comparable { } } +@available(Network 0.1.0, *) struct SentPacketRecord: ~Copyable { var transmittedItems: TransmittedItems = TransmittedItems() @@ -163,6 +164,7 @@ struct SentPacketRecord: ~Copyable { } } +@available(Network 0.1.0, *) struct Packet: ~Copyable { static let longHeaderBaseSize = 5 static let shortHeaderBaseSize = 1 @@ -694,6 +696,7 @@ struct Packet: ~Copyable { } } +@available(Network 0.1.0, *) extension InPlaceSerializer where Factory: ~Escapable, Factory: ~Copyable { mutating func connectionID(_ value: QUICConnectionID) throws(SerializationError) { diff --git a/Sources/SwiftNetwork/QUIC/PacketBuilder.swift b/Sources/SwiftNetwork/QUIC/PacketBuilder.swift index 404828e..164ae2c 100644 --- a/Sources/SwiftNetwork/QUIC/PacketBuilder.swift +++ b/Sources/SwiftNetwork/QUIC/PacketBuilder.swift @@ -44,6 +44,7 @@ enum PacketBuilderError: Int, Error { } } +@available(Network 0.1.0, *) extension Packet { static func build( into outboundFrame: inout Frame, diff --git a/Sources/SwiftNetwork/QUIC/PacketFormats.swift b/Sources/SwiftNetwork/QUIC/PacketFormats.swift index cfc87ff..3ef6142 100644 --- a/Sources/SwiftNetwork/QUIC/PacketFormats.swift +++ b/Sources/SwiftNetwork/QUIC/PacketFormats.swift @@ -21,21 +21,25 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) private struct PacketFormatConstants { static let preambleLength = MemoryLayout.size } +@available(Network 0.1.0, *) extension QUICConnectionID { // number of bytes required to represent a Connection ID length on the wire static let headerCIDLength = 1 } +@available(Network 0.1.0, *) enum QUICPacketFormatsError: Int, Error { case serializationBufferTooSmall case unexpectedLength case sealingFailure } +@available(Network 0.1.0, *) private func validateSerializationResult(_ result: SerializationResult) throws(QUICError) { guard result.isValid else { throw QUICError.packetFormats(QUICPacketFormatsError.serializationBufferTooSmall) @@ -43,6 +47,7 @@ private func validateSerializationResult(_ result: SerializationResult) throws(Q } // MARK: - Version Negotiation +@available(Network 0.1.0, *) struct QUICVersionNegotiation: ~Copyable { // 0 1 2 3 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 @@ -119,6 +124,7 @@ struct QUICVersionNegotiation: ~Copyable { } // Retry Packet +@available(Network 0.1.0, *) struct QUICRetryPacket: ~Copyable { // 0 1 2 3 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 @@ -204,6 +210,7 @@ struct QUICRetryPacket: ~Copyable { } // https://www.rfc-editor.org/rfc/rfc9001.html#name-retry-packet-integrity +@available(Network 0.1.0, *) struct QUICPseudoRetry: ~Copyable { static func assemble( firstByte: UInt8, @@ -224,6 +231,7 @@ struct QUICPseudoRetry: ~Copyable { } } +@available(Network 0.1.0, *) struct QUICStatelessResetPacket: ~Copyable { // This design ensures that a Stateless Reset is -- to the extent possible -- indistinguishable from a regular packet with a short header diff --git a/Sources/SwiftNetwork/QUIC/PacketNumberSpace.swift b/Sources/SwiftNetwork/QUIC/PacketNumberSpace.swift index b807b42..a02b517 100644 --- a/Sources/SwiftNetwork/QUIC/PacketNumberSpace.swift +++ b/Sources/SwiftNetwork/QUIC/PacketNumberSpace.swift @@ -26,6 +26,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) struct PacketIdentifier: Comparable { static func < (lhs: PacketIdentifier, rhs: PacketIdentifier) -> Bool { if lhs.space == rhs.space { @@ -53,6 +54,7 @@ struct PacketIdentifier: Comparable { } } +@available(Network 0.1.0, *) struct EncodedPacketNumber { enum Size: Int, CaseIterable { case oneByte = 1 @@ -92,6 +94,7 @@ struct EncodedPacketNumber { } } +@available(Network 0.1.0, *) struct PacketNumber: Comparable, ExpressibleByIntegerLiteral, Hashable, CustomStringConvertible { init(integerLiteral value: Int64) { @@ -240,6 +243,7 @@ struct PacketNumber: Comparable, ExpressibleByIntegerLiteral, Hashable, CustomSt } } +@available(Network 0.1.0, *) enum PacketNumberSpace: UInt8, Comparable, CaseIterable { case initial = 0 case handshake = 1 @@ -259,6 +263,7 @@ enum PacketNumberSpace: UInt8, Comparable, CaseIterable { } } +@available(Network 0.1.0, *) extension NetworkRigidArray { // This extension is used to subscript an array by a PacketNumberSpace's rawValue // This ensures the performance of the lookup in the data path diff --git a/Sources/SwiftNetwork/QUIC/PacketParser.swift b/Sources/SwiftNetwork/QUIC/PacketParser.swift index 48ee40d..480b145 100644 --- a/Sources/SwiftNetwork/QUIC/PacketParser.swift +++ b/Sources/SwiftNetwork/QUIC/PacketParser.swift @@ -26,6 +26,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) struct PacketParser: ~Copyable, PrefixedLoggable { var log: LogPrefixer @@ -697,6 +698,7 @@ struct PacketParser: ~Copyable, PrefixedLoggable { } } +@available(Network 0.1.0, *) extension Deserializer where Factory: ~Escapable { mutating func packetNumber(_ value: inout PacketNumber, pnSize: UInt8) throws(DeserializationError) { switch pnSize { diff --git a/Sources/SwiftNetwork/QUIC/Prague.swift b/Sources/SwiftNetwork/QUIC/Prague.swift index 655a6fc..e3787bc 100644 --- a/Sources/SwiftNetwork/QUIC/Prague.swift +++ b/Sources/SwiftNetwork/QUIC/Prague.swift @@ -35,6 +35,7 @@ enum RTTControlType: UInt8 { case rateEquivalence } +@available(Network 0.1.0, *) struct Prague: CongestionControlProtocol, CubicLikeProtocol { let log: LogPrefixer diff --git a/Sources/SwiftNetwork/QUIC/Preferences.swift b/Sources/SwiftNetwork/QUIC/Preferences.swift index 14f4800..375202f 100644 --- a/Sources/SwiftNetwork/QUIC/Preferences.swift +++ b/Sources/SwiftNetwork/QUIC/Preferences.swift @@ -16,6 +16,7 @@ #if NETWORK_EMBEDDED // QUICPreferences for Embedded is small subset of preferences based on what is currently used in the stack otherwise. +@available(Network 0.1.0, *) struct QUICPreferences { static let shared = QUICPreferences() let ackCompressionEnabled: Bool = true @@ -33,6 +34,7 @@ struct QUICPreferences { private init() {} } #else +@available(Network 0.1.0, *) struct QUICPreferences: ~Copyable, Sendable { static let shared = QUICPreferences() diff --git a/Sources/SwiftNetwork/QUIC/Protector.swift b/Sources/SwiftNetwork/QUIC/Protector.swift index b47d0b1..5b9279a 100644 --- a/Sources/SwiftNetwork/QUIC/Protector.swift +++ b/Sources/SwiftNetwork/QUIC/Protector.swift @@ -28,6 +28,7 @@ internal import SwiftSystem #if canImport(CryptoKit) internal import CryptoKit +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) typealias SymmetricKey = CryptoKit.SymmetricKey #elseif canImport(Crypto) @preconcurrency internal import Crypto @@ -58,10 +59,13 @@ internal import DequeModule #endif #endif +@available(Network 0.1.0, *) typealias ProtectorNonce = [12 of UInt8] +@available(Network 0.1.0, *) typealias ProtectorIV = [12 of UInt8] // Crypto returns an IV in SymmetricKey format, but to speed up performance, we convert it to an InlineArray. +@available(Network 0.1.0, *) extension ProtectorIV { init(_ key: SymmetricKey) { precondition(key.bitCount == 96) @@ -79,6 +83,7 @@ enum SecFramerError: Int, Error { case openFailed } +@available(Network 0.1.0, *) enum TLSEncryptionLevel: CaseIterable { case initial case earlyData @@ -144,6 +149,7 @@ enum TLSCipherSuite: CaseIterable { } } +@available(Network 0.1.0, *) struct SecFramerKeys: ~Copyable { enum KeyType { case aesGCM @@ -195,6 +201,7 @@ struct SecFramerKeys: ~Copyable { } } +@available(Network 0.1.0, *) protocol SecFramerProtocol: ~Copyable { static func createKeyStorage( key: SymmetricKey, @@ -227,6 +234,7 @@ protocol SecFramerProtocol: ~Copyable { ) throws(QUICError) } +@available(Network 0.1.0, *) struct SecFramerAESGCM: ~Copyable, SecFramerProtocol { static func createKeyStorage( @@ -417,6 +425,7 @@ struct SecFramerAESGCM: ~Copyable, SecFramerProtocol { } #if !NETWORK_EMBEDDED +@available(Network 0.1.0, *) struct SecFramerChaChaPoly: ~Copyable, SecFramerProtocol { static func createKeyStorage( key: SymmetricKey, @@ -577,6 +586,7 @@ struct SecFramerChaChaPoly: ~Copyable, SecFramerProtocol { } #endif +@available(Network 0.1.0, *) struct Protector: ~Copyable, PrefixedLoggable { var log: LogPrefixer @@ -1345,6 +1355,7 @@ struct Protector: ~Copyable, PrefixedLoggable { #else // Stub implementation +@available(Network 0.1.0, *) struct Protector: ~Copyable, PrefixedLoggable { var log: LogPrefixer private let isClient: Bool @@ -1409,12 +1420,14 @@ struct Protector: ~Copyable, PrefixedLoggable { #endif #endif +@available(macOS 10.14.4, iOS 12.2, tvOS 12.2, watchOS 5.2, *) extension RawSpan { subscript(index: Int) -> UInt8 { unsafeLoad(fromByteOffset: index, as: UInt8.self) } } +@available(Network 0.1.0, *) extension MutableRawSpan { subscript(index: Int) -> UInt8 { get { unsafeLoad(fromByteOffset: index, as: UInt8.self) } @@ -1422,6 +1435,7 @@ extension MutableRawSpan { } } +@available(macOS 10.14.4, iOS 12.2, tvOS 12.2, watchOS 5.2, *) extension Array where Element == UInt8 { /// Copies the bytes of the given raw span into this array. /// diff --git a/Sources/SwiftNetwork/QUIC/QUICConnection.swift b/Sources/SwiftNetwork/QUIC/QUICConnection.swift index 8d1d300..6378122 100644 --- a/Sources/SwiftNetwork/QUIC/QUICConnection.swift +++ b/Sources/SwiftNetwork/QUIC/QUICConnection.swift @@ -4409,6 +4409,7 @@ public final class QUICConnection: ManyToManyApplicationStreamProtocol, // MARK: Flow Control - Inbound Frame Processing +@available(Network 0.1.0, *) extension QUICConnection { // Process an incoming NEW_TOKEN frame @@ -4829,6 +4830,7 @@ extension QUICConnection { // MARK: Flow Control - Outbound Frame Processing +@available(Network 0.1.0, *) extension QUICConnection { // Prepare and send maxStreamsBidirectional @@ -5086,6 +5088,7 @@ extension QUICConnection { // MARK: Flow Control - Stream +@available(Network 0.1.0, *) extension QUICConnection { func withMutableQUICStreams(unidirectional: Bool, closure: (inout QUICStreamIDState) -> Void) { if unidirectional { @@ -5197,6 +5200,7 @@ extension QUICConnection { // MARK: Inbound stream creation +@available(Network 0.1.0, *) extension QUICConnection { // Support QUICStreamIDState being ~Copyable @@ -5375,6 +5379,7 @@ extension QUICConnection { // MARK: Datagram flow handling +@available(Network 0.1.0, *) extension QUICConnection { // Handle new outbound datagrams being available. public func serviceDatagramsToSend(flow flowID: MultiplexedFlowIdentifier) { @@ -5485,6 +5490,7 @@ extension QUICConnection { // MARK: Frame Processing helpers +@available(Network 0.1.0, *) extension QUICConnection { func processFrame( _ frame: consuming QUICFrame, @@ -5570,6 +5576,7 @@ extension QUICConnection { } // MARK: Frame Acknowledgement helpers +@available(Network 0.1.0, *) extension QUICConnection { func acknowledged( _ packet: borrowing SentPacketRecord, @@ -5685,6 +5692,7 @@ extension QUICConnection { // MARK: Connection Idle / Reuse +@available(Network 0.1.0, *) extension QUICConnection { fileprivate func handleConnectionIdleForFlow(_ flowID: MultiplexedFlowIdentifier) { @@ -5767,6 +5775,7 @@ extension QUICConnection { // MARK: Connection ID Lifecycle +@available(Network 0.1.0, *) extension QUICConnection { public func handleApplicationEvent( @@ -6097,6 +6106,7 @@ extension QUICConnection { // MARK: Path Challenge processing +@available(Network 0.1.0, *) extension QUICConnection { @discardableResult func handlePathChallengeFrame( diff --git a/Sources/SwiftNetwork/QUIC/QUICConnectionID.swift b/Sources/SwiftNetwork/QUIC/QUICConnectionID.swift index 47d5d14..5b18030 100644 --- a/Sources/SwiftNetwork/QUIC/QUICConnectionID.swift +++ b/Sources/SwiftNetwork/QUIC/QUICConnectionID.swift @@ -35,6 +35,7 @@ enum QUICConnectionIDError: Int { @available(Network 0.1.0, *) public typealias QUICConnectionIDStorage = [20 of UInt8] +@available(Network 0.1.0, *) extension QUICConnectionIDStorage { static var empty: QUICConnectionIDStorage { QUICConnectionIDStorage(repeating: 0) @@ -175,6 +176,7 @@ public struct QUICConnectionID: Sendable, Equatable, CustomStringConvertible { } } +@available(Network 0.1.0, *) extension QUICConnectionID: Hashable { public func hash(into hasher: inout Hasher) { hasher.combine(actualLength) @@ -184,6 +186,7 @@ extension QUICConnectionID: Hashable { } } +@available(Network 0.1.0, *) struct ManagedConnectionID { let sequenceNumber: UInt64 let connectionID: QUICConnectionID @@ -220,6 +223,7 @@ struct ManagedConnectionID { } } +@available(Network 0.1.0, *) struct QUICConnectionIDList: Sequence, IteratorProtocol { private(set) var managedConnectionIDs = Deque() @@ -373,6 +377,7 @@ struct QUICConnectionIDList: Sequence, IteratorProtocol { } // In QUIC, connection IDs are always serialized with a prefixed 8 bit length. +@available(Network 0.1.0, *) extension Serializer { func connectionID(_ value: QUICConnectionID) -> Serializable { .buffer([UInt8(value.length)] + value.connectionID) diff --git a/Sources/SwiftNetwork/QUIC/QUICError.swift b/Sources/SwiftNetwork/QUIC/QUICError.swift index e7326b7..2ef898a 100644 --- a/Sources/SwiftNetwork/QUIC/QUICError.swift +++ b/Sources/SwiftNetwork/QUIC/QUICError.swift @@ -247,6 +247,7 @@ extension NetworkError { // More granular error types are not used as embedded swift does not support untyped throws #if !NETWORK_NO_SWIFT_QUIC +@available(Network 0.1.0, *) enum QUICError: Error { case packet(QUICPacketError) case packetBuilder(PacketBuilderError) diff --git a/Sources/SwiftNetwork/QUIC/QUICFrame.swift b/Sources/SwiftNetwork/QUIC/QUICFrame.swift index 2d62888..480931a 100644 --- a/Sources/SwiftNetwork/QUIC/QUICFrame.swift +++ b/Sources/SwiftNetwork/QUIC/QUICFrame.swift @@ -23,6 +23,7 @@ internal import os // MARK: - QUIC Frames +@available(Network 0.1.0, *) enum QUICFrame: ~Copyable { case padding(frame: FramePadding) case ping(frame: FramePing) @@ -328,6 +329,7 @@ enum QUICFrame: ~Copyable { } // MARK: - QUIC Frame Types +@available(Network 0.1.0, *) enum FrameType: RawRepresentable, CaseIterable, Equatable { static let paddingCode: UInt64 = 0x00 static let pingCode: UInt64 = 0x01 @@ -513,6 +515,7 @@ enum FrameType: RawRepresentable, CaseIterable, Equatable { } } +@available(Network 0.1.0, *) extension FrameType { func description() -> String { switch self { @@ -568,6 +571,7 @@ extension FrameType { } } +@available(Network 0.1.0, *) enum FrameParseError: Error { case parsingError case invalidType(UInt64) @@ -585,12 +589,14 @@ enum FrameParseError: Error { } } +@available(Network 0.1.0, *) enum FrameWriteError: Int, Error { case smallBuffer case invalidTypeForSend } // MARK: - QUIC Frame Protocols +@available(Network 0.1.0, *) protocol QUICFrameProtocol: ~Copyable { var type: FrameType { get } @@ -602,11 +608,13 @@ protocol QUICFrameProtocol: ~Copyable { // func write(frame: inout Frame, stats: inout Statistics?) throws(QUICError) } +@available(Network 0.1.0, *) extension QUICFrameProtocol { // Most frames don't do anything when they are acknowledged. func acknowledged() {} } +@available(Network 0.1.0, *) extension QUICFrameProtocol { // Common frame deserialization validation func validateDeserializationResult(_ result: DeserializationResult) throws(QUICError) { @@ -636,6 +644,7 @@ extension QUICFrameProtocol { } } +@available(Network 0.1.0, *) extension QUICFrameProtocol where Self: ~Copyable { // Common frame deserialization validation func validateDeserializationResult(_ result: DeserializationResult) throws(QUICError) { @@ -667,6 +676,7 @@ extension QUICFrameProtocol where Self: ~Copyable { // MARK: - Padding (0x00) +@available(Network 0.1.0, *) struct FramePadding: ~Copyable, QUICFrameProtocol { let type = FrameType.padding @@ -759,6 +769,7 @@ struct FramePadding: ~Copyable, QUICFrameProtocol { } // MARK: Ping (0x01) +@available(Network 0.1.0, *) struct FramePing: ~Copyable, QUICFrameProtocol { let type = FrameType.ping @@ -808,11 +819,13 @@ struct FramePing: ~Copyable, QUICFrameProtocol { // MARK: Ack (0x02-0x03) +@available(Network 0.1.0, *) struct FrameAckRange { var gap: PacketNumber var range: PacketNumber } +@available(Network 0.1.0, *) struct FrameAck: QUICFrameProtocol { var type = FrameType.ack @@ -1013,6 +1026,7 @@ struct FrameAck: QUICFrameProtocol { // MARK: Reset Stream (0x04) +@available(Network 0.1.0, *) struct FrameResetStream: ~Copyable, QUICFrameProtocol { let type = FrameType.resetStream @@ -1181,6 +1195,7 @@ struct FrameResetStream: ~Copyable, QUICFrameProtocol { // MARK: Stop Sending (0x05) +@available(Network 0.1.0, *) struct FrameStopSending: ~Copyable, QUICFrameProtocol { let type = FrameType.stopSending @@ -1311,6 +1326,7 @@ struct FrameStopSending: ~Copyable, QUICFrameProtocol { // MARK: Crypto (0x06) +@available(Network 0.1.0, *) struct FrameCrypto: ~Copyable, QUICFrameProtocol { let type = FrameType.crypto @@ -1552,6 +1568,7 @@ struct FrameCrypto: ~Copyable, QUICFrameProtocol { // MARK: New Token (0x07) +@available(Network 0.1.0, *) struct FrameNewToken: ~Copyable, QUICFrameProtocol { let type = FrameType.newToken @@ -1601,6 +1618,7 @@ struct FrameNewToken: ~Copyable, QUICFrameProtocol { // MARK: Stream (0x08...0x0f) +@available(Network 0.1.0, *) struct FrameStreamFlag: ExpressibleByIntegerLiteral { // The FIN bit (0x01) indicates that the frame marks the end of the stream static let final: UInt64 = 0x01 @@ -1621,6 +1639,7 @@ struct FrameStreamFlag: ExpressibleByIntegerLiteral { } } +@available(Network 0.1.0, *) extension FrameStreamFlag { static func fromCode(_ code: UInt64) -> FrameStreamFlag { let flag = code - FrameType.streamCodes.lowerBound @@ -1643,6 +1662,7 @@ extension FrameStreamFlag { } // Only used for sending (or re-sending) STREAM frames +@available(Network 0.1.0, *) struct FrameStreamSendMetadata: QUICFrameProtocol { let type: FrameType @@ -1842,6 +1862,7 @@ struct FrameStreamSendMetadata: QUICFrameProtocol { } // Only used for receiving STREAM frames +@available(Network 0.1.0, *) struct FrameStreamReceived: ~Copyable, QUICFrameProtocol { var type = FrameType.stream() @@ -1983,6 +2004,7 @@ struct FrameStreamReceived: ~Copyable, QUICFrameProtocol { // MARK: Max Data (0x10) +@available(Network 0.1.0, *) struct FrameMaxData: ~Copyable, QUICFrameProtocol { let type = FrameType.maxData @@ -2026,6 +2048,7 @@ struct FrameMaxData: ~Copyable, QUICFrameProtocol { // MARK: Max Stream Data (0x11) +@available(Network 0.1.0, *) struct FrameMaxStreamData: ~Copyable, QUICFrameProtocol { let type = FrameType.maxStreamData @@ -2073,6 +2096,7 @@ struct FrameMaxStreamData: ~Copyable, QUICFrameProtocol { // MARK: Max Streams Bidirectional (0x12) +@available(Network 0.1.0, *) struct FrameMaxStreamsBidirectional: ~Copyable, QUICFrameProtocol { let type = FrameType.maxStreamsBidirectional @@ -2118,6 +2142,7 @@ struct FrameMaxStreamsBidirectional: ~Copyable, QUICFrameProtocol { // MARK: Max Streams Unidirectional (0x13) +@available(Network 0.1.0, *) struct FrameMaxStreamsUnidirectional: ~Copyable, QUICFrameProtocol { let type = FrameType.maxStreamsUnidirectional @@ -2163,6 +2188,7 @@ struct FrameMaxStreamsUnidirectional: ~Copyable, QUICFrameProtocol { // MARK: Data Blocked (0x14) +@available(Network 0.1.0, *) struct FrameDataBlocked: ~Copyable, QUICFrameProtocol { let type = FrameType.dataBlocked @@ -2211,6 +2237,7 @@ struct FrameDataBlocked: ~Copyable, QUICFrameProtocol { // MARK: Stream Data Blocked (0x15) +@available(Network 0.1.0, *) struct FrameStreamDataBlocked: ~Copyable, QUICFrameProtocol { let type = FrameType.streamDataBlocked @@ -2268,6 +2295,7 @@ struct FrameStreamDataBlocked: ~Copyable, QUICFrameProtocol { // MARK: Streams Blocked Bidirectional (0x16) +@available(Network 0.1.0, *) struct FrameStreamsBlockedBidirectional: ~Copyable, QUICFrameProtocol { let type = FrameType.streamsBlockedBidirectional @@ -2318,6 +2346,7 @@ struct FrameStreamsBlockedBidirectional: ~Copyable, QUICFrameProtocol { // MARK: Streams Blocked Unidirectional (0x17) +@available(Network 0.1.0, *) struct FrameStreamsBlockedUnidirectional: ~Copyable, QUICFrameProtocol { let type = FrameType.streamsBlockedUnidirectional @@ -2368,6 +2397,7 @@ struct FrameStreamsBlockedUnidirectional: ~Copyable, QUICFrameProtocol { // MARK: New Connection ID (0x18) +@available(Network 0.1.0, *) struct FrameNewConnectionID: QUICFrameProtocol { let type = FrameType.newConnectionID private(set) var sequence: UInt64 = 0 @@ -2454,6 +2484,7 @@ struct FrameNewConnectionID: QUICFrameProtocol { // MARK: Retire Connection ID (0x19) +@available(Network 0.1.0, *) struct FrameRetireConnectionID: QUICFrameProtocol { let type = FrameType.retireConnectionID @@ -2497,6 +2528,7 @@ struct FrameRetireConnectionID: QUICFrameProtocol { // MARK: Path Challenge (0x1a) +@available(Network 0.1.0, *) struct FramePathChallenge: QUICFrameProtocol { let type = FrameType.pathChallenge @@ -2547,6 +2579,7 @@ struct FramePathChallenge: QUICFrameProtocol { // MARK: Path Response (0x1b) +@available(Network 0.1.0, *) struct FramePathResponse: QUICFrameProtocol { let type = FrameType.pathResponse @@ -2597,6 +2630,7 @@ struct FramePathResponse: QUICFrameProtocol { // MARK: Connection Close (0x1c) +@available(Network 0.1.0, *) private func updateConnectionCloseStats( errorCode: UInt64, isRx: Bool, @@ -2679,6 +2713,7 @@ private func updateConnectionCloseStats( } } +@available(Network 0.1.0, *) struct FrameConnectionClose: ~Copyable, QUICFrameProtocol { let type = FrameType.connectionClose @@ -2763,6 +2798,7 @@ struct FrameConnectionClose: ~Copyable, QUICFrameProtocol { // MARK: Application Close (0x1d) +@available(Network 0.1.0, *) struct FrameApplicationClose: ~Copyable, QUICFrameProtocol { let type = FrameType.applicationClose @@ -2840,6 +2876,7 @@ struct FrameApplicationClose: ~Copyable, QUICFrameProtocol { // MARK: Handshake Done (0x1e) +@available(Network 0.1.0, *) struct FrameHandshakeDone: ~Copyable, QUICFrameProtocol { let type = FrameType.handshakeDone @@ -2891,6 +2928,7 @@ struct FrameHandshakeDone: ~Copyable, QUICFrameProtocol { // The least significant bit of the Type field in the DATAGRAM frame is the LEN bit (0x01), // which indicates whether there is a Length field present: if this bit is set to 0, // the Length field is absent and the Datagram Data field extends to the end of the packet +@available(Network 0.1.0, *) struct FrameDatagram: ~Copyable, QUICFrameProtocol { var type = FrameType.datagram() diff --git a/Sources/SwiftNetwork/QUIC/QUICPath.swift b/Sources/SwiftNetwork/QUIC/QUICPath.swift index da66fc1..55a4866 100644 --- a/Sources/SwiftNetwork/QUIC/QUICPath.swift +++ b/Sources/SwiftNetwork/QUIC/QUICPath.swift @@ -104,6 +104,7 @@ enum QUICPathState: CustomStringConvertible, CaseIterable { } } +@available(Network 0.1.0, *) struct PendingChallenge { let data = UInt64.random(in: 0.., Equatable } // Congestion Control access +@available(Network 0.1.0, *) extension QUICPath { @inline(__always) var congestionControlWindow: UInt64 { diff --git a/Sources/SwiftNetwork/QUIC/QUICStream.swift b/Sources/SwiftNetwork/QUIC/QUICStream.swift index ee5d45c..cf9a192 100644 --- a/Sources/SwiftNetwork/QUIC/QUICStream.swift +++ b/Sources/SwiftNetwork/QUIC/QUICStream.swift @@ -28,6 +28,7 @@ internal import os // MARK: QUIC StreamID state // Keeps track of the QUICStreamID state for local and remote uni/bidi streams +@available(Network 0.1.0, *) struct QUICStreamIDState: ~Copyable { let logContext: String let streamType: QUICStreamType @@ -322,6 +323,7 @@ struct StreamListMembership: OptionSet { // Note that QUICStreamList only holds the flow identifiers that are used to lookup // the actual streams held in the multiplexedFlows dictionary already. // Also note that a flow identifier can exist in multiple lists at one time. +@available(Network 0.1.0, *) struct QUICStreamList: ~Copyable { private var list: [MultiplexedFlowIdentifier] = [] private let name: StaticString @@ -1131,6 +1133,7 @@ public final class QUICStreamInstance: MultiplexedStreamFlow, // MARK: Utility on Stream +@available(Network 0.1.0, *) extension QUICStreamInstance { static func isValid(isServer: Bool, streamID: QUICStreamID) -> Bool { if !isServer && streamID.isClientInitiated { @@ -1146,6 +1149,7 @@ extension QUICStreamInstance { // MARK: Flow Control - Limits +@available(Network 0.1.0, *) extension QUICStreamInstance { func setupMaxStreamData( diff --git a/Sources/SwiftNetwork/QUIC/QUICStreamID.swift b/Sources/SwiftNetwork/QUIC/QUICStreamID.swift index 2076605..a97696d 100644 --- a/Sources/SwiftNetwork/QUIC/QUICStreamID.swift +++ b/Sources/SwiftNetwork/QUIC/QUICStreamID.swift @@ -34,6 +34,7 @@ enum QUICStreamType: CustomStringConvertible { #if !NETWORK_NO_SWIFT_QUIC // RFC9000 2.1 Stream Types and Identifiers. We use specific type to ensure type // safe operations, instead of extending UInt64 for example. +@available(Network 0.1.0, *) struct QUICStreamID: Comparable, Hashable { // UInt64: A stream ID is a 62-bit integer that is unique for all streams on a connection. private(set) var value: UInt64 @@ -136,6 +137,7 @@ struct QUICStreamID: Comparable, Hashable { // MARK: QUICStreamID computations +@available(Network 0.1.0, *) extension QUICStreamID { static func computeRemoteMaxStreamIDBidirectional( server: Bool, @@ -246,12 +248,14 @@ extension QUICStreamID { } +@available(Network 0.1.0, *) extension QUICStreamID { var variableLengthSize: Int { self.value.variableLengthSize } } +@available(Network 0.1.0, *) extension QUICStreamID { // Returns the next available Stream ID static func nextAvailableStreamID( @@ -290,6 +294,7 @@ extension QUICStreamID { } } +@available(Network 0.1.0, *) extension QUICStreamID: Strideable { func advanced(by n: Int) -> QUICStreamID { QUICStreamID(self.value + UInt64(n))! @@ -300,6 +305,7 @@ extension QUICStreamID: Strideable { } } +@available(Network 0.1.0, *) extension QUICStreamID { static let strideLengthToNextOfSameTypeAndInitiator = 4 // Advance to next stream ID of same type and initiator. @@ -311,6 +317,7 @@ extension QUICStreamID { } } +@available(Network 0.1.0, *) extension QUICStreamID: CustomStringConvertible { var description: String { String(value) diff --git a/Sources/SwiftNetwork/QUIC/QUICStreamState.swift b/Sources/SwiftNetwork/QUIC/QUICStreamState.swift index 723090d..6cbf473 100644 --- a/Sources/SwiftNetwork/QUIC/QUICStreamState.swift +++ b/Sources/SwiftNetwork/QUIC/QUICStreamState.swift @@ -22,6 +22,7 @@ internal import os #endif // Note: This is CaseIterable only so that tests can ensure it checks all states +@available(Network 0.1.0, *) enum QUICSendStreamState: UInt8, CaseIterable, CustomStringConvertible { case invalid case ready @@ -87,6 +88,7 @@ enum QUICSendStreamState: UInt8, CaseIterable, CustomStringConvertible { } // Note: It is CaseIterable only so that tests can ensure it checks all states +@available(Network 0.1.0, *) enum QUICReceiveStreamState: CaseIterable, CustomStringConvertible { case invalid case receive diff --git a/Sources/SwiftNetwork/QUIC/QUICStreamZombies.swift b/Sources/SwiftNetwork/QUIC/QUICStreamZombies.swift index e659f15..633b89f 100644 --- a/Sources/SwiftNetwork/QUIC/QUICStreamZombies.swift +++ b/Sources/SwiftNetwork/QUIC/QUICStreamZombies.swift @@ -28,6 +28,7 @@ internal import os * in the process table waiting for the parent to read its exit code. */ +@available(Network 0.1.0, *) struct QUICStreamZombie { let streamID: QUICStreamID let logIDString: String @@ -91,6 +92,7 @@ struct QUICStreamZombie { } } +@available(Network 0.1.0, *) struct QUICStreamZombieList { private var zombies: [QUICStreamZombie] = [] diff --git a/Sources/SwiftNetwork/QUIC/QUICUtilities.swift b/Sources/SwiftNetwork/QUIC/QUICUtilities.swift index e4503bc..d72834b 100644 --- a/Sources/SwiftNetwork/QUIC/QUICUtilities.swift +++ b/Sources/SwiftNetwork/QUIC/QUICUtilities.swift @@ -21,6 +21,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) extension System { static func isHighMemory() -> Bool { #if NETWORK_EMBEDDED diff --git a/Sources/SwiftNetwork/QUIC/RTT.swift b/Sources/SwiftNetwork/QUIC/RTT.swift index 95aedc8..4282cfb 100644 --- a/Sources/SwiftNetwork/QUIC/RTT.swift +++ b/Sources/SwiftNetwork/QUIC/RTT.swift @@ -21,6 +21,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) struct RTT: ~Copyable, PrefixedLoggable { static let initialRTT: NetworkDuration = .milliseconds(333) static let historyInterval: NetworkDuration = .seconds(60) diff --git a/Sources/SwiftNetwork/QUIC/ReassemblyQueue.swift b/Sources/SwiftNetwork/QUIC/ReassemblyQueue.swift index 56210a3..9657300 100644 --- a/Sources/SwiftNetwork/QUIC/ReassemblyQueue.swift +++ b/Sources/SwiftNetwork/QUIC/ReassemblyQueue.swift @@ -26,6 +26,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) struct ReassemblyQueueItem: ~Copyable { var offset: Int var frame: Frame @@ -40,6 +41,7 @@ struct ReassemblyQueueItem: ~Copyable { static let itemSize = MemoryLayout.size } +@available(Network 0.1.0, *) struct ReassemblyQueue: ~Copyable { var log: NetworkLoggerState #if QUIC_REASSQ_TRACE diff --git a/Sources/SwiftNetwork/QUIC/Recovery.swift b/Sources/SwiftNetwork/QUIC/Recovery.swift index a2eb291..f06bb89 100644 --- a/Sources/SwiftNetwork/QUIC/Recovery.swift +++ b/Sources/SwiftNetwork/QUIC/Recovery.swift @@ -26,6 +26,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) struct PacketContainerEntry: ~Copyable, NetworkComparable { var packet: SentPacketRecord var sentTime: NetworkClock.Instant @@ -45,6 +46,7 @@ struct PacketContainerEntry: ~Copyable, NetworkComparable { } } +@available(Network 0.1.0, *) struct Recovery: ~Copyable, PrefixedLoggable, NonCopyableTimerUser { struct InnerState: ~Copyable, PrefixedLoggable { var log: LogPrefixer diff --git a/Sources/SwiftNetwork/QUIC/SendItems.swift b/Sources/SwiftNetwork/QUIC/SendItems.swift index f476e62..997e910 100644 --- a/Sources/SwiftNetwork/QUIC/SendItems.swift +++ b/Sources/SwiftNetwork/QUIC/SendItems.swift @@ -28,6 +28,7 @@ internal import os // MARK: - Sendable Items (Per-Frame Sending Logic) +@available(Network 0.1.0, *) protocol SendableItem: ~Copyable { static var isAckEliciting: Bool { get } static var isInFlightEligible: Bool { get } @@ -56,6 +57,7 @@ protocol SendableItem: ~Copyable { ) throws(QUICError) } +@available(Network 0.1.0, *) extension SendableItem where Self: ~Copyable { static var isAckEliciting: Bool { true } // Default to true for most frames static var isInFlightEligible: Bool { isAckEliciting } // Default to being the same as ack-eliciting @@ -133,6 +135,7 @@ extension SendableItem where Self: ~Copyable { } } +@available(Network 0.1.0, *) extension FramePadding: SendableItem { static var isAckEliciting: Bool { false } static var isInFlightEligible: Bool { true } @@ -189,6 +192,7 @@ extension FramePadding: SendableItem { } } +@available(Network 0.1.0, *) extension FramePing: SendableItem { static func isPresent(in pendingItems: borrowing PendingItems) -> Bool { pendingItems.ping } @@ -227,6 +231,7 @@ extension FramePing: SendableItem { } } +@available(Network 0.1.0, *) extension FrameAck: SendableItem { static var isAckEliciting: Bool { false } @@ -281,6 +286,7 @@ extension FrameAck: SendableItem { } } +@available(Network 0.1.0, *) extension FrameResetStream: SendableItem { static var isRepeatable: Bool { true } @@ -340,6 +346,7 @@ extension FrameResetStream: SendableItem { } } +@available(Network 0.1.0, *) extension FrameStopSending: SendableItem { static var isRepeatable: Bool { true } @@ -395,6 +402,7 @@ extension FrameStopSending: SendableItem { } } +@available(Network 0.1.0, *) extension FrameCrypto: SendableItem { static var isRepeatable: Bool { true } @@ -551,6 +559,7 @@ extension FrameCrypto: SendableItem { } } +@available(Network 0.1.0, *) extension FrameNewToken: SendableItem { static func isPresent(in pendingItems: borrowing PendingItems) -> Bool { pendingItems.newToken @@ -585,6 +594,7 @@ extension FrameNewToken: SendableItem { } } +@available(Network 0.1.0, *) extension FrameStreamSendMetadata: SendableItem { static var isRepeatable: Bool { true } @@ -863,6 +873,7 @@ extension FrameStreamSendMetadata: SendableItem { } } +@available(Network 0.1.0, *) extension FrameDataBlocked: SendableItem { static func isPresent(in pendingItems: borrowing PendingItems) -> Bool { pendingItems.dataBlocked @@ -897,6 +908,7 @@ extension FrameDataBlocked: SendableItem { } } +@available(Network 0.1.0, *) extension FrameStreamDataBlocked: SendableItem { static var isRepeatable: Bool { true } @@ -953,6 +965,7 @@ extension FrameStreamDataBlocked: SendableItem { } } +@available(Network 0.1.0, *) extension FrameStreamsBlockedBidirectional: SendableItem { static func isPresent(in pendingItems: borrowing PendingItems) -> Bool { pendingItems.streamsBlockedBidirectional @@ -989,6 +1002,7 @@ extension FrameStreamsBlockedBidirectional: SendableItem { } } +@available(Network 0.1.0, *) extension FrameStreamsBlockedUnidirectional: SendableItem { static func isPresent(in pendingItems: borrowing PendingItems) -> Bool { pendingItems.streamsBlockedUnidirectional @@ -1025,6 +1039,7 @@ extension FrameStreamsBlockedUnidirectional: SendableItem { } } +@available(Network 0.1.0, *) extension FrameMaxData: SendableItem { static func isPresent(in pendingItems: borrowing PendingItems) -> Bool { pendingItems.maxData } @@ -1057,6 +1072,7 @@ extension FrameMaxData: SendableItem { } } +@available(Network 0.1.0, *) extension FrameMaxStreamData: SendableItem { static var isRepeatable: Bool { true } @@ -1115,6 +1131,7 @@ extension FrameMaxStreamData: SendableItem { } } +@available(Network 0.1.0, *) extension FrameMaxStreamsBidirectional: SendableItem { static func isPresent(in pendingItems: borrowing PendingItems) -> Bool { pendingItems.maxStreamsBidirectional @@ -1152,6 +1169,7 @@ extension FrameMaxStreamsBidirectional: SendableItem { } } +@available(Network 0.1.0, *) extension FrameMaxStreamsUnidirectional: SendableItem { static func isPresent(in pendingItems: borrowing PendingItems) -> Bool { pendingItems.maxStreamsUnidirectional @@ -1191,6 +1209,7 @@ extension FrameMaxStreamsUnidirectional: SendableItem { } } +@available(Network 0.1.0, *) extension FrameNewConnectionID: SendableItem { static var isRepeatable: Bool { true } @@ -1245,6 +1264,7 @@ extension FrameNewConnectionID: SendableItem { } } +@available(Network 0.1.0, *) extension FrameRetireConnectionID: SendableItem { static var isRepeatable: Bool { true } @@ -1293,6 +1313,7 @@ extension FrameRetireConnectionID: SendableItem { } } +@available(Network 0.1.0, *) extension FramePathChallenge: SendableItem { static func isPresent(in pendingItems: borrowing PendingItems) -> Bool { #if DEBUG @@ -1332,6 +1353,7 @@ extension FramePathChallenge: SendableItem { } } +@available(Network 0.1.0, *) extension FramePathResponse: SendableItem { static func isPresent(in pendingItems: borrowing PendingItems) -> Bool { #if DEBUG @@ -1372,6 +1394,7 @@ extension FramePathResponse: SendableItem { } } +@available(Network 0.1.0, *) extension FrameConnectionClose: SendableItem { static var isAckEliciting: Bool { false } @@ -1423,6 +1446,7 @@ extension FrameConnectionClose: SendableItem { } } +@available(Network 0.1.0, *) extension FrameApplicationClose: SendableItem { static var isAckEliciting: Bool { false } @@ -1482,6 +1506,7 @@ extension FrameApplicationClose: SendableItem { } } +@available(Network 0.1.0, *) extension FrameHandshakeDone: SendableItem { static func isPresent(in pendingItems: borrowing PendingItems) -> Bool { pendingItems.handshakeDone @@ -1515,6 +1540,7 @@ extension FrameHandshakeDone: SendableItem { } } +@available(Network 0.1.0, *) extension FrameDatagram: SendableItem { static var isRepeatable: Bool { true } @@ -1611,6 +1637,7 @@ extension FrameDatagram: SendableItem { // This list the priority order in which to send frames // Note: This list may be updated after review +@available(Network 0.1.0, *) enum PrioritizedSendableItems: CaseIterable { // Control frames come first so that they fit in the earliest outgoing frame case crypto @@ -2177,6 +2204,7 @@ enum PrioritizedSendableItems: CaseIterable { // MARK: - PendingItems (State for pending send) +@available(Network 0.1.0, *) struct SimpleSendableItemsFlags: OptionSet { init(rawValue: Self.RawValue) { self.rawValue = rawValue @@ -2208,6 +2236,7 @@ struct SimpleSendableItemsFlags: OptionSet { static let sendCrypto = SimpleSendableItemsFlags(rawValue: 1 << 24) } +@available(Network 0.1.0, *) struct PendingItems: ~Copyable { let packetNumberSpace: PacketNumberSpace @@ -2808,6 +2837,7 @@ struct PendingItems: ~Copyable { // MARK: - TransmittedItems (State for previous send) +@available(Network 0.1.0, *) struct TransmittedItems: ~Copyable { var simpleSendableItems = SimpleSendableItemsFlags(rawValue: 0) var ping: Bool { diff --git a/Sources/SwiftNetwork/QUIC/Shorthand.swift b/Sources/SwiftNetwork/QUIC/Shorthand.swift index e300643..4764748 100644 --- a/Sources/SwiftNetwork/QUIC/Shorthand.swift +++ b/Sources/SwiftNetwork/QUIC/Shorthand.swift @@ -21,6 +21,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) enum QUICShorthandFrame: CustomStringConvertible { case padding(_ entry: ShorthandFramePadding) case ping(_ entry: ShorthandFrameGeneric) @@ -95,6 +96,7 @@ enum QUICShorthandFrame: CustomStringConvertible { } } +@available(Network 0.1.0, *) protocol ShorthandLogEntry: CustomStringConvertible { var outgoing: Bool { get } } diff --git a/Sources/SwiftNetwork/QUIC/ShorthandFrame.swift b/Sources/SwiftNetwork/QUIC/ShorthandFrame.swift index c751df8..7a89767 100644 --- a/Sources/SwiftNetwork/QUIC/ShorthandFrame.swift +++ b/Sources/SwiftNetwork/QUIC/ShorthandFrame.swift @@ -15,6 +15,7 @@ #if !NETWORK_NO_SWIFT_QUIC // MARK: PADDING +@available(Network 0.1.0, *) extension FramePadding { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.padding(ShorthandFramePadding(outgoing: outgoing, frame: self)) @@ -24,6 +25,7 @@ extension FramePadding { } } +@available(Network 0.1.0, *) struct ShorthandFramePadding: ShorthandLogEntry { var outgoing: Bool let type = FrameType.padding @@ -51,6 +53,7 @@ struct ShorthandFramePadding: ShorthandLogEntry { } // MARK: RESET_STREAM +@available(Network 0.1.0, *) extension FrameResetStream { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.resetStream( @@ -74,6 +77,7 @@ extension FrameResetStream { } } +@available(Network 0.1.0, *) struct ShorthandFrameResetStream: ShorthandLogEntry { let outgoing: Bool let type = FrameType.resetStream @@ -102,6 +106,7 @@ struct ShorthandFrameResetStream: ShorthandLogEntry { } // MARK: STOP_SENDING +@available(Network 0.1.0, *) extension FrameStopSending { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.stopSending( @@ -119,6 +124,7 @@ extension FrameStopSending { } } +@available(Network 0.1.0, *) struct ShorthandFrameStopSending: ShorthandLogEntry { let outgoing: Bool let type = FrameType.stopSending @@ -143,6 +149,7 @@ struct ShorthandFrameStopSending: ShorthandLogEntry { } // MARK: CRYPTO +@available(Network 0.1.0, *) extension FrameCrypto { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.crypto(ShorthandFrameCrypto(outgoing: outgoing, frame: self)) @@ -158,6 +165,7 @@ extension FrameCrypto { } } +@available(Network 0.1.0, *) struct ShorthandFrameCrypto: ShorthandLogEntry { let type = FrameType.crypto let outgoing: Bool @@ -182,6 +190,7 @@ struct ShorthandFrameCrypto: ShorthandLogEntry { } } +@available(Network 0.1.0, *) extension FrameAck { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.ack(ShorthandFrameAck(outgoing: outgoing, frame: self)) @@ -205,6 +214,7 @@ extension FrameAck { } } +@available(Network 0.1.0, *) struct ShorthandFrameAck: ShorthandLogEntry { let type: FrameType let delay: UInt64 @@ -273,6 +283,7 @@ struct ShorthandFrameAck: ShorthandLogEntry { } // MARK: MAX_DATA +@available(Network 0.1.0, *) extension FrameMaxData { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.maxData(ShorthandFrameMaxData(outgoing: outgoing, frame: self)) @@ -282,6 +293,7 @@ extension FrameMaxData { } } +@available(Network 0.1.0, *) struct ShorthandFrameMaxData: ShorthandLogEntry { var outgoing: Bool var type = FrameType.maxData @@ -303,6 +315,7 @@ struct ShorthandFrameMaxData: ShorthandLogEntry { } // MARK: MAX_STREAM_DATA +@available(Network 0.1.0, *) extension FrameMaxStreamData { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.maxStreamData( @@ -320,6 +333,7 @@ extension FrameMaxStreamData { } } +@available(Network 0.1.0, *) struct ShorthandFrameMaxStreamData: ShorthandLogEntry { var type = FrameType.maxStreamData var outgoing: Bool @@ -345,6 +359,7 @@ struct ShorthandFrameMaxStreamData: ShorthandLogEntry { } // MARK: MAX_STREAMS_BIDI +@available(Network 0.1.0, *) extension FrameMaxStreamsBidirectional { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.maxStreamsBidirectional( @@ -358,6 +373,7 @@ extension FrameMaxStreamsBidirectional { } } +@available(Network 0.1.0, *) struct ShorthandFrameMaxStreamsBidirectional: ShorthandLogEntry { let type = FrameType.maxStreamsBidirectional let outgoing: Bool @@ -379,6 +395,7 @@ struct ShorthandFrameMaxStreamsBidirectional: ShorthandLogEntry { } // MARK: MAX_STREAMS_UNI +@available(Network 0.1.0, *) extension FrameMaxStreamsUnidirectional { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.maxStreamsUnidirectional( @@ -392,6 +409,7 @@ extension FrameMaxStreamsUnidirectional { } } +@available(Network 0.1.0, *) struct ShorthandFrameMaxStreamsUnidirectional: ShorthandLogEntry { let outgoing: Bool let type = FrameType.maxStreamsUnidirectional @@ -413,6 +431,7 @@ struct ShorthandFrameMaxStreamsUnidirectional: ShorthandLogEntry { } // MARK: DATA_BLOCKED +@available(Network 0.1.0, *) extension FrameDataBlocked { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.dataBlocked( @@ -426,6 +445,7 @@ extension FrameDataBlocked { } } +@available(Network 0.1.0, *) struct ShorthandFrameDataBlocked: ShorthandLogEntry { let outgoing: Bool let type = FrameType.dataBlocked @@ -447,6 +467,7 @@ struct ShorthandFrameDataBlocked: ShorthandLogEntry { } // MARK: STREAM_DATA_BLOCKED +@available(Network 0.1.0, *) extension FrameStreamDataBlocked { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.streamDataBlocked( @@ -464,6 +485,7 @@ extension FrameStreamDataBlocked { } } +@available(Network 0.1.0, *) struct ShorthandFrameStreamDataBlocked: ShorthandLogEntry { let outgoing: Bool let type = FrameType.streamDataBlocked @@ -488,6 +510,7 @@ struct ShorthandFrameStreamDataBlocked: ShorthandLogEntry { } // MARK: STREAMS_BLOCKED_BIDI +@available(Network 0.1.0, *) extension FrameStreamsBlockedBidirectional { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.streamsBlockedBidirectional( @@ -501,6 +524,7 @@ extension FrameStreamsBlockedBidirectional { } } +@available(Network 0.1.0, *) struct ShorthandFrameStreamsBlockedBidirectional: ShorthandLogEntry { let outgoing: Bool let type = FrameType.streamsBlockedBidirectional @@ -522,6 +546,7 @@ struct ShorthandFrameStreamsBlockedBidirectional: ShorthandLogEntry { } // MARK: STREAMS_BLOCKED_UNI +@available(Network 0.1.0, *) extension FrameStreamsBlockedUnidirectional { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.streamsBlockedUnidirectional( @@ -535,6 +560,7 @@ extension FrameStreamsBlockedUnidirectional { } } +@available(Network 0.1.0, *) struct ShorthandFrameStreamsBlockedUnidirectional: ShorthandLogEntry { let outgoing: Bool let type = FrameType.streamsBlockedUnidirectional @@ -555,6 +581,7 @@ struct ShorthandFrameStreamsBlockedUnidirectional: ShorthandLogEntry { } } +@available(Network 0.1.0, *) extension FrameNewConnectionID { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.newConnectionID( @@ -578,6 +605,7 @@ extension FrameNewConnectionID { } } +@available(Network 0.1.0, *) struct ShorthandFrameNewConnectionID: ShorthandLogEntry { let outgoing: Bool let type = FrameType.newConnectionID @@ -610,6 +638,7 @@ struct ShorthandFrameNewConnectionID: ShorthandLogEntry { } // MARK: RETIRE_CONNECTION_ID +@available(Network 0.1.0, *) extension FrameRetireConnectionID { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.retireConnectionID( @@ -623,6 +652,7 @@ extension FrameRetireConnectionID { } } +@available(Network 0.1.0, *) struct ShorthandFrameRetireConnectionID: ShorthandLogEntry { let outgoing: Bool let type = FrameType.retireConnectionID @@ -644,6 +674,7 @@ struct ShorthandFrameRetireConnectionID: ShorthandLogEntry { } // MARK: CONNECTION_CLOSE +@available(Network 0.1.0, *) extension FrameConnectionClose { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.connectionClose( @@ -667,6 +698,7 @@ extension FrameConnectionClose { } } +@available(Network 0.1.0, *) struct ShorthandFrameConnectionClose: ShorthandLogEntry { let outgoing: Bool let errorCode: UInt64 @@ -698,6 +730,7 @@ struct ShorthandFrameConnectionClose: ShorthandLogEntry { } // MARK: APPLICATION_CLOSE +@available(Network 0.1.0, *) extension FrameApplicationClose { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.applicationClose( @@ -715,6 +748,7 @@ extension FrameApplicationClose { } } +@available(Network 0.1.0, *) struct ShorthandFrameApplicationClose: ShorthandLogEntry { let outgoing: Bool let errorCode: UInt64 @@ -740,6 +774,7 @@ struct ShorthandFrameApplicationClose: ShorthandLogEntry { // MARK: DATAGRAM // MARK: DATAGRAM_LEN +@available(Network 0.1.0, *) extension FrameDatagram { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.datagram(ShorthandFrameDatagram(outgoing: outgoing, frame: self)) @@ -755,6 +790,7 @@ extension FrameDatagram { } } +@available(Network 0.1.0, *) struct ShorthandFrameDatagram: ShorthandLogEntry { let outgoing: Bool let type: FrameType @@ -786,6 +822,7 @@ struct ShorthandFrameDatagram: ShorthandLogEntry { //STREAM_FIRST, ..., STREAM_LAST: // MARK: STREAM +@available(Network 0.1.0, *) extension FrameStreamReceived { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { precondition(!outgoing) @@ -793,6 +830,7 @@ extension FrameStreamReceived { } } +@available(Network 0.1.0, *) extension FrameStreamSendMetadata { static func toShorthandLogEntry( outgoing: Bool = true, @@ -814,6 +852,7 @@ extension FrameStreamSendMetadata { } } +@available(Network 0.1.0, *) struct ShorthandFrameStream: ShorthandLogEntry { let outgoing: Bool let type: FrameType @@ -856,6 +895,7 @@ struct ShorthandFrameStream: ShorthandLogEntry { // The following shorthand types are logged only as their frame type.description. // Emit all as ShorthandFrameGeneric() entries. // MARK: HANDSHAKE_DONE +@available(Network 0.1.0, *) extension FrameHandshakeDone { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.handshakeDone( @@ -869,6 +909,7 @@ extension FrameHandshakeDone { } } // MARK: PING +@available(Network 0.1.0, *) extension FramePing { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.ping(ShorthandFrameGeneric(outgoing: outgoing, type: type)) @@ -881,6 +922,7 @@ extension FramePing { } // MARK: NEW_TOKEN +@available(Network 0.1.0, *) extension FrameNewToken { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.newToken(ShorthandFrameNewToken(outgoing: outgoing, frame: self)) @@ -892,6 +934,7 @@ extension FrameNewToken { } } +@available(Network 0.1.0, *) struct ShorthandFrameNewToken: ShorthandLogEntry { let outgoing: Bool let length: Int @@ -913,6 +956,7 @@ struct ShorthandFrameNewToken: ShorthandLogEntry { } // MARK: PATH_CHALLENGE +@available(Network 0.1.0, *) extension FramePathChallenge { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.pathChallenge( @@ -927,6 +971,7 @@ extension FramePathChallenge { } // MARK: PATH_RESPONSE +@available(Network 0.1.0, *) extension FramePathResponse { func toShorthandLogEntry(outgoing: Bool) -> QUICShorthandFrame { QUICShorthandFrame.pathResponse( @@ -940,6 +985,7 @@ extension FramePathResponse { } } +@available(Network 0.1.0, *) struct ShorthandFrameGeneric: ShorthandLogEntry { let outgoing: Bool private(set) var type: FrameType diff --git a/Sources/SwiftNetwork/QUIC/ShorthandPacket.swift b/Sources/SwiftNetwork/QUIC/ShorthandPacket.swift index b95c4a6..97e274f 100644 --- a/Sources/SwiftNetwork/QUIC/ShorthandPacket.swift +++ b/Sources/SwiftNetwork/QUIC/ShorthandPacket.swift @@ -14,6 +14,7 @@ #if !NETWORK_NO_SWIFT_QUIC +@available(Network 0.1.0, *) struct ShorthandPacket: ShorthandLogEntry { let delta: NetworkDuration let keyState: PacketKeyState? diff --git a/Sources/SwiftNetwork/QUIC/Signpost.swift b/Sources/SwiftNetwork/QUIC/Signpost.swift index 832aa04..954d14a 100644 --- a/Sources/SwiftNetwork/QUIC/Signpost.swift +++ b/Sources/SwiftNetwork/QUIC/Signpost.swift @@ -23,6 +23,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) struct QUICSignpost { typealias IntervalState = OSSignpostIntervalState private static let signposter = OSSignposter(logger: Logger.proto) @@ -114,6 +115,7 @@ struct QUICSignpost { } #else // Signposts are not enabled unless the `SignpostOutput` package trait is enabled. +@available(Network 0.1.0, *) struct QUICSignpost { typealias IntervalState = Int static func makeSignpostID() -> Int { 0 } diff --git a/Sources/SwiftNetwork/QUIC/StatelessResetToken.swift b/Sources/SwiftNetwork/QUIC/StatelessResetToken.swift index aa5d6d0..786d39e 100644 --- a/Sources/SwiftNetwork/QUIC/StatelessResetToken.swift +++ b/Sources/SwiftNetwork/QUIC/StatelessResetToken.swift @@ -91,6 +91,7 @@ public struct QUICStatelessResetToken: Equatable, Sendable, CustomStringConverti } } +@available(Network 0.1.0, *) extension QUICStatelessResetToken.TokenStorage { fileprivate static var emptyToken: QUICStatelessResetToken.TokenStorage { QUICStatelessResetToken.TokenStorage(repeating: 0) diff --git a/Sources/SwiftNetwork/QUIC/Statistics.swift b/Sources/SwiftNetwork/QUIC/Statistics.swift index 88c458d..c3ab50b 100644 --- a/Sources/SwiftNetwork/QUIC/Statistics.swift +++ b/Sources/SwiftNetwork/QUIC/Statistics.swift @@ -21,6 +21,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) enum QUICStatistic: Int, CaseIterable { case connectionAttempts case connectionsEstablished @@ -138,6 +139,7 @@ enum QUICStatistic: Int, CaseIterable { case txDepartureTimestamp } +@available(Network 0.1.0, *) struct Statistics: ~Copyable { private var statisticsArray: [96 of Int] diff --git a/Sources/SwiftNetwork/QUIC/StreamSendBuffer.swift b/Sources/SwiftNetwork/QUIC/StreamSendBuffer.swift index a690804..e1c4f94 100644 --- a/Sources/SwiftNetwork/QUIC/StreamSendBuffer.swift +++ b/Sources/SwiftNetwork/QUIC/StreamSendBuffer.swift @@ -24,6 +24,7 @@ internal import os typealias StreamOffset = UInt64 typealias StreamLength = UInt64 +@available(Network 0.1.0, *) struct StreamSendBuffer: ~Copyable { private var storage = FrameArrayQueue() private(set) var storageStartOffset: StreamOffset = 0 @@ -241,6 +242,7 @@ struct StreamSendBuffer: ~Copyable { } // Special case of frame array that keeps track of the total unclaimed length +@available(Network 0.1.0, *) struct FrameArrayQueue: ~Copyable { private var frames = FrameArray() private var cachedUnclaimedLength = 0 diff --git a/Sources/SwiftNetwork/QUIC/Timer.swift b/Sources/SwiftNetwork/QUIC/Timer.swift index e89b237..a1aef05 100644 --- a/Sources/SwiftNetwork/QUIC/Timer.swift +++ b/Sources/SwiftNetwork/QUIC/Timer.swift @@ -26,16 +26,19 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) protocol TimerUser { var timerID: Timer.TimerID? { get set } func timerFired(timeNow: NetworkClock.Instant) } +@available(Network 0.1.0, *) protocol NonCopyableTimerUser: ~Copyable { var timerID: Timer.TimerID? { get set } mutating func timerFired(timeNow: NetworkClock.Instant) } +@available(Network 0.1.0, *) private struct TimerEntry: ~Copyable { let identifier: Timer.TimerID var deadline: NetworkClock.Instant = .zero @@ -60,6 +63,7 @@ private struct TimerEntry: ~Copyable { } // TODO: convert timer to ~Copyable +@available(Network 0.1.0, *) final class Timer: PrefixedLoggable { typealias TimerID = UInt8 diff --git a/Sources/SwiftNetwork/QUIC/TransportParameters.swift b/Sources/SwiftNetwork/QUIC/TransportParameters.swift index e3a1301..9b9a1b2 100644 --- a/Sources/SwiftNetwork/QUIC/TransportParameters.swift +++ b/Sources/SwiftNetwork/QUIC/TransportParameters.swift @@ -58,6 +58,7 @@ enum TransportParameterEncodeErrors: Int, Error { case invalidValue } +@available(Network 0.1.0, *) enum TransportParameter: Equatable { case originalDCID( _ type: TransportParameterTypes = .originalDCID, diff --git a/Sources/SwiftNetwork/System/Darwin/DarwinInterface.swift b/Sources/SwiftNetwork/System/Darwin/DarwinInterface.swift index 4033600..8b160d1 100644 --- a/Sources/SwiftNetwork/System/Darwin/DarwinInterface.swift +++ b/Sources/SwiftNetwork/System/Darwin/DarwinInterface.swift @@ -20,6 +20,7 @@ import Darwin #endif /// A set of Darwin system APIs for interacting with the system interface. +@available(Network 0.1.0, *) internal enum SystemInterface { enum Constants { diff --git a/Sources/SwiftNetwork/System/Darwin/DarwinRoute.swift b/Sources/SwiftNetwork/System/Darwin/DarwinRoute.swift index 94b00cb..8e0f5f6 100644 --- a/Sources/SwiftNetwork/System/Darwin/DarwinRoute.swift +++ b/Sources/SwiftNetwork/System/Darwin/DarwinRoute.swift @@ -58,6 +58,7 @@ public let RTA_DST: Int32 = 0x1 public let RTF_IFSCOPE: Int32 = 0x1000000 /// A set of Darwin system APIs for interacting with the system interface. +@available(Network 0.1.0, *) internal enum SystemRoute { static func routeGetInterfaceIndex(dst: any IPAddress, scopedIndex: UInt32 = 0) throws -> UInt32 { diff --git a/Sources/SwiftNetwork/System/NetworkError.swift b/Sources/SwiftNetwork/System/NetworkError.swift index f6bd918..7764ad4 100644 --- a/Sources/SwiftNetwork/System/NetworkError.swift +++ b/Sources/SwiftNetwork/System/NetworkError.swift @@ -30,7 +30,6 @@ internal import os /// /// See `NetworkPOSIXError` and `HTTP2Error` as two examples of `NetworkDomainSpecificError`. @_spi(ProtocolProvider) -@available(Network 0.1.0, *) public protocol NetworkDomainSpecificError: Error, Sendable, CustomStringConvertible { static var domain: NetworkError.Domain { get } var code: Int64 { get } @@ -49,7 +48,6 @@ public protocol NetworkDomainSpecificError: Error, Sendable, CustomStringConvert /// emit an error that protocols can translate into different error codes — for example, /// HTTP/2 `ENHANCE_YOUR_CALM` versus `H3_EXCESSIVE_LOAD`. @_spi(ProtocolProvider) -@available(Network 0.1.0, *) public struct NetworkError: Error, Sendable, Hashable, CustomStringConvertible { private let domain: Domain? private let code: Int64? @@ -137,7 +135,6 @@ extension NetworkError.CommonCategory: Codable {} #endif @_spi(ProtocolProvider) -@available(Network 0.1.0, *) public struct NetworkPOSIXError: NetworkDomainSpecificError { public static var domain: NetworkError.Domain { .init(rawValue: "POSIX") } diff --git a/Sources/SwiftNetwork/System/System.swift b/Sources/SwiftNetwork/System/System.swift index a048b60..c65d7ff 100644 --- a/Sources/SwiftNetwork/System/System.swift +++ b/Sources/SwiftNetwork/System/System.swift @@ -29,6 +29,7 @@ internal import DriverKitRuntime.Mach.mach_time #endif #endif +@available(Network 0.1.0, *) internal struct System { struct Time { diff --git a/Sources/SwiftNetwork/System/SystemCalls.swift b/Sources/SwiftNetwork/System/SystemCalls.swift index 244c1dc..33bdec6 100644 --- a/Sources/SwiftNetwork/System/SystemCalls.swift +++ b/Sources/SwiftNetwork/System/SystemCalls.swift @@ -73,6 +73,7 @@ extension IOResult where T: FixedWidthInteger { } } +@available(Network 0.1.0, *) extension System { #if !NETWORK_STANDALONE || NETWORK_DRIVERKIT diff --git a/Sources/SwiftNetwork/System/SystemInterface.swift b/Sources/SwiftNetwork/System/SystemInterface.swift index e456191..4d8ff8a 100644 --- a/Sources/SwiftNetwork/System/SystemInterface.swift +++ b/Sources/SwiftNetwork/System/SystemInterface.swift @@ -27,6 +27,7 @@ internal import errno_h /// An extension that adds system-interface APIs. /// /// Extends `System` with system-interface functions. +@available(Network 0.1.0, *) extension System { static func interfaceGetMTU(socket: Int32, name: String) throws -> Int { diff --git a/Sources/SwiftNetwork/System/SystemResources.swift b/Sources/SwiftNetwork/System/SystemResources.swift index f71a5b8..a5cc09a 100644 --- a/Sources/SwiftNetwork/System/SystemResources.swift +++ b/Sources/SwiftNetwork/System/SystemResources.swift @@ -15,6 +15,7 @@ /// An extension that adds system-resource APIs. /// /// Extends `System` with system-resource functions. +@available(Network 0.1.0, *) extension System { /// Returns the file-descriptor limit, if available. diff --git a/Sources/SwiftNetwork/System/SystemSocket.swift b/Sources/SwiftNetwork/System/SystemSocket.swift index 942344c..2c70a79 100644 --- a/Sources/SwiftNetwork/System/SystemSocket.swift +++ b/Sources/SwiftNetwork/System/SystemSocket.swift @@ -52,6 +52,7 @@ enum SocketType: CUnsignedInt, Sendable { } /// A type that creates a cross-platform socket. +@available(Network 0.1.0, *) class SystemSocket { /// Socket file descriptor @@ -246,6 +247,7 @@ class SystemSocket { } #if !NETWORK_PRIVATE && !NETWORK_STANDALONE +@available(Network 0.1.0, *) extension IPAddress { func withSockAddr(_ body: (UnsafePointer, Int) throws -> T) throws(NetworkError) -> T { try self.withSockAddr(port: 0, body) diff --git a/Sources/SwiftNetwork/System/SystemUUID.swift b/Sources/SwiftNetwork/System/SystemUUID.swift index 24af256..634aab3 100644 --- a/Sources/SwiftNetwork/System/SystemUUID.swift +++ b/Sources/SwiftNetwork/System/SystemUUID.swift @@ -125,6 +125,7 @@ public struct SystemUUID: Hashable, Equatable, CustomStringConvertible, Sendable } } +@available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) extension UInt128 { static var randomUUIDValue: UInt128 { let random = UInt128.random(in: 1...UInt128.max) @@ -144,6 +145,7 @@ extension UInt128 { } #if !NETWORK_STANDALONE +@available(Network 0.1.0, *) extension SystemUUID: Codable { public func encode(to encoder: any Encoder) throws { var container = encoder.singleValueContainer() diff --git a/Sources/SwiftNetwork/Utilities/CryptoWrappers.swift b/Sources/SwiftNetwork/Utilities/CryptoWrappers.swift index 47e03b1..88e95cd 100644 --- a/Sources/SwiftNetwork/Utilities/CryptoWrappers.swift +++ b/Sources/SwiftNetwork/Utilities/CryptoWrappers.swift @@ -28,6 +28,7 @@ internal import CryptoKit @preconcurrency internal import Crypto #endif +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) extension SymmetricKey { var bytes: RawSpan { @_lifetime(self) @@ -40,6 +41,7 @@ extension SymmetricKey { } } +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) extension AES.GCM.Nonce { init(copying bytes: RawSpan) throws(CryptoKitMetaError) { self = try bytes.withUnsafeBytes { nonceBuffer throws(CryptoKitMetaError) in @@ -48,6 +50,7 @@ extension AES.GCM.Nonce { } } +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) extension AES.GCM { static func seal( inPlace message: inout MutableRawSpan, @@ -116,6 +119,7 @@ extension AES.GCM { } } +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) extension ChaChaPoly.Nonce { init(copying bytes: RawSpan) throws(CryptoKitMetaError) { self = try bytes.withUnsafeBytes { nonceBuffer throws(CryptoKitMetaError) in @@ -124,6 +128,7 @@ extension ChaChaPoly.Nonce { } } +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) extension ChaChaPoly { static func seal( inPlace message: inout MutableRawSpan, diff --git a/Sources/SwiftNetwork/Utilities/Logging.swift b/Sources/SwiftNetwork/Utilities/Logging.swift index 54087a0..8a82b37 100644 --- a/Sources/SwiftNetwork/Utilities/Logging.swift +++ b/Sources/SwiftNetwork/Utilities/Logging.swift @@ -19,6 +19,7 @@ internal import Logging internal import os #endif +#if os(Linux) || (NETWORK_EMBEDDED && !NETWORK_DRIVERKIT) extension Logger { #if DisableDebugLogging @@ -34,7 +35,6 @@ extension Logger { #endif #endif - #if os(Linux) || (NETWORK_EMBEDDED && !NETWORK_DRIVERKIT) static let interface = Logger(label: "com.apple.network.interface") static let system = Logger(label: "com.apple.network.system") static let proto = Logger(label: "com.apple.network.protocol") @@ -50,8 +50,26 @@ extension Logger { Logger.system.critical("\(message)") } #endif +} +#endif + +#if canImport(os) || NETWORK_DRIVERKIT +@available(macOS 11, iOS 14, tvOS 14, watchOS 7, *) +extension Logger { + + #if DisableDebugLogging + // Specify the `DisableDebugLogging` trait to compile out info, debug, and datapath logging. + static let swiftNetworkProtocolLoggingEnabled: Bool = false + static let swiftNetworkDatapathLoggingEnabled: Bool = false + #else + static let swiftNetworkProtocolLoggingEnabled: Bool = true + #if DatapathLogging + static let swiftNetworkDatapathLoggingEnabled: Bool = true #else - #if canImport(os) || NETWORK_DRIVERKIT + static let swiftNetworkDatapathLoggingEnabled: Bool = false + #endif + #endif + static let system = Logger(subsystem: "com.apple.network", category: "system") static let interface = Logger(subsystem: "com.apple.network", category: "interface") static let proto = Logger(subsystem: "com.apple.network", category: "protocol") @@ -62,6 +80,5 @@ extension Logger { static let listener = Logger(subsystem: "com.apple.network", category: "listener") static let tls = Logger(subsystem: "com.apple.security.swifttls", category: "SwiftTLSProtocol") static let migration = Logger(subsystem: "com.apple.network", category: "migration") - #endif - #endif } +#endif diff --git a/Sources/SwiftNetwork/Utilities/NetworkGappyArray.swift b/Sources/SwiftNetwork/Utilities/NetworkGappyArray.swift index a62d6ba..c223811 100644 --- a/Sources/SwiftNetwork/Utilities/NetworkGappyArray.swift +++ b/Sources/SwiftNetwork/Utilities/NetworkGappyArray.swift @@ -19,6 +19,7 @@ internal import DequeModule // This index is used to refer to a location (as in NetworkGappyArray) without // exposing numeric properties +@available(Network 0.1.0, *) struct NetworkStateIndex: Hashable { fileprivate let index: Int fileprivate init(index: Int) { @@ -35,6 +36,7 @@ struct NetworkStateIndex: Hashable { // This type does not convey any particular order, but is used to be a condensed // way of holding elements that have fast lookup. This is similar to how // interface indices (if_index) is used in kernel networking stacks. +@available(Network 0.1.0, *) struct NetworkGappyArray: ~Copyable { // Array of elements, which may have gaps diff --git a/Sources/SwiftNetwork/Utilities/NetworkHeap.swift b/Sources/SwiftNetwork/Utilities/NetworkHeap.swift index dcce7eb..971a34d 100644 --- a/Sources/SwiftNetwork/Utilities/NetworkHeap.swift +++ b/Sources/SwiftNetwork/Utilities/NetworkHeap.swift @@ -17,6 +17,7 @@ import BasicContainers internal import DequeModule #endif +@available(Network 0.1.0, *) internal struct NetworkHeap: ~Copyable { internal var storage: NetworkUniqueArray @@ -151,6 +152,7 @@ internal struct NetworkHeap: ~Copyable { } } +@available(Network 0.1.0, *) extension NetworkHeap where Element: ~Copyable { var startIndex: Int { self.storage.startIndex @@ -187,9 +189,11 @@ extension NetworkHeap where Element: ~Copyable { } } +@available(Network 0.1.0, *) extension NetworkHeap { func copy() -> NetworkHeap { NetworkHeap(self.storage.clone()) } } +@available(Network 0.1.0, *) extension NetworkHeap: Sendable where Element: Sendable & ~Copyable {} diff --git a/Sources/SwiftNetwork/Utilities/NetworkMutex.swift b/Sources/SwiftNetwork/Utilities/NetworkMutex.swift index 76700b4..3442851 100644 --- a/Sources/SwiftNetwork/Utilities/NetworkMutex.swift +++ b/Sources/SwiftNetwork/Utilities/NetworkMutex.swift @@ -16,6 +16,7 @@ internal import Synchronization +@available(Network 0.1.0, *) typealias NetworkMutex = Mutex #endif diff --git a/Sources/SwiftNetwork/Utilities/NetworkPriorityQueue.swift b/Sources/SwiftNetwork/Utilities/NetworkPriorityQueue.swift index 177ca64..d2a2a38 100644 --- a/Sources/SwiftNetwork/Utilities/NetworkPriorityQueue.swift +++ b/Sources/SwiftNetwork/Utilities/NetworkPriorityQueue.swift @@ -17,12 +17,14 @@ import BasicContainers internal import DequeModule #endif +@available(Network 0.1.0, *) protocol NetworkComparable: ~Copyable { static func < (lhs: borrowing Self, rhs: borrowing Self) -> Bool static func == (lhs: borrowing Self, rhs: borrowing Self) -> Bool } +@available(Network 0.1.0, *) struct NetworkPriorityQueue: ~Copyable { internal var _heap: NetworkHeap @@ -81,12 +83,14 @@ struct NetworkPriorityQueue: ~Copyable { } } +@available(Network 0.1.0, *) extension NetworkPriorityQueue where Element: ~Copyable { var count: Int { self._heap.count } } +@available(Network 0.1.0, *) extension NetworkPriorityQueue where Element: Copyable { func peek() -> Element? { @@ -98,4 +102,5 @@ extension NetworkPriorityQueue where Element: Copyable { } } +@available(Network 0.1.0, *) extension NetworkPriorityQueue: Sendable where Element: Sendable {} diff --git a/Sources/SwiftNetwork/Utilities/NetworkUniqueArray.swift b/Sources/SwiftNetwork/Utilities/NetworkUniqueArray.swift index bf4361d..2e0a876 100644 --- a/Sources/SwiftNetwork/Utilities/NetworkUniqueArray.swift +++ b/Sources/SwiftNetwork/Utilities/NetworkUniqueArray.swift @@ -17,9 +17,12 @@ import BasicContainers internal import DequeModule +@available(Network 0.1.0, *) typealias NetworkUniqueArray = BasicContainers.UniqueArray +@available(Network 0.1.0, *) typealias NetworkRigidArray = BasicContainers.RigidArray +@available(Network 0.1.0, *) typealias NetworkUniqueDeque = DequeModule.UniqueDeque #endif diff --git a/Sources/SwiftNetwork/Utilities/Serializer.swift b/Sources/SwiftNetwork/Utilities/Serializer.swift index 32399e0..74ca0c2 100644 --- a/Sources/SwiftNetwork/Utilities/Serializer.swift +++ b/Sources/SwiftNetwork/Utilities/Serializer.swift @@ -818,6 +818,7 @@ public struct FrameSerializer: ~Copyable { #endif } +@available(Network 0.1.0, *) extension Serializer { public static func serialize( diff --git a/Sources/SwiftNetwork/Utilities/StreamDeserializer.swift b/Sources/SwiftNetwork/Utilities/StreamDeserializer.swift index 88d8807..8e562d3 100644 --- a/Sources/SwiftNetwork/Utilities/StreamDeserializer.swift +++ b/Sources/SwiftNetwork/Utilities/StreamDeserializer.swift @@ -418,6 +418,7 @@ public struct StreamDeserializer< } } +@available(Network 0.1.0, *) extension StreamDeserializer where T: StreamDeserializerState & ~Copyable, Factory: DeserializerSpanFactory & ~Copyable & ~Escapable { public static func beginState(_ stateIdentifier: StateIdentifier) -> [Step] { @@ -432,6 +433,7 @@ where T: StreamDeserializerState & ~Copyable, Factory: DeserializerSpanFactory & } } +@available(Network 0.1.0, *) extension StreamDeserializer where T: ~Copyable, Factory == FrameArraySpanFactory { public mutating func handleFrames(_ frames: inout FrameArray) throws(DeserializationError) -> T? { try handleInputInternal( @@ -459,6 +461,7 @@ extension StreamDeserializer where T: ~Copyable, Factory == FrameArraySpanFactor } } +@available(Network 0.1.0, *) extension StreamDeserializer where T: ~Copyable, Factory == SingleSpanFactory { public mutating func handleSpan(_ span: RawSpan) throws(DeserializationError) -> T? { try handleInputInternal( @@ -482,6 +485,7 @@ extension StreamDeserializer where T: ~Copyable, Factory == SingleSpanFactory { } } +@available(Network 0.1.0, *) extension StreamDeserializer where Factory: ~Copyable & ~Escapable, T: ~Copyable, StateIdentifier == Int { public static func parser( @StreamDeserializationBuilder _ builder: (_ stream: StreamDeserializer.Type) -> @@ -495,6 +499,7 @@ extension StreamDeserializer where Factory: ~Copyable & ~Escapable, T: ~Copyable } } +@available(Network 0.1.0, *) extension StreamDeserializer where Factory: ~Copyable & ~Escapable, T: StreamDeserializerState & ~Copyable { public static func parser( @StreamDeserializationBuilder _ builder: ( diff --git a/Sources/SwiftNetwork/Utilities/UInt64+VLE.swift b/Sources/SwiftNetwork/Utilities/UInt64+VLE.swift index 3a69a7f..5fd1edb 100644 --- a/Sources/SwiftNetwork/Utilities/UInt64+VLE.swift +++ b/Sources/SwiftNetwork/Utilities/UInt64+VLE.swift @@ -34,6 +34,7 @@ extension FixedWidthInteger { return nil } + @available(macOS 11, iOS 14, tvOS 14, watchOS 7, *) var variableLengthSize: Int { guard let size = self.safeVariableLengthSize else { Logger.proto.error("Integer value too large to encode into a 8-byte VLE") @@ -52,6 +53,7 @@ extension UInt64 { if self <= 4_611_686_018_427_387_903 { return 8 } return nil } + @available(macOS 11, iOS 14, tvOS 14, watchOS 7, *) @inline(__always) var variableLengthSize: Int { guard let size = self.safeVariableLengthSize else { @@ -63,6 +65,7 @@ extension UInt64 { } extension UInt64 { + @available(macOS 11, iOS 14, tvOS 14, watchOS 7, *) func variableLengthEncodeInto(_ buffer: inout [UInt8]) { guard let length = self.safeVariableLengthSize else { // Too big, encode the max UInt62 value instead @@ -88,6 +91,7 @@ extension UInt64 { } } + @available(macOS 10.14.4, iOS 12.2, tvOS 12.2, watchOS 5.2, *) @discardableResult func variableLengthEncodeInto( _ bytes: inout MutableRawSpan, @@ -118,6 +122,7 @@ extension UInt64 { return length } + @available(macOS 11, iOS 14, tvOS 14, watchOS 7, *) func variableLengthValidateInBuffer(_ buffer: RawSpan, offset: Int = 0) throws(VariableLengthEncodingError) -> Int { let length = self.variableLengthSize guard offset + length <= buffer.byteCount else { diff --git a/Sources/SwiftNetworkBenchmarks/BenchmarkUtility.swift b/Sources/SwiftNetworkBenchmarks/BenchmarkUtility.swift index e42bbdd..3c1d609 100644 --- a/Sources/SwiftNetworkBenchmarks/BenchmarkUtility.swift +++ b/Sources/SwiftNetworkBenchmarks/BenchmarkUtility.swift @@ -36,6 +36,7 @@ internal import os #endif @_spi(ProtocolProvider) +@available(Network 0.1.0, *) public struct QUICLoopbackState { public let context: NetworkContext public var clientApplicationLayers: [StreamUpperHarness] @@ -67,6 +68,7 @@ public struct QUICLoopbackState { } @_spi(ProtocolProvider) +@available(Network 0.1.0, *) public struct QUICClientEndpointResult { public var instance: QUICConnection public var parameters: Parameters @@ -76,6 +78,7 @@ public struct QUICClientEndpointResult { } @_spi(ProtocolProvider) +@available(Network 0.1.0, *) public struct QUICServerEndpointResult { public var instance: QUICConnection public var parameters: Parameters @@ -89,6 +92,7 @@ public enum BenchmarkError: Error { } @_spi(ProtocolProvider) +@available(Network 0.1.0, *) public final class QUICBenchmarkUtility { // 127.0.0.1 (Just point both at loopback) @@ -255,6 +259,9 @@ public final class QUICBenchmarkUtility { #endif @_spi(ProtocolProvider) +#if !(os(Linux) || NETWORK_EMBEDDED) +@available(macOS 11, iOS 14, tvOS 14, watchOS 7, *) +#endif public struct LoggingHandle: CustomStringConvertible { #if os(Linux) || NETWORK_EMBEDDED let logger = Logger(label: "com.apple.network.benchmarks") @@ -311,6 +318,7 @@ public struct LoggingHandle: CustomStringConvertible { } @_spi(ProtocolProvider) +@available(Network 0.1.0, *) public final class DataBenchmarkUtility { @discardableResult public func loopOutputHandlerPackets( diff --git a/Sources/SwiftNetworkBenchmarks/DatagramPerfTestHandler.swift b/Sources/SwiftNetworkBenchmarks/DatagramPerfTestHandler.swift index fc419f1..943fe3a 100644 --- a/Sources/SwiftNetworkBenchmarks/DatagramPerfTestHandler.swift +++ b/Sources/SwiftNetworkBenchmarks/DatagramPerfTestHandler.swift @@ -22,6 +22,7 @@ internal import os #endif @_spi(ProtocolProvider) +@available(Network 0.1.0, *) public final class DatagramPerfTestHandler: ProtocolInstanceContainer, InboundDatagramHandler, LoggableProtocol { public typealias LowerProtocol = OutboundDatagramLinkage @@ -240,6 +241,7 @@ public final class DatagramPerfTestHandler: ProtocolInstanceContainer, InboundDa } @_spi(ProtocolProvider) +@available(Network 0.1.0, *) extension DatagramPerfTestHandler: UpperProtocolHandler { // UpperProtocolHandler conformance diff --git a/Sources/SwiftNetworkBenchmarks/NewFlowPerfTestHandler.swift b/Sources/SwiftNetworkBenchmarks/NewFlowPerfTestHandler.swift index fab6df1..bf9b3c8 100644 --- a/Sources/SwiftNetworkBenchmarks/NewFlowPerfTestHandler.swift +++ b/Sources/SwiftNetworkBenchmarks/NewFlowPerfTestHandler.swift @@ -24,6 +24,7 @@ internal import os #if IMPORT_SWIFTTLS && canImport(SwiftTLS) @_spi(Essentials) @_spi(ProtocolProvider) +@available(Network 0.1.0, *) public final class NewFlowPerfTestHandler: ProtocolInstanceContainer, InboundFlowHandler, LoggableProtocol { public typealias LowerProtocol = StreamListenerLinkage @@ -185,6 +186,7 @@ public final class NewFlowPerfTestHandler: ProtocolInstanceContainer, InboundFlo } } +@available(Network 0.1.0, *) extension NewFlowPerfTestHandler: UpperProtocolHandler { // Conform to UpperProtocolHandler but the function is unused public func attachLowerProtocol( diff --git a/Sources/SwiftNetworkBenchmarks/StreamPerfTestHandler.swift b/Sources/SwiftNetworkBenchmarks/StreamPerfTestHandler.swift index 19dea73..e5e3f00 100644 --- a/Sources/SwiftNetworkBenchmarks/StreamPerfTestHandler.swift +++ b/Sources/SwiftNetworkBenchmarks/StreamPerfTestHandler.swift @@ -24,6 +24,7 @@ internal import os #if IMPORT_SWIFTTLS && canImport(SwiftTLS) @_spi(Essentials) @_spi(ProtocolProvider) +@available(Network 0.1.0, *) public final class StreamPerfTestHandler: ProtocolInstanceContainer, InboundStreamHandler, LoggableProtocol { public typealias LowerProtocol = OutboundStreamLinkage @@ -266,6 +267,7 @@ public final class StreamPerfTestHandler: ProtocolInstanceContainer, InboundStre } } +@available(Network 0.1.0, *) extension StreamPerfTestHandler: UpperProtocolHandler { // UpperProtocolHandler conformance diff --git a/Sources/Tools/IPUDPTransfer/main.swift b/Sources/Tools/IPUDPTransfer/main.swift index 67228f8..d9ba011 100644 --- a/Sources/Tools/IPUDPTransfer/main.swift +++ b/Sources/Tools/IPUDPTransfer/main.swift @@ -23,6 +23,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) final class IPUDPTransfer { // 169.254.156.146 @@ -199,64 +200,68 @@ final class IPUDPTransfer { } } -// Take command line arguments -var iterations = 1000 -var packets = 1000 -var loggingHandler: LoggingHandle = LoggingHandle(loggingType: .none) -var sendSize = 1000 // 1k -var arguments = CommandLine.arguments.dropFirst(0) -if arguments.contains("-iterations"), - let index = arguments.firstIndex(of: "-iterations") -{ - if arguments.count >= (index + 2) { - if let parsedIterations = Int(arguments[index + 1]) { - iterations = parsedIterations +if #available(anyAppleOS 26, *) { + // Take command line arguments + var iterations = 1000 + var packets = 1000 + var loggingHandler: LoggingHandle = LoggingHandle(loggingType: .none) + var sendSize = 1000 // 1k + let arguments = CommandLine.arguments.dropFirst(0) + if arguments.contains("-iterations"), + let index = arguments.firstIndex(of: "-iterations") + { + if arguments.count >= (index + 2) { + if let parsedIterations = Int(arguments[index + 1]) { + iterations = parsedIterations + } } } -} -if arguments.contains("-packets"), - let index = arguments.firstIndex(of: "-packets") -{ - if arguments.count >= (index + 2) { - if let parsedPackets = Int(arguments[index + 1]) { - packets = parsedPackets + if arguments.contains("-packets"), + let index = arguments.firstIndex(of: "-packets") + { + if arguments.count >= (index + 2) { + if let parsedPackets = Int(arguments[index + 1]) { + packets = parsedPackets + } } } -} -if arguments.contains("-logging"), - let index = arguments.firstIndex(of: "-logging") -{ - if arguments.count >= (index + 2) { - let parsedLoggingOption = String(arguments[index + 1]) - loggingHandler = LoggingHandle(parsedLoggingOption) + if arguments.contains("-logging"), + let index = arguments.firstIndex(of: "-logging") + { + if arguments.count >= (index + 2) { + let parsedLoggingOption = String(arguments[index + 1]) + loggingHandler = LoggingHandle(parsedLoggingOption) + } } -} -if arguments.contains("-size"), - let index = arguments.firstIndex(of: "-size") -{ - if arguments.count >= (index + 2) { - if let sendSizeOption = Int(arguments[index + 1]) { - sendSize = sendSizeOption + if arguments.contains("-size"), + let index = arguments.firstIndex(of: "-size") + { + if arguments.count >= (index + 2) { + if let sendSizeOption = Int(arguments[index + 1]) { + sendSize = sendSizeOption + } } } -} -// Create and run the transfers -let ipUDPTransfer = IPUDPTransfer() -let group = DispatchGroup() -print("Starting \(iterations) transfers of \(packets) packets with logging set to \(loggingHandler)") -let totalTime = ipUDPTransfer.run( - iterations: iterations, - packets: packets, - loggingHandle: loggingHandler, - group: group, - sendSize: sendSize -) -if totalTime > 0 { - print("Finished all (\(iterations)) transfers in \(totalTime) seconds") + // Create and run the transfers + let ipUDPTransfer = IPUDPTransfer() + let group = DispatchGroup() + print("Starting \(iterations) transfers of \(packets) packets with logging set to \(loggingHandler)") + let totalTime = ipUDPTransfer.run( + iterations: iterations, + packets: packets, + loggingHandle: loggingHandler, + group: group, + sendSize: sendSize + ) + if totalTime > 0 { + print("Finished all (\(iterations)) transfers in \(totalTime) seconds") + } else { + print("Error running all (\(iterations)) transfers, something failed") + } } else { - print("Error running all (\(iterations)) transfers, something failed") + fatalError("This tool requires macOS 26 or newer") } diff --git a/Sources/Tools/QUICHandshake/main.swift b/Sources/Tools/QUICHandshake/main.swift index bf4761b..845ed7b 100644 --- a/Sources/Tools/QUICHandshake/main.swift +++ b/Sources/Tools/QUICHandshake/main.swift @@ -25,6 +25,7 @@ internal import os #if IMPORT_SWIFTTLS && canImport(SwiftTLS) +@available(Network 0.1.0, *) final class QUICHandshake { let quicBenchmarkUtility = QUICBenchmarkUtility() @@ -164,35 +165,39 @@ final class QUICHandshake { } } -// Take command line arguments -var iterations = 10000 -var loggingHandler: LoggingHandle = LoggingHandle(loggingType: .none) -var arguments = CommandLine.arguments.dropFirst(0) -if arguments.contains("-iterations"), - let index = arguments.firstIndex(of: "-iterations") -{ - if arguments.count >= (index + 2) { - if let parsedIterations = Int(arguments[index + 1]) { - iterations = parsedIterations +if #available(anyAppleOS 26, *) { + // Take command line arguments + var iterations = 10000 + var loggingHandler: LoggingHandle = LoggingHandle(loggingType: .none) + let arguments = CommandLine.arguments.dropFirst(0) + if arguments.contains("-iterations"), + let index = arguments.firstIndex(of: "-iterations") + { + if arguments.count >= (index + 2) { + if let parsedIterations = Int(arguments[index + 1]) { + iterations = parsedIterations + } } } -} -if arguments.contains("-logging"), - let index = arguments.firstIndex(of: "-logging") -{ - if arguments.count >= (index + 2) { - let parsedLoggingOption = String(arguments[index + 1]) - loggingHandler = LoggingHandle(parsedLoggingOption) + if arguments.contains("-logging"), + let index = arguments.firstIndex(of: "-logging") + { + if arguments.count >= (index + 2) { + let parsedLoggingOption = String(arguments[index + 1]) + loggingHandler = LoggingHandle(parsedLoggingOption) + } } -} -// Create and run the handshake -let handshake = QUICHandshake() -let group = DispatchGroup() -print("Starting \(iterations) iterations with logging set to \(loggingHandler)") -let totalTime = handshake.run(iterations: iterations, loggingHandle: loggingHandler, group: group) + // Create and run the handshake + let handshake = QUICHandshake() + let group = DispatchGroup() + print("Starting \(iterations) iterations with logging set to \(loggingHandler)") + let totalTime = handshake.run(iterations: iterations, loggingHandle: loggingHandler, group: group) -print("Finished all (\(iterations)) iterations in \(totalTime) seconds") + print("Finished all (\(iterations)) iterations in \(totalTime) seconds") +} else { + fatalError("This tool requires macOS 26 or newer") +} #endif diff --git a/Sources/Tools/QUICStreamLoad/main.swift b/Sources/Tools/QUICStreamLoad/main.swift index a0463f9..26cb78f 100644 --- a/Sources/Tools/QUICStreamLoad/main.swift +++ b/Sources/Tools/QUICStreamLoad/main.swift @@ -31,6 +31,7 @@ import Crypto #if IMPORT_SWIFTTLS && canImport(SwiftTLS) +@available(Network 0.1.0, *) final class QUICStreamLoad { // 169.254.156.146 @@ -414,100 +415,104 @@ final class QUICStreamLoad { } } -// Take command line arguments -var loggingHandler: LoggingHandle = LoggingHandle(loggingType: .none) -var uploadSize = 1000 // 1kb -var downloadSize = 1000 // 1kb -var streamCount = 100000 -var concurrentStreams = 100 -var linkDelay = NetworkDuration.zero -var arguments = CommandLine.arguments.dropFirst(0) - -if arguments.contains("-logging"), - let index = arguments.firstIndex(of: "-logging") -{ - if arguments.count >= (index + 2) { - let parsedLoggingOption = String(arguments[index + 1]) - loggingHandler = LoggingHandle(parsedLoggingOption) +if #available(anyAppleOS 26, *) { + // Take command line arguments + var loggingHandler: LoggingHandle = LoggingHandle(loggingType: .none) + var uploadSize = 1000 // 1kb + var downloadSize = 1000 // 1kb + var streamCount = 100000 + var concurrentStreams = 100 + var linkDelay = NetworkDuration.zero + let arguments = CommandLine.arguments.dropFirst(0) + + if arguments.contains("-logging"), + let index = arguments.firstIndex(of: "-logging") + { + if arguments.count >= (index + 2) { + let parsedLoggingOption = String(arguments[index + 1]) + loggingHandler = LoggingHandle(parsedLoggingOption) + } } -} -if arguments.contains("-stream-count"), - let index = arguments.firstIndex(of: "-stream-count") -{ - if arguments.count >= (index + 2) { - if let streamCountOption = Int(arguments[index + 1]) { - streamCount = streamCountOption + if arguments.contains("-stream-count"), + let index = arguments.firstIndex(of: "-stream-count") + { + if arguments.count >= (index + 2) { + if let streamCountOption = Int(arguments[index + 1]) { + streamCount = streamCountOption + } } } -} -if arguments.contains("-concurrent-streams"), - let index = arguments.firstIndex(of: "-concurrent-streams") -{ - if arguments.count >= (index + 2) { - if let concurrentStreamsOption = Int(arguments[index + 1]) { - concurrentStreams = concurrentStreamsOption + if arguments.contains("-concurrent-streams"), + let index = arguments.firstIndex(of: "-concurrent-streams") + { + if arguments.count >= (index + 2) { + if let concurrentStreamsOption = Int(arguments[index + 1]) { + concurrentStreams = concurrentStreamsOption + } } } -} -if arguments.contains("-link-delay-ms"), - let index = arguments.firstIndex(of: "-link-delay-ms") -{ - if arguments.count >= (index + 2) { - if let linkDelayOption = Int(arguments[index + 1]) { - linkDelay = .milliseconds(linkDelayOption) + if arguments.contains("-link-delay-ms"), + let index = arguments.firstIndex(of: "-link-delay-ms") + { + if arguments.count >= (index + 2) { + if let linkDelayOption = Int(arguments[index + 1]) { + linkDelay = .milliseconds(linkDelayOption) + } } } -} -if arguments.contains("-link-delay-us"), - let index = arguments.firstIndex(of: "-link-delay-us") -{ - if arguments.count >= (index + 2) { - if let linkDelayOption = Int(arguments[index + 1]) { - linkDelay = .microseconds(linkDelayOption) + if arguments.contains("-link-delay-us"), + let index = arguments.firstIndex(of: "-link-delay-us") + { + if arguments.count >= (index + 2) { + if let linkDelayOption = Int(arguments[index + 1]) { + linkDelay = .microseconds(linkDelayOption) + } } } -} -if arguments.contains("-upload-size"), - let index = arguments.firstIndex(of: "-upload-size") -{ - if arguments.count >= (index + 2) { - if let sizeOption = Int(arguments[index + 1]) { - uploadSize = sizeOption + if arguments.contains("-upload-size"), + let index = arguments.firstIndex(of: "-upload-size") + { + if arguments.count >= (index + 2) { + if let sizeOption = Int(arguments[index + 1]) { + uploadSize = sizeOption + } } } -} -if arguments.contains("-download-size"), - let index = arguments.firstIndex(of: "-download-size") -{ - if arguments.count >= (index + 2) { - if let sizeOption = Int(arguments[index + 1]) { - downloadSize = sizeOption + if arguments.contains("-download-size"), + let index = arguments.firstIndex(of: "-download-size") + { + if arguments.count >= (index + 2) { + if let sizeOption = Int(arguments[index + 1]) { + downloadSize = sizeOption + } } } -} -// Create and run the transfers -let quicStreamLoad = QUICStreamLoad() -let group = DispatchGroup() -let totalTime = quicStreamLoad.run( - loggingHandle: loggingHandler, - group: group, - streamCount: streamCount, - concurrentStreams: concurrentStreams, - uploadSize: uploadSize, - downloadSize: downloadSize, - linkDelay: linkDelay -) -if totalTime > .zero { - print("Finished test in \(totalTime)") + // Create and run the transfers + let quicStreamLoad = QUICStreamLoad() + let group = DispatchGroup() + let totalTime = quicStreamLoad.run( + loggingHandle: loggingHandler, + group: group, + streamCount: streamCount, + concurrentStreams: concurrentStreams, + uploadSize: uploadSize, + downloadSize: downloadSize, + linkDelay: linkDelay + ) + if totalTime > .zero { + print("Finished test in \(totalTime)") + } else { + print("Error running test") + } } else { - print("Error running test") + fatalError("This tool requires macOS 26 or newer") } #endif diff --git a/Sources/Tools/QUICTransfer/main.swift b/Sources/Tools/QUICTransfer/main.swift index f1e32fc..e2dd682 100644 --- a/Sources/Tools/QUICTransfer/main.swift +++ b/Sources/Tools/QUICTransfer/main.swift @@ -31,6 +31,7 @@ import Crypto #if IMPORT_SWIFTTLS && canImport(SwiftTLS) +@available(Network 0.1.0, *) final class QUICTransfer { // 169.254.156.146 @@ -277,54 +278,58 @@ final class QUICTransfer { } } -// Take command line arguments -var iterations = 10000 // 5gb total (if 500000 sendSize) -var loggingHandler: LoggingHandle = LoggingHandle(loggingType: .none) -var sendSize = 500000 // 500kb -var arguments = CommandLine.arguments.dropFirst(0) -if arguments.contains("-iterations"), - let index = arguments.firstIndex(of: "-iterations") -{ - if arguments.count >= (index + 2) { - if let parsedIterations = Int(arguments[index + 1]) { - iterations = parsedIterations +if #available(anyAppleOS 26, *) { + // Take command line arguments + var iterations = 10000 // 5gb total (if 500000 sendSize) + var loggingHandler: LoggingHandle = LoggingHandle(loggingType: .none) + var sendSize = 500000 // 500kb + let arguments = CommandLine.arguments.dropFirst(0) + if arguments.contains("-iterations"), + let index = arguments.firstIndex(of: "-iterations") + { + if arguments.count >= (index + 2) { + if let parsedIterations = Int(arguments[index + 1]) { + iterations = parsedIterations + } } } -} -if arguments.contains("-logging"), - let index = arguments.firstIndex(of: "-logging") -{ - if arguments.count >= (index + 2) { - let parsedLoggingOption = String(arguments[index + 1]) - loggingHandler = LoggingHandle(parsedLoggingOption) + if arguments.contains("-logging"), + let index = arguments.firstIndex(of: "-logging") + { + if arguments.count >= (index + 2) { + let parsedLoggingOption = String(arguments[index + 1]) + loggingHandler = LoggingHandle(parsedLoggingOption) + } } -} -if arguments.contains("-size"), - let index = arguments.firstIndex(of: "-size") -{ - if arguments.count >= (index + 2) { - if let sendSizeOption = Int(arguments[index + 1]) { - sendSize = sendSizeOption + if arguments.contains("-size"), + let index = arguments.firstIndex(of: "-size") + { + if arguments.count >= (index + 2) { + if let sendSizeOption = Int(arguments[index + 1]) { + sendSize = sendSizeOption + } } } -} -// Create and run the transfers -let quicTransfer = QUICTransfer() -let group = DispatchGroup() -print("Starting \(iterations) transfers with logging set to \(loggingHandler)") -let totalTime = quicTransfer.run( - iterations: iterations, - loggingHandle: loggingHandler, - group: group, - sendSize: sendSize -) -if totalTime > 0 { - print("Finished all (\(iterations)) transfers in \(totalTime) seconds") + // Create and run the transfers + let quicTransfer = QUICTransfer() + let group = DispatchGroup() + print("Starting \(iterations) transfers with logging set to \(loggingHandler)") + let totalTime = quicTransfer.run( + iterations: iterations, + loggingHandle: loggingHandler, + group: group, + sendSize: sendSize + ) + if totalTime > 0 { + print("Finished all (\(iterations)) transfers in \(totalTime) seconds") + } else { + print("Error running all (\(iterations)) transfers, something failed") + } } else { - print("Error running all (\(iterations)) transfers, something failed") + fatalError("This tool requires macOS 26 or newer") } #endif diff --git a/Sources/Tools/SocketTransfer/main.swift b/Sources/Tools/SocketTransfer/main.swift index 7f99b08..13d6c96 100644 --- a/Sources/Tools/SocketTransfer/main.swift +++ b/Sources/Tools/SocketTransfer/main.swift @@ -24,7 +24,8 @@ internal import os // MARK: - IP address parsing -private func parseIPv4(_ string: String) -> IPv4Address? { +@available(Network 0.1.0, *) +func parseIPv4(_ string: String) -> IPv4Address? { let parts = string.split(separator: ".") guard parts.count == 4 else { return nil } var bytes = [UInt8]() @@ -35,7 +36,8 @@ private func parseIPv4(_ string: String) -> IPv4Address? { return IPv4Address(bytes) } -private func parseIPv6(_ string: String) -> IPv6Address? { +@available(Network 0.1.0, *) +func parseIPv6(_ string: String) -> IPv6Address? { var addr = in6_addr() guard string.withCString({ inet_pton(AF_INET6, $0, &addr) }) == 1 else { return nil @@ -46,17 +48,20 @@ private func parseIPv6(_ string: String) -> IPv6Address? { // MARK: - Helpers -private func makeParams(localEndpoint: Endpoint) -> ParametersBuilder { +@available(Network 0.1.0, *) +func makeParams(localEndpoint: Endpoint) -> ParametersBuilder { let builder = ParametersBuilder.parameters { UDP() } .localEndpoint(localEndpoint) return builder } -private func makeConnection(to remote: Endpoint, localEndpoint: Endpoint) -> NetworkConnection { +@available(Network 0.1.0, *) +func makeConnection(to remote: Endpoint, localEndpoint: Endpoint) -> NetworkConnection { NetworkConnection(to: remote, using: makeParams(localEndpoint: localEndpoint)) } -private func parseEndpoints(ipString: String, port: UInt16, localPort: UInt16) -> (remote: Endpoint, local: Endpoint)? { +@available(Network 0.1.0, *) +func parseEndpoints(ipString: String, port: UInt16, localPort: UInt16) -> (remote: Endpoint, local: Endpoint)? { if let v4 = parseIPv4(ipString) { return ( Endpoint(address: v4, port: port), @@ -73,10 +78,11 @@ private func parseEndpoints(ipString: String, port: UInt16, localPort: UInt16) - // MARK: - SocketTransfer -let NSEC_PER_MSEC = UInt64(Duration.milliseconds(1) / Duration.nanoseconds(1)) - +@available(Network 0.1.0, *) final class SocketTransfer { + static let NSEC_PER_MSEC = UInt64(Duration.milliseconds(1) / Duration.nanoseconds(1)) + let clientPort: UInt16 = 9100 let serverPort: UInt16 = 9101 @@ -176,7 +182,7 @@ final class SocketTransfer { print("Completed \(successCount) / \(iterations) transfers") guard successCount == iterations else { return 0 } let endTime = DispatchTime.now().uptimeNanoseconds - return Double(endTime - timestart) / Double(NSEC_PER_MSEC) / 1000.0 + return Double(endTime - timestart) / Double(SocketTransfer.NSEC_PER_MSEC) / 1000.0 } func sendToRemote( @@ -224,63 +230,69 @@ final class SocketTransfer { print("Completed \(successCount) / \(iterations) sends") guard successCount == iterations else { return 0 } let endTime = DispatchTime.now().uptimeNanoseconds - return Double(endTime - timestart) / Double(NSEC_PER_MSEC) / 1000.0 + return Double(endTime - timestart) / Double(SocketTransfer.NSEC_PER_MSEC) / 1000.0 } } -// MARK: - Argument parsing +// MARK: - Argument parsing helper -var iterations = 100 -var sendSize = 1000 -var echo = true -var remoteIP: String? = nil -var remotePort: UInt16? = nil -var localPort: UInt16 = 0 -let arguments = CommandLine.arguments - -func parseArg(_ flag: String, parse: (String) -> T?) -> T? { +func parseArg(_ arguments: [String], _ flag: String, parse: (String) -> T?) -> T? { guard let index = arguments.firstIndex(of: flag), arguments.count > index + 1 else { return nil } return parse(arguments[index + 1]) } -if let v: Int = parseArg("-iterations", parse: { Int($0) }) { iterations = v } -if let v: Int = parseArg("-size", parse: { Int($0) }) { sendSize = v } -if let v: String = parseArg("-ip", parse: { $0 }) { remoteIP = v } -if let v: UInt16 = parseArg("-port", parse: { UInt16($0) }) { remotePort = v } -if let v: UInt16 = parseArg("-localport", parse: { UInt16($0) }) { localPort = v } -if arguments.contains("-oneway") { echo = false } +if #available(anyAppleOS 26, *) { + // MARK: - Argument parsing -// MARK: - Run + var iterations = 100 + var sendSize = 1000 + var echo = true + var remoteIP: String? = nil + var remotePort: UInt16? = nil + var localPort: UInt16 = 0 + let arguments = CommandLine.arguments -let socketTransfer = SocketTransfer() + if let v: Int = parseArg(arguments, "-iterations", parse: { Int($0) }) { iterations = v } + if let v: Int = parseArg(arguments, "-size", parse: { Int($0) }) { sendSize = v } + if let v: String = parseArg(arguments, "-ip", parse: { $0 }) { remoteIP = v } + if let v: UInt16 = parseArg(arguments, "-port", parse: { UInt16($0) }) { remotePort = v } + if let v: UInt16 = parseArg(arguments, "-localport", parse: { UInt16($0) }) { localPort = v } + if arguments.contains("-oneway") { echo = false } -if let remoteIP { - guard let remotePort else { - print("Error: -port is required when using -ip") - exit(1) - } - print("Starting \(iterations) sends to \(remoteIP):\(remotePort)") - let totalTime = socketTransfer.sendToRemote( - ipString: remoteIP, - port: remotePort, - localPort: localPort, - iterations: iterations, - sendSize: sendSize - ) - if totalTime > 0 { - print("Finished all (\(iterations)) sends in \(totalTime) seconds") + // MARK: - Run + + let socketTransfer = SocketTransfer() + + if let remoteIP { + guard let remotePort else { + print("Error: -port is required when using -ip") + exit(1) + } + print("Starting \(iterations) sends to \(remoteIP):\(remotePort)") + let totalTime = socketTransfer.sendToRemote( + ipString: remoteIP, + port: remotePort, + localPort: localPort, + iterations: iterations, + sendSize: sendSize + ) + if totalTime > 0 { + print("Finished all (\(iterations)) sends in \(totalTime) seconds") + } else { + print("Error running all (\(iterations)) sends, something failed") + } } else { - print("Error running all (\(iterations)) sends, something failed") + let mode = echo ? "round-trip echo" : "one-way send" + print("Starting \(iterations) \(mode) transfers") + let totalTime = socketTransfer.run(iterations: iterations, sendSize: sendSize, echo: echo) + if totalTime > 0 { + print("Finished all (\(iterations)) transfers in \(totalTime) seconds") + } else { + print("Error running all (\(iterations)) transfers, something failed") + } } } else { - let mode = echo ? "round-trip echo" : "one-way send" - print("Starting \(iterations) \(mode) transfers") - let totalTime = socketTransfer.run(iterations: iterations, sendSize: sendSize, echo: echo) - if totalTime > 0 { - print("Finished all (\(iterations)) transfers in \(totalTime) seconds") - } else { - print("Error running all (\(iterations)) transfers, something failed") - } + fatalError("This tool requires macOS 26 or newer") } diff --git a/Tests/QUICTests/AckTests.swift b/Tests/QUICTests/AckTests.swift index c1eec43..65a5b37 100644 --- a/Tests/QUICTests/AckTests.swift +++ b/Tests/QUICTests/AckTests.swift @@ -22,9 +22,11 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) @testable import Network #endif +@available(Network 0.1.0, *) func setAckFrame(_: PacketNumberSpace, _: consuming QUICFrame, _: Bool) { } +@available(Network 0.1.0, *) extension Ack { // only required by the test currently func size( @@ -39,8 +41,10 @@ extension Ack { } } +@available(Network 0.1.0, *) let ackTestsLogPrefixer: LogPrefixer = LogPrefixer("[AckTests]") +@available(Network 0.1.0, *) final class AckTests: XCTestCase { var ack = Ack(logPrefixer: ackTestsLogPrefixer) diff --git a/Tests/QUICTests/CubicTests.swift b/Tests/QUICTests/CubicTests.swift index eb3cce8..af68ed3 100644 --- a/Tests/QUICTests/CubicTests.swift +++ b/Tests/QUICTests/CubicTests.swift @@ -22,6 +22,7 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) @testable import Network #endif +@available(Network 0.1.0, *) final class CubicTests: XCTestCase { var rtt: RTT! diff --git a/Tests/QUICTests/ECNTests.swift b/Tests/QUICTests/ECNTests.swift index 1e6581f..d430b81 100644 --- a/Tests/QUICTests/ECNTests.swift +++ b/Tests/QUICTests/ECNTests.swift @@ -23,6 +23,7 @@ import XCTest #endif // MARK: ECN Initialization Tests +@available(Network 0.1.0, *) final class ECNTests: XCTestCase { var ecn: ECN! var ecnPath: ECNPathState! @@ -179,6 +180,7 @@ final class ECNTests: XCTestCase { } +@available(Network 0.1.0, *) struct ECNTestStepSend { let description: String let repeats: Int @@ -188,6 +190,7 @@ struct ECNTestStepSend { let expectedFlag: IPProtocol.ECN } +@available(Network 0.1.0, *) struct ECNTestStepAck: ~Copyable { let description: String let repeats: Int @@ -199,6 +202,7 @@ struct ECNTestStepAck: ~Copyable { let newlyAckedECNCount: UInt64 } +@available(Network 0.1.0, *) extension ECNTestStepSend { // Convenience constructors since most of the tests follow the same test steps static func probingState(flag: IPProtocol.ECN, repeats: Int) -> ECNTestStepSend { @@ -301,6 +305,7 @@ extension ECNTestStepSend { } } +@available(Network 0.1.0, *) extension ECNTestStepAck { // Convenience constructors since most of the tests follow the same test steps static func validateToCapable( @@ -395,6 +400,7 @@ extension ECNTestStepAck { } // MARK: ECN Validation Tests +@available(Network 0.1.0, *) final class ECNValidateTests: XCTestCase { var ecn: ECN! var ecnPath: ECNPathState! diff --git a/Tests/QUICTests/FlowControlTests.swift b/Tests/QUICTests/FlowControlTests.swift index f8bfdf4..0704dbe 100644 --- a/Tests/QUICTests/FlowControlTests.swift +++ b/Tests/QUICTests/FlowControlTests.swift @@ -22,6 +22,7 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) @testable import Network #endif +@available(Network 0.1.0, *) final class FlowControlTests: XCTestCase { func testOutboundFlowControl() { let logPrefixer = LogPrefixer("[FlowControlTests]") diff --git a/Tests/QUICTests/LedbatTests.swift b/Tests/QUICTests/LedbatTests.swift index 15e9aba..2fe3d6e 100644 --- a/Tests/QUICTests/LedbatTests.swift +++ b/Tests/QUICTests/LedbatTests.swift @@ -22,6 +22,7 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) @testable import Network #endif +@available(Network 0.1.0, *) final class LedbatTests: XCTestCase { var rtt: RTT! let mss = Constants.initialMSS diff --git a/Tests/QUICTests/ManagedConnectionIDTests.swift b/Tests/QUICTests/ManagedConnectionIDTests.swift index f2fe7de..d33cfcb 100644 --- a/Tests/QUICTests/ManagedConnectionIDTests.swift +++ b/Tests/QUICTests/ManagedConnectionIDTests.swift @@ -22,6 +22,7 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) @testable import Network #endif +@available(Network 0.1.0, *) class ManagedConnectionIDTests: XCTestCase { func testInit() { let managedConnectionID = ManagedConnectionID( diff --git a/Tests/QUICTests/PacerTests.swift b/Tests/QUICTests/PacerTests.swift index 820eee4..baad6d5 100644 --- a/Tests/QUICTests/PacerTests.swift +++ b/Tests/QUICTests/PacerTests.swift @@ -22,6 +22,7 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) @testable import Network #endif +@available(Network 0.1.0, *) final class PacerTests: XCTestCase { var connection: QUICConnection! diff --git a/Tests/QUICTests/PacketNumberSpaceTests.swift b/Tests/QUICTests/PacketNumberSpaceTests.swift index bfd50a0..fb66937 100644 --- a/Tests/QUICTests/PacketNumberSpaceTests.swift +++ b/Tests/QUICTests/PacketNumberSpaceTests.swift @@ -22,6 +22,7 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) @testable import Network #endif +@available(Network 0.1.0, *) final class PacketNumberSpaceTests: XCTestCase { func testPacketNumberSpaceFromKeyState() { for state in PacketKeyState.allCases { diff --git a/Tests/QUICTests/PragueTests.swift b/Tests/QUICTests/PragueTests.swift index c439498..f8523e8 100644 --- a/Tests/QUICTests/PragueTests.swift +++ b/Tests/QUICTests/PragueTests.swift @@ -22,6 +22,7 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) @testable import Network #endif +@available(Network 0.1.0, *) final class PragueTests: XCTestCase { var rtt: RTT! diff --git a/Tests/QUICTests/ProtectorTests.swift b/Tests/QUICTests/ProtectorTests.swift index c6cda42..b53427f 100644 --- a/Tests/QUICTests/ProtectorTests.swift +++ b/Tests/QUICTests/ProtectorTests.swift @@ -22,6 +22,7 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) @testable import Network #endif +@available(Network 0.1.0, *) let protectorTestsLogPrefixer: LogPrefixer = LogPrefixer("[ProtectorTests]") #if IMPORT_CRYPTO @@ -37,6 +38,7 @@ import CryptoKit import Crypto #endif +@available(Network 0.1.0, *) extension InlineArray where Element: Equatable { fileprivate func equalTo(_ rhs: Self) -> Bool { for i in 0.. Bool { func checkHeapProperty(index: Int) -> Bool { @@ -173,6 +177,7 @@ extension NetworkHeap { } } +@available(Network 0.1.0, *) extension Array where Element: NetworkComparable & Copyable { init(_ heap: borrowing NetworkHeap) { self = [] @@ -184,6 +189,7 @@ extension Array where Element: NetworkComparable & Copyable { } } +@available(Network 0.1.0, *) extension NetworkHeap { func sorted() -> [Element] { Array(self).sorted(by: { $0 < $1 }) diff --git a/Tests/SwiftNetworkTests/SwiftNetworkIPTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkIPTests.swift index 6e78708..48c5f0a 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkIPTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkIPTests.swift @@ -22,6 +22,7 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) import Network #endif +@available(Network 0.1.0, *) final class SwiftNetworkIPTests: NetTestCase { // 169.254.156.146 diff --git a/Tests/SwiftNetworkTests/SwiftNetworkInterfaceTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkInterfaceTests.swift index e3253eb..d15bbef 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkInterfaceTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkInterfaceTests.swift @@ -22,6 +22,7 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) final class SwiftNetworkInterfaceTests: NetTestCase { // Create interface with bad index, Darwin will abort on index 0 so this is guarded diff --git a/Tests/SwiftNetworkTests/SwiftNetworkMultiplexingTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkMultiplexingTests.swift index ca42c44..5515a16 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkMultiplexingTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkMultiplexingTests.swift @@ -22,6 +22,7 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) import Network #endif +@available(Network 0.1.0, *) final class SwiftNetworkMultiplexingTests: NetTestCase { static let outputMessage: [UInt8] = [0x0a, 0x0b, 0x0c, 0x0d] diff --git a/Tests/SwiftNetworkTests/SwiftNetworkMutexTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkMutexTests.swift index 8e04811..50bcf4c 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkMutexTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkMutexTests.swift @@ -15,6 +15,7 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) @testable import SwiftNetwork +@available(Network 0.1.0, *) final class SwiftNetworkMutexTests: NetTestCase { func testMutexWithoutStorage() throws { let context = NetworkContext.implicitContext diff --git a/Tests/SwiftNetworkTests/SwiftNetworkPriorityQueueTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkPriorityQueueTests.swift index 169a4f9..d6e4d52 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkPriorityQueueTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkPriorityQueueTests.swift @@ -18,8 +18,10 @@ import XCTest @testable import SwiftNetwork #endif +@available(Network 0.1.0, *) extension String: NetworkComparable {} +@available(Network 0.1.0, *) final class SwiftNetworkPriorityQueueTests: XCTestCase { func testSomeStringsAsc() throws { @@ -141,6 +143,7 @@ final class SwiftNetworkPriorityQueueTests: XCTestCase { } /// This data type is only partially ordered. Ie. from `a < b` and `a != b` we can't imply `a > b`. +@available(Network 0.1.0, *) struct SomePartiallyOrderedDataType: NetworkComparable, Equatable, CustomStringConvertible { public static func < (lhs: SomePartiallyOrderedDataType, rhs: SomePartiallyOrderedDataType) -> Bool { lhs.width < rhs.width && lhs.height < rhs.height @@ -162,6 +165,7 @@ struct SomePartiallyOrderedDataType: NetworkComparable, Equatable, CustomStringC } } +@available(Network 0.1.0, *) extension NetworkPriorityQueue where Element: Equatable { public static func == (lhs: borrowing Self, rhs: borrowing Self) -> Bool { let arr = Array(lhs._heap) diff --git a/Tests/SwiftNetworkTests/SwiftNetworkProtocolStackTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkProtocolStackTests.swift index e03c027..deabd28 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkProtocolStackTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkProtocolStackTests.swift @@ -18,6 +18,7 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) @testable import SwiftNetwork #endif +@available(Network 0.1.0, *) final class SwiftNetworkProtocolStackTests: NetTestCase { func testIPOptions() { let ipOptions = IPProtocol.definition.protocolOptions() diff --git a/Tests/SwiftNetworkTests/SwiftNetworkQUICECNTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkQUICECNTests.swift index 9fa85a2..7a87f92 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkQUICECNTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkQUICECNTests.swift @@ -46,6 +46,7 @@ internal import os #if IMPORT_SWIFTTLS #if canImport(SwiftTLS) #if !NETWORK_PRIVATE +@available(Network 0.1.0, *) final class SwiftNetworkQUICECNTests: NetTestCase { func testQUICTestECNMarkedPacketsSentAndACKed() throws { QUICTestHarness().runQUICTest( diff --git a/Tests/SwiftNetworkTests/SwiftNetworkQUICEarlyDataTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkQUICEarlyDataTests.swift index d004bb7..7ee58cd 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkQUICEarlyDataTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkQUICEarlyDataTests.swift @@ -45,6 +45,7 @@ internal import os #if IMPORT_SWIFTTLS #if canImport(SwiftTLS) +@available(Network 0.1.0, *) final class SwiftNetworkQUICEarlyDataTests: NetTestCase { // 10.0.0.20 diff --git a/Tests/SwiftNetworkTests/SwiftNetworkQUICHarnessTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkQUICHarnessTests.swift index 6dba7d0..b6f33db 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkQUICHarnessTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkQUICHarnessTests.swift @@ -49,6 +49,7 @@ import Dispatch #if IMPORT_SWIFTTLS #if canImport(SwiftTLS) +@available(Network 0.1.0, *) final class SwiftNetworkQUICHarnessTests: NetTestCase { // MARK: Handshake tests diff --git a/Tests/SwiftNetworkTests/SwiftNetworkQUICKeepaliveTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkQUICKeepaliveTests.swift index 754d7e5..a13cdf1 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkQUICKeepaliveTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkQUICKeepaliveTests.swift @@ -45,6 +45,7 @@ internal import os #if IMPORT_SWIFTTLS #if canImport(SwiftTLS) +@available(Network 0.1.0, *) final class SwiftNetworkQUICKeepaliveTests: NetTestCase { func testQUICClientKeepAliveWithLowTimeoutAndPMTUDInterval() throws { // This test is expected to timeout because the idleTimeout is set to 2 seconds. diff --git a/Tests/SwiftNetworkTests/SwiftNetworkQUICPacer.swift b/Tests/SwiftNetworkTests/SwiftNetworkQUICPacer.swift index 8f7542e..d18d541 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkQUICPacer.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkQUICPacer.swift @@ -45,6 +45,7 @@ internal import os #if IMPORT_SWIFTTLS #if canImport(SwiftTLS) +@available(Network 0.1.0, *) final class SwiftNetworkQUICPacer: NetTestCase { func testQUICClientPacingMarkedPackets() throws { let clientOptions = QUICProtocol.options() diff --git a/Tests/SwiftNetworkTests/SwiftNetworkQUICRetryTokenTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkQUICRetryTokenTests.swift index 795dc19..6af7129 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkQUICRetryTokenTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkQUICRetryTokenTests.swift @@ -46,6 +46,7 @@ internal import os #if IMPORT_SWIFTTLS #if canImport(SwiftTLS) +@available(Network 0.1.0, *) final class SwiftNetworkQUICRetryTokenTests: NetTestCase { func testQUICInternalServerForceRetryDuringInitial() throws { let serverOptions = QUICProtocol.options() diff --git a/Tests/SwiftNetworkTests/SwiftNetworkQUICShortLHPacketTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkQUICShortLHPacketTests.swift index 4798bc9..bb4b441 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkQUICShortLHPacketTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkQUICShortLHPacketTests.swift @@ -45,6 +45,7 @@ internal import os #if IMPORT_SWIFTTLS #if canImport(SwiftTLS) +@available(Network 0.1.0, *) final class SwiftNetworkQUICShortLHPacketTests: NetTestCase { var serverSigningKey = P256.Signing.PrivateKey() diff --git a/Tests/SwiftNetworkTests/SwiftNetworkQUICSpinBitTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkQUICSpinBitTests.swift index b81c117..56d1a31 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkQUICSpinBitTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkQUICSpinBitTests.swift @@ -46,6 +46,7 @@ internal import os #if IMPORT_SWIFTTLS #if canImport(SwiftTLS) +@available(Network 0.1.0, *) final class SwiftNetworkQUICSpinBitTests: NetTestCase { func testQUICSpinBitEnabledOrDisabled() throws { // Even when the client leaves the spin bit enabled there is a chance (1 / 16) that it diff --git a/Tests/SwiftNetworkTests/SwiftNetworkQUICStackTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkQUICStackTests.swift index 5fbac50..09da2b2 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkQUICStackTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkQUICStackTests.swift @@ -45,6 +45,7 @@ internal import os #if IMPORT_SWIFTTLS #if canImport(SwiftTLS) +@available(Network 0.1.0, *) final class SwiftNetworkQUICStackTests: NetTestCase { // 10.0.0.20 diff --git a/Tests/SwiftNetworkTests/SwiftNetworkQUICStatisticsTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkQUICStatisticsTests.swift index f5e622c..d593e80 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkQUICStatisticsTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkQUICStatisticsTests.swift @@ -46,6 +46,7 @@ internal import os #if IMPORT_SWIFTTLS #if canImport(SwiftTLS) +@available(Network 0.1.0, *) final class SwiftNetworkQUICStatisticsTests: NetTestCase { func testQUICStatisticsForOneStream() throws { QUICTestHarness().runQUICTest( diff --git a/Tests/SwiftNetworkTests/SwiftNetworkQUICUngracefulCloseTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkQUICUngracefulCloseTests.swift index 10cc866..3886986 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkQUICUngracefulCloseTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkQUICUngracefulCloseTests.swift @@ -49,6 +49,7 @@ internal import os #if IMPORT_SWIFTTLS #if canImport(SwiftTLS) +@available(Network 0.1.0, *) final class SwiftNetworkQUICUngracefulCloseTests: NetTestCase { func testQUICServerUnreachable() throws { let clientOptions = QUICProtocol.options() diff --git a/Tests/SwiftNetworkTests/SwiftNetworkQUICVersionNegotiation.swift b/Tests/SwiftNetworkTests/SwiftNetworkQUICVersionNegotiation.swift index 4c04957..985567a 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkQUICVersionNegotiation.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkQUICVersionNegotiation.swift @@ -46,6 +46,7 @@ internal import os #if IMPORT_SWIFTTLS #if canImport(SwiftTLS) +@available(Network 0.1.0, *) final class SwiftNetworkQUICVersionNegotiation: NetTestCase { func testQUICClientForceVersionNegotiation() throws { // This test forces version negotiation from the client by sending the negotiation pattern to the server in the initial. diff --git a/Tests/SwiftNetworkTests/SwiftNetworkSerializerTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkSerializerTests.swift index 03dc734..23a2d5f 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkSerializerTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkSerializerTests.swift @@ -20,6 +20,7 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) @testable import Network #endif +@available(Network 0.1.0, *) final class SwiftNetworkSerializerTests: NetTestCase { let arrayCount = 10 diff --git a/Tests/SwiftNetworkTests/SwiftNetworkSocketTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkSocketTests.swift index 965033e..6a912cc 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkSocketTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkSocketTests.swift @@ -24,6 +24,7 @@ import XCTest #endif #endif +@available(Network 0.1.0, *) final class SwiftNetworkSocketTests: NetTestCase { // MARK: - Helpers diff --git a/Tests/SwiftNetworkTests/SwiftNetworkStreamDeserializationTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkStreamDeserializationTests.swift index 918701c..df2370d 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkStreamDeserializationTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkStreamDeserializationTests.swift @@ -20,6 +20,7 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) @testable import Network #endif +@available(Network 0.1.0, *) final class SwiftNetworkStreamDeserializationTests: NetTestCase { // Simple TLV protocol that uses variable-length integers diff --git a/Tests/SwiftNetworkTests/SwiftNetworkUDPTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkUDPTests.swift index 1021929..51664ec 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkUDPTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkUDPTests.swift @@ -22,6 +22,7 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) import Network #endif +@available(Network 0.1.0, *) final class SwiftNetworkUDPTests: NetTestCase { // 10.0.0.20 diff --git a/Tests/SwiftNetworkTests/SwiftNetworkUUIDTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkUUIDTests.swift index 9e226ff..3b853ee 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkUUIDTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkUUIDTests.swift @@ -29,6 +29,7 @@ import Glibc internal import SwiftNetworkLinuxShim #endif +@available(Network 0.1.0, *) final class SwiftNetworkUUIDTests: NetTestCase { func testUUIDCreation() { diff --git a/Tests/SwiftNetworkTests/SwiftNetworkUniqueArrayTests.swift b/Tests/SwiftNetworkTests/SwiftNetworkUniqueArrayTests.swift index 8beb780..48966c9 100644 --- a/Tests/SwiftNetworkTests/SwiftNetworkUniqueArrayTests.swift +++ b/Tests/SwiftNetworkTests/SwiftNetworkUniqueArrayTests.swift @@ -22,6 +22,7 @@ import XCTest @_spi(Essentials) @_spi(ProtocolProvider) @testable import Network #endif +@available(Network 0.1.0, *) final class SwiftNetworkUniqueArrayTests: NetTestCase { func testArrayCapacity() { diff --git a/Tests/SwiftNetworkTests/TestMultiplexingProtocol.swift b/Tests/SwiftNetworkTests/TestMultiplexingProtocol.swift index 85707a2..2533c5f 100644 --- a/Tests/SwiftNetworkTests/TestMultiplexingProtocol.swift +++ b/Tests/SwiftNetworkTests/TestMultiplexingProtocol.swift @@ -27,14 +27,17 @@ internal import Logging internal import os #endif +@available(Network 0.1.0, *) final class TestDatagramFlow: MultiplexedDatagramFlow { } +@available(Network 0.1.0, *) final class TestDatagramPath: MultiplexingDatagramPath { } +@available(Network 0.1.0, *) final class TestMultiplexingProtocol: ManyToManyApplicationDatagramProtocol, ManyToManyOutboundDatagramProtocol, DatagramListenerHandler, HomogeneousManyToManyProtocolHandler, ProtocolInstanceContainer {