Add `NIOBSDSocket.ProtocolSubtype` (#2317)

* RawSocket prototype

* Conform `ProtocolSubtype` to `Hashable`

* Add public `NIOIPProtocol` type

Make `ProtocolSubtype` internal

* Subset of IANA protocols with an RFC

* Add `CustomStringConvertible` to `NIOIPProtocol`

* Add `init(_ rawValue: Int)`

* Rename `NIOBSDSocket.ProtocolSubtype.ip` to `.default`

* Add `NIOBSDSocket.ProtocolSubtype.mptcp`

and remove `NIOBSDSocket.mptcpProtocolSubtype`
This commit is contained in:
David Nadoba 2022-11-22 15:01:52 +01:00 committed by GitHub
parent dd074002a5
commit 0b4edd8329
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 271 additions and 46 deletions

View File

@ -48,6 +48,7 @@ EOF
"$here/../../Sources/NIOPosix/BSDSocketAPIPosix.swift" \
"$here/../../Sources/NIOPosix/System.swift" \
"$here/../../Sources/NIOCore/IO.swift" \
"$here/../../Sources/NIOCore/IPProtocol.swift" \
"$here/../../Sources/NIOCore/NIOSendable.swift" \
"$tmpdir/syscallwrapper/Sources/syscallwrapper"
cp "$here/../../Sources/NIOPosix/IO.swift" "$tmpdir/syscallwrapper/Sources/syscallwrapper/NIOPosixIO.swift"

View File

@ -0,0 +1,177 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2022 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
/// In the Internet Protocol version 4 (IPv4) [RFC791] there is a field
/// called "Protocol" to identify the next level protocol. This is an 8
/// bit field. In Internet Protocol version 6 (IPv6) [RFC8200], this field
/// is called the "Next Header" field.
public struct NIOIPProtocol: RawRepresentable, Hashable {
public typealias RawValue = UInt8
public var rawValue: RawValue
@inlinable
public init(rawValue: RawValue) {
self.rawValue = rawValue
}
}
extension NIOIPProtocol {
/// - precondition: `rawValue` must fit into an `UInt8`
public init(_ rawValue: Int) {
self.init(rawValue: UInt8(rawValue))
}
}
// Subset of https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml with an RFC
extension NIOIPProtocol {
/// IPv6 Hop-by-Hop Option - [RFC8200]
public static let hopopt = Self(rawValue: 0)
/// Internet Control Message - [RFC792]
public static let icmp = Self(rawValue: 1)
/// Internet Group Management - [RFC1112]
public static let igmp = Self(rawValue: 2)
/// Gateway-to-Gateway - [RFC823]
public static let ggp = Self(rawValue: 3)
/// IPv4 encapsulation - [RFC2003]
public static let ipv4 = Self(rawValue: 4)
/// Stream - [RFC1190][RFC1819]
public static let st = Self(rawValue: 5)
/// Transmission Control - [RFC9293]
public static let tcp = Self(rawValue: 6)
/// Exterior Gateway Protocol - [RFC888][David_Mills]
public static let egp = Self(rawValue: 8)
/// Network Voice Protocol - [RFC741][Steve_Casner]
public static let nvpIi = Self(rawValue: 11)
/// User Datagram - [RFC768][Jon_Postel]
public static let udp = Self(rawValue: 17)
/// Host Monitoring - [RFC869][Bob_Hinden]
public static let hmp = Self(rawValue: 20)
/// Reliable Data Protocol - [RFC908][Bob_Hinden]
public static let rdp = Self(rawValue: 27)
/// Internet Reliable Transaction - [RFC938][Trudy_Miller]
public static let irtp = Self(rawValue: 28)
/// ISO Transport Protocol Class 4 - [RFC905][<mystery contact>]
public static let isoTp4 = Self(rawValue: 29)
/// Bulk Data Transfer Protocol - [RFC969][David_Clark]
public static let netblt = Self(rawValue: 30)
/// Datagram Congestion Control Protocol - [RFC4340]
public static let dccp = Self(rawValue: 33)
/// IPv6 encapsulation - [RFC2473]
public static let ipv6 = Self(rawValue: 41)
/// Reservation Protocol - [RFC2205][RFC3209][Bob_Braden]
public static let rsvp = Self(rawValue: 46)
/// Generic Routing Encapsulation - [RFC2784][Tony_Li]
public static let gre = Self(rawValue: 47)
/// Dynamic Source Routing Protocol - [RFC4728]
public static let dsr = Self(rawValue: 48)
/// Encap Security Payload - [RFC4303]
public static let esp = Self(rawValue: 50)
/// Authentication Header - [RFC4302]
public static let ah = Self(rawValue: 51)
/// NBMA Address Resolution Protocol - [RFC1735]
public static let narp = Self(rawValue: 54)
/// ICMP for IPv6 - [RFC8200]
public static let ipv6Icmp = Self(rawValue: 58)
/// No Next Header for IPv6 - [RFC8200]
public static let ipv6Nonxt = Self(rawValue: 59)
/// Destination Options for IPv6 - [RFC8200]
public static let ipv6Opts = Self(rawValue: 60)
/// EIGRP - [RFC7868]
public static let eigrp = Self(rawValue: 88)
/// OSPFIGP - [RFC1583][RFC2328][RFC5340][John_Moy]
public static let ospfigp = Self(rawValue: 89)
/// Ethernet-within-IP Encapsulation - [RFC3378]
public static let etherip = Self(rawValue: 97)
/// Encapsulation Header - [RFC1241][Robert_Woodburn]
public static let encap = Self(rawValue: 98)
/// Protocol Independent Multicast - [RFC7761][Dino_Farinacci]
public static let pim = Self(rawValue: 103)
/// IP Payload Compression Protocol - [RFC2393]
public static let ipcomp = Self(rawValue: 108)
/// Virtual Router Redundancy Protocol - [RFC5798]
public static let vrrp = Self(rawValue: 112)
/// Layer Two Tunneling Protocol - [RFC3931][Bernard_Aboba]
public static let l2tp = Self(rawValue: 115)
/// Fibre Channel - [Murali_Rajagopal][RFC6172]
public static let fc = Self(rawValue: 133)
/// MANET Protocols - [RFC5498]
public static let manet = Self(rawValue: 138)
/// Host Identity Protocol - [RFC7401]
public static let hip = Self(rawValue: 139)
/// Shim6 Protocol - [RFC5533]
public static let shim6 = Self(rawValue: 140)
/// Wrapped Encapsulating Security Payload - [RFC5840]
public static let wesp = Self(rawValue: 141)
/// Robust Header Compression - [RFC5858]
public static let rohc = Self(rawValue: 142)
/// Ethernet - [RFC8986]
public static let ethernet = Self(rawValue: 143)
/// AGGFRAG encapsulation payload for ESP - [RFC-ietf-ipsecme-iptfs-19]
public static let aggfrag = Self(rawValue: 144)
}
extension NIOIPProtocol: CustomStringConvertible {
private var name: String? {
switch self {
case .hopopt: return "IPv6 Hop-by-Hop Option"
case .icmp: return "Internet Control Message"
case .igmp: return "Internet Group Management"
case .ggp: return "Gateway-to-Gateway"
case .ipv4: return "IPv4 encapsulation"
case .st: return "Stream"
case .tcp: return "Transmission Control"
case .egp: return "Exterior Gateway Protocol"
case .nvpIi: return "Network Voice Protocol"
case .udp: return "User Datagram"
case .hmp: return "Host Monitoring"
case .rdp: return "Reliable Data Protocol"
case .irtp: return "Internet Reliable Transaction"
case .isoTp4: return "ISO Transport Protocol Class 4"
case .netblt: return "Bulk Data Transfer Protocol"
case .dccp: return "Datagram Congestion Control Protocol"
case .ipv6: return "IPv6 encapsulation"
case .rsvp: return "Reservation Protocol"
case .gre: return "Generic Routing Encapsulation"
case .dsr: return "Dynamic Source Routing Protocol"
case .esp: return "Encap Security Payload"
case .ah: return "Authentication Header"
case .narp: return "NBMA Address Resolution Protocol"
case .ipv6Icmp: return "ICMP for IPv6"
case .ipv6Nonxt: return "No Next Header for IPv6"
case .ipv6Opts: return "Destination Options for IPv6"
case .eigrp: return "EIGRP"
case .ospfigp: return "OSPFIGP"
case .etherip: return "Ethernet-within-IP Encapsulation"
case .encap: return "Encapsulation Header"
case .pim: return "Protocol Independent Multicast"
case .ipcomp: return "IP Payload Compression Protocol"
case .vrrp: return "Virtual Router Redundancy Protocol"
case .l2tp: return "Layer Two Tunneling Protocol"
case .fc: return "Fibre Channel"
case .manet: return "MANET Protocols"
case .hip: return "Host Identity Protocol"
case .shim6: return "Shim6 Protocol"
case .wesp: return "Wrapped Encapsulating Security Payload"
case .rohc: return "Robust Header Compression"
case .ethernet: return "Ethernet"
case .aggfrag: return "AGGFRAG encapsulation payload for ESP"
default: return nil
}
}
public var description: String {
let name = self.name ?? "Unknown Protocol"
return "\(name) - \(rawValue)"
}
}

View File

@ -2,7 +2,7 @@
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2020-2021 Apple Inc. and the SwiftNIO project authors
// Copyright (c) 2020-2022 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
@ -127,6 +127,38 @@ extension NIOBSDSocket.Option {
NIOBSDSocket.Option(rawValue: Posix.IPV6_RECVPKTINFO)
}
extension NIOBSDSocket {
struct ProtocolSubtype: RawRepresentable, Hashable {
typealias RawValue = CInt
var rawValue: RawValue
init(rawValue: RawValue) {
self.rawValue = rawValue
}
}
}
extension NIOBSDSocket.ProtocolSubtype {
static let `default` = Self(rawValue: 0)
/// The protocol subtype for MPTCP.
/// - returns: nil if MPTCP is not supported.
static var mptcp: Self? {
#if os(Linux)
// Defined by the linux kernel, this is IPPROTO_MPTCP.
return .init(rawValue: 262)
#else
return nil
#endif
}
}
extension NIOBSDSocket.ProtocolSubtype {
init(_ protocol: NIOIPProtocol) {
self.rawValue = CInt(`protocol`.rawValue)
}
}
/// This protocol defines the methods that are expected to be found on
/// `NIOBSDSocket`. While defined as a protocol there is no expectation that any
/// object other than `NIOBSDSocket` will implement this protocol: instead, this
@ -195,7 +227,7 @@ protocol _BSDSocketProtocol {
static func socket(domain af: NIOBSDSocket.ProtocolFamily,
type: NIOBSDSocket.SocketType,
`protocol`: CInt) throws -> NIOBSDSocket.Handle
protocolSubtype: NIOBSDSocket.ProtocolSubtype) throws -> NIOBSDSocket.Handle
static func recvmmsg(socket: NIOBSDSocket.Handle,
msgvec: UnsafeMutablePointer<MMsgHdr>,

View File

@ -122,8 +122,8 @@ extension NIOBSDSocket {
static func socket(domain af: NIOBSDSocket.ProtocolFamily,
type: NIOBSDSocket.SocketType,
`protocol`: CInt) throws -> NIOBSDSocket.Handle {
return try Posix.socket(domain: af, type: type, protocol: `protocol`)
protocolSubtype: NIOBSDSocket.ProtocolSubtype) throws -> NIOBSDSocket.Handle {
return try Posix.socket(domain: af, type: type, protocolSubtype: protocolSubtype)
}
static func recvmmsg(socket: NIOBSDSocket.Handle,
@ -209,17 +209,6 @@ extension NIOBSDSocket {
throw err
}
}
// The protocol subtype for MPTCP.
// Returns nil if mptcp is not supported.
static var mptcpProtocolSubtype: Int? {
#if os(Linux)
// Defined by the linux kernel, this is IPPROTO_MPTCP.
return 262
#else
return nil
#endif
}
}
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)

View File

@ -360,8 +360,8 @@ extension NIOBSDSocket {
@inline(never)
static func socket(domain af: NIOBSDSocket.ProtocolFamily,
type: NIOBSDSocket.SocketType,
`protocol`: CInt) throws -> NIOBSDSocket.Handle {
let socket: NIOBSDSocket.Handle = WinSDK.socket(af.rawValue, type.rawValue, `protocol`)
protocolSubtype: NIOBSDSocket.ProtocolSubtype) throws -> NIOBSDSocket.Handle {
let socket: NIOBSDSocket.Handle = WinSDK.socket(af.rawValue, type.rawValue, protocolSubtype.rawValue)
if socket == WinSDK.INVALID_SOCKET {
throw IOError(winsock: WSAGetLastError(), reason: "socket")
}

View File

@ -162,12 +162,15 @@ class BaseSocket: BaseSocketProtocol {
/// - parameters:
/// - protocolFamily: The protocol family to use (usually `AF_INET6` or `AF_INET`).
/// - type: The type of the socket to create.
/// - protocolSubtype: The subtype of the protocol, corresponding to the `protocol`
/// argument to the socket syscall. Defaults to 0.
/// - setNonBlocking: Set non-blocking mode on the socket.
/// - returns: the file descriptor of the socket that was created.
/// - throws: An `IOError` if creation of the socket failed.
static func makeSocket(protocolFamily: NIOBSDSocket.ProtocolFamily, type: NIOBSDSocket.SocketType, protocolSubtype: Int = 0, setNonBlocking: Bool = false) throws -> NIOBSDSocket.Handle {
static func makeSocket(
protocolFamily: NIOBSDSocket.ProtocolFamily,
type: NIOBSDSocket.SocketType,
protocolSubtype: NIOBSDSocket.ProtocolSubtype,
setNonBlocking: Bool = false
) throws -> NIOBSDSocket.Handle {
var sockType: CInt = type.rawValue
#if os(Linux)
if setNonBlocking {
@ -176,7 +179,7 @@ class BaseSocket: BaseSocketProtocol {
#endif
let sock = try NIOBSDSocket.socket(domain: protocolFamily,
type: NIOBSDSocket.SocketType(rawValue: sockType),
protocol: CInt(protocolSubtype))
protocolSubtype: protocolSubtype)
#if !os(Linux)
if setNonBlocking {
do {
@ -205,7 +208,7 @@ class BaseSocket: BaseSocketProtocol {
}
return sock
}
/// Cleanup the unix domain socket.
///
/// Deletes the associated file if it exists and has socket type. Does nothing if pathname does not exist.

View File

@ -1085,7 +1085,8 @@ public final class DatagramBootstrap {
}
func makeChannel(_ eventLoop: SelectableEventLoop) throws -> DatagramChannel {
return try DatagramChannel(eventLoop: eventLoop,
protocolFamily: address.protocol)
protocolFamily: address.protocol,
protocolSubtype: .default)
}
return withNewChannel(makeChannel: makeChannel) { (eventLoop, channel) in
channel.register().flatMap {
@ -1132,7 +1133,8 @@ public final class DatagramBootstrap {
}
func makeChannel(_ eventLoop: SelectableEventLoop) throws -> DatagramChannel {
return try DatagramChannel(eventLoop: eventLoop,
protocolFamily: address.protocol)
protocolFamily: address.protocol,
protocolSubtype: .default)
}
return withNewChannel(makeChannel: makeChannel) { (eventLoop, channel) in
channel.register().flatMap {
@ -1182,6 +1184,7 @@ public final class DatagramBootstrap {
extension DatagramBootstrap: Sendable {}
#endif
/// A `NIOPipeBootstrap` is an easy way to bootstrap a `PipeChannel` which uses two (uni-directional) UNIX pipes
/// and makes a `Channel` out of them.
///

View File

@ -34,7 +34,7 @@ import NIOCore
/// argument to the socket syscall. Defaults to 0.
/// - setNonBlocking: Set non-blocking mode on the socket.
/// - throws: An `IOError` if creation of the socket failed.
init(protocolFamily: NIOBSDSocket.ProtocolFamily, protocolSubtype: Int = 0, setNonBlocking: Bool = false) throws {
init(protocolFamily: NIOBSDSocket.ProtocolFamily, protocolSubtype: NIOBSDSocket.ProtocolSubtype = .default, setNonBlocking: Bool = false) throws {
let sock = try BaseSocket.makeSocket(protocolFamily: protocolFamily, type: .stream, protocolSubtype: protocolSubtype, setNonBlocking: setNonBlocking)
switch protocolFamily {
case .unix:

View File

@ -36,8 +36,18 @@ typealias IOVector = iovec
/// argument to the socket syscall. Defaults to 0.
/// - setNonBlocking: Set non-blocking mode on the socket.
/// - throws: An `IOError` if creation of the socket failed.
init(protocolFamily: NIOBSDSocket.ProtocolFamily, type: NIOBSDSocket.SocketType, protocolSubtype: Int = 0, setNonBlocking: Bool = false) throws {
let sock = try BaseSocket.makeSocket(protocolFamily: protocolFamily, type: type, protocolSubtype: protocolSubtype, setNonBlocking: setNonBlocking)
init(
protocolFamily: NIOBSDSocket.ProtocolFamily,
type: NIOBSDSocket.SocketType,
protocolSubtype: NIOBSDSocket.ProtocolSubtype = .default,
setNonBlocking: Bool = false
) throws {
let sock = try BaseSocket.makeSocket(
protocolFamily: protocolFamily,
type: type,
protocolSubtype: protocolSubtype,
setNonBlocking: setNonBlocking
)
try super.init(socket: sock)
}

View File

@ -51,9 +51,9 @@ final class SocketChannel: BaseStreamSocketChannel<Socket> {
private var connectTimeout: TimeAmount? = nil
init(eventLoop: SelectableEventLoop, protocolFamily: NIOBSDSocket.ProtocolFamily, enableMPTCP: Bool = false) throws {
var protocolSubtype = 0
var protocolSubtype = NIOBSDSocket.ProtocolSubtype.default
if enableMPTCP {
guard let subtype = NIOBSDSocket.mptcpProtocolSubtype else {
guard let subtype = NIOBSDSocket.ProtocolSubtype.mptcp else {
throw ChannelError.operationUnsupported
}
protocolSubtype = subtype
@ -162,9 +162,9 @@ final class ServerSocketChannel: BaseSocketChannel<ServerSocket> {
override public var isWritable: Bool { return false }
convenience init(eventLoop: SelectableEventLoop, group: EventLoopGroup, protocolFamily: NIOBSDSocket.ProtocolFamily, enableMPTCP: Bool = false) throws {
var protocolSubtype = 0
var protocolSubtype = NIOBSDSocket.ProtocolSubtype.default
if enableMPTCP {
guard let subtype = NIOBSDSocket.mptcpProtocolSubtype else {
guard let subtype = NIOBSDSocket.ProtocolSubtype.mptcp else {
throw ChannelError.operationUnsupported
}
protocolSubtype = subtype
@ -404,9 +404,18 @@ final class DatagramChannel: BaseSocketChannel<Socket> {
}
}
init(eventLoop: SelectableEventLoop, protocolFamily: NIOBSDSocket.ProtocolFamily) throws {
init(
eventLoop: SelectableEventLoop,
protocolFamily: NIOBSDSocket.ProtocolFamily,
protocolSubtype: NIOBSDSocket.ProtocolSubtype,
socketType: NIOBSDSocket.SocketType = .datagram
) throws {
self.vectorReadManager = nil
let socket = try Socket(protocolFamily: protocolFamily, type: .datagram)
let socket = try Socket(
protocolFamily: protocolFamily,
type: socketType,
protocolSubtype: protocolSubtype
)
do {
try socket.setNonBlocking()
} catch let err {

View File

@ -495,9 +495,9 @@ internal enum Posix {
}
@inline(never)
internal static func socket(domain: NIOBSDSocket.ProtocolFamily, type: NIOBSDSocket.SocketType, `protocol`: CInt) throws -> CInt {
internal static func socket(domain: NIOBSDSocket.ProtocolFamily, type: NIOBSDSocket.SocketType, protocolSubtype: NIOBSDSocket.ProtocolSubtype) throws -> CInt {
return try syscall(blocking: false) {
return sysSocket(domain.rawValue, type.rawValue, `protocol`)
return sysSocket(domain.rawValue, type.rawValue, protocolSubtype.rawValue)
}.result
}
@ -840,10 +840,10 @@ internal enum Posix {
@inline(never)
internal static func socketpair(domain: NIOBSDSocket.ProtocolFamily,
type: NIOBSDSocket.SocketType,
protocol: CInt,
protocolSubtype: NIOBSDSocket.ProtocolSubtype,
socketVector: UnsafeMutablePointer<CInt>?) throws {
_ = try syscall(blocking: false) {
sysSocketpair(domain.rawValue, type.rawValue, `protocol`, socketVector)
sysSocketpair(domain.rawValue, type.rawValue, protocolSubtype.rawValue, socketVector)
}
}
#endif

View File

@ -153,7 +153,7 @@ class BootstrapTest: XCTestCase {
var socketFDs: [CInt] = [-1, -1]
XCTAssertNoThrow(try Posix.socketpair(domain: .local,
type: .stream,
protocol: 0,
protocolSubtype: .default,
socketVector: &socketFDs))
defer {
// 0 is closed together with the Channel below.
@ -173,7 +173,7 @@ class BootstrapTest: XCTestCase {
func testPreConnectedServerSocketToleratesFuturesFromDifferentEventLoopsReturnedInInitializers() throws {
let socket =
try NIOBSDSocket.socket(domain: .inet, type: .stream, protocol: 0)
try NIOBSDSocket.socket(domain: .inet, type: .stream, protocolSubtype: .default)
let serverAddress = try assertNoThrowWithValue(SocketAddress.makeAddressResolvingHost("127.0.0.1", port: 0))
try serverAddress.withSockAddr { address, len in

View File

@ -1974,7 +1974,7 @@ public final class ChannelTests: XCTestCase {
func withChannel(skipDatagram: Bool = false, skipStream: Bool = false, skipServerSocket: Bool = false, file: StaticString = #filePath, line: UInt = #line, _ body: (Channel) throws -> Void) {
XCTAssertNoThrow(try {
let el = elg.next() as! SelectableEventLoop
let channels: [Channel] = (skipDatagram ? [] : [try DatagramChannel(eventLoop: el, protocolFamily: .inet)]) +
let channels: [Channel] = (skipDatagram ? [] : [try DatagramChannel(eventLoop: el, protocolFamily: .inet, protocolSubtype: .default)]) +
/* Xcode need help */ (skipStream ? []: [try SocketChannel(eventLoop: el, protocolFamily: .inet)]) +
/* Xcode need help */ (skipServerSocket ? []: [try ServerSocketChannel(eventLoop: el, group: elg, protocolFamily: .inet)])
for channel in channels {

View File

@ -381,7 +381,7 @@ class DatagramChannelTests: XCTestCase {
init(error: Int32) throws {
self.error = error
try super.init(protocolFamily: .inet, type: .datagram)
try super.init(protocolFamily: .inet, type: .datagram, protocolSubtype: .default)
}
override func recvmsg(pointer: UnsafeMutableRawBufferPointer,
@ -537,7 +537,8 @@ class DatagramChannelTests: XCTestCase {
XCTAssertNoThrow(try group.syncShutdownGracefully())
}
let channel = try DatagramChannel(eventLoop: group.next() as! SelectableEventLoop,
protocolFamily: .inet)
protocolFamily: .inet,
protocolSubtype: .default)
XCTAssertThrowsError(try channel.triggerUserOutboundEvent("event").wait()) { (error: Error) in
if let error = error as? ChannelError {
XCTAssertEqual(ChannelError.operationUnsupported, error)

View File

@ -146,7 +146,7 @@ final class PipeChannelTest: XCTestCase {
var socketPair: [CInt] = [-1, -1]
XCTAssertNoThrow(try socketPair.withUnsafeMutableBufferPointer { socketPairPtr in
precondition(socketPairPtr.count == 2)
try Posix.socketpair(domain: .local, type: .stream, protocol: 0, socketVector: socketPairPtr.baseAddress)
try Posix.socketpair(domain: .local, type: .stream, protocolSubtype: .default, socketVector: socketPairPtr.baseAddress)
})
defer {
XCTAssertNoThrow(try socketPair.filter { $0 > 0 }.forEach(Posix.close(descriptor:)))

View File

@ -40,7 +40,7 @@ class SelectorTest: XCTestCase {
XCTAssertNoThrow(try selector.close())
}
let socket1 = try Socket(protocolFamily: .inet, type: .stream)
let socket1 = try Socket(protocolFamily: .inet, type: .stream, protocolSubtype: .default)
defer {
if socket1.isOpen {
XCTAssertNoThrow(try socket1.close())
@ -48,7 +48,7 @@ class SelectorTest: XCTestCase {
}
try socket1.setNonBlocking()
let socket2 = try Socket(protocolFamily: .inet, type: .stream)
let socket2 = try Socket(protocolFamily: .inet, type: .stream, protocolSubtype: .default)
defer {
if socket2.isOpen {
XCTAssertNoThrow(try socket2.close())
@ -391,7 +391,7 @@ class SelectorTest: XCTestCase {
var socketFDs: [CInt] = [-1, -1]
XCTAssertNoThrow(try Posix.socketpair(domain: .local,
type: .stream,
protocol: 0,
protocolSubtype: .default,
socketVector: &socketFDs))
let numberFires = ManagedAtomic(0)