Skip to content

Commit 661207f

Browse files
committed
WIP: Apply doc comments and make concrete socket addresses optional properties.
1 parent bca51a4 commit 661207f

File tree

9 files changed

+171
-148
lines changed

9 files changed

+171
-148
lines changed

Sources/Samples/Resolve.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,7 @@ struct Resolve: ParsableCommand {
4040
var ipv6: Bool = false
4141

4242
func run() throws {
43-
var flags = SocketAddress.ResolverFlags()
44-
flags.insert(.default)
45-
flags.insert(.all)
43+
var flags: SocketAddress.ResolverFlags = [.default, .all]
4644
if canonicalName { flags.insert(.canonicalName) }
4745
if passive { flags.insert(.passive) }
4846
if numericHost { flags.insert(.numericHost) }

Sources/System/Sockets/SocketAddress+IPv4.swift

Lines changed: 28 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,6 @@ extension SocketAddress {
1919
self.rawValue = rawValue
2020
self.rawValue.sin_family = Family.ipv4.rawValue
2121
}
22-
23-
public init?(_ address: SocketAddress) {
24-
guard address.family == .ipv4 else { return nil }
25-
let value: CInterop.SockAddrIn? = address.withUnsafeBytes { buffer in
26-
guard buffer.count >= MemoryLayout<CInterop.SockAddrIn>.size else {
27-
return nil
28-
}
29-
return buffer.baseAddress!.load(as: CInterop.SockAddrIn.self)
30-
}
31-
guard let value = value else { return nil }
32-
self.rawValue = value
33-
}
3422
}
3523
}
3624

@@ -43,21 +31,36 @@ extension SocketAddress {
4331
SocketAddress(buffer)
4432
}
4533
}
34+
35+
/// If `self` holds an IPv4 address, extract it, otherwise return `nil`.
36+
@_alwaysEmitIntoClient
37+
public var ipv4: IPv4? {
38+
guard family == .ipv4 else { return nil }
39+
let value: CInterop.SockAddrIn? = self.withUnsafeBytes { buffer in
40+
guard buffer.count >= MemoryLayout<CInterop.SockAddrIn>.size else {
41+
return nil
42+
}
43+
return buffer.baseAddress!.load(as: CInterop.SockAddrIn.self)
44+
}
45+
guard let value = value else { return nil }
46+
return IPv4(rawValue: value)
47+
}
4648
}
4749

4850
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
4951
extension SocketAddress.IPv4 {
5052
/// Create a socket address from a given Internet address and port number.
5153
@_alwaysEmitIntoClient
52-
public init(address: Address, port: Port) {
54+
public init(address: Address, port: SocketAddress.Port) {
5355
rawValue = CInterop.SockAddrIn()
5456
rawValue.sin_family = CInterop.SAFamily(SocketDescriptor.Domain.ipv4.rawValue);
5557
rawValue.sin_port = port.rawValue._networkOrder
5658
rawValue.sin_addr = CInterop.InAddr(s_addr: address.rawValue._networkOrder)
5759
}
5860

61+
/// TODO: doc
5962
@_alwaysEmitIntoClient
60-
public init?(address: String, port: Port) {
63+
public init?(address: String, port: SocketAddress.Port) {
6164
guard let address = Address(address) else { return nil }
6265
self.init(address: address, port: port)
6366
}
@@ -84,44 +87,6 @@ extension SocketAddress.IPv4: CustomStringConvertible {
8487
}
8588
}
8689

87-
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
88-
extension SocketAddress.IPv4 {
89-
@frozen
90-
/// The port number on which the socket is listening.
91-
public struct Port: RawRepresentable, ExpressibleByIntegerLiteral, Hashable {
92-
/// The port number, in host byte order.
93-
public var rawValue: CInterop.InPort
94-
95-
@_alwaysEmitIntoClient
96-
public init(_ value: CInterop.InPort) {
97-
self.rawValue = value
98-
}
99-
100-
@_alwaysEmitIntoClient
101-
public init(rawValue: CInterop.InPort) {
102-
self.init(rawValue)
103-
}
104-
105-
@_alwaysEmitIntoClient
106-
public init(integerLiteral value: CInterop.InPort) {
107-
self.init(value)
108-
}
109-
}
110-
111-
@_alwaysEmitIntoClient
112-
public var port: Port {
113-
get { Port(CInterop.InPort(_networkOrder: rawValue.sin_port)) }
114-
set { rawValue.sin_port = newValue.rawValue._networkOrder }
115-
}
116-
}
117-
118-
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
119-
extension SocketAddress.IPv4.Port: CustomStringConvertible {
120-
public var description: String {
121-
rawValue.description
122-
}
123-
}
124-
12590
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
12691
extension SocketAddress.IPv4 {
12792
@frozen
@@ -134,13 +99,9 @@ extension SocketAddress.IPv4 {
13499
public init(rawValue: CInterop.InAddrT) {
135100
self.rawValue = rawValue
136101
}
137-
138-
@_alwaysEmitIntoClient
139-
public init(_ value: CInterop.InAddrT) {
140-
self.rawValue = value
141-
}
142102
}
143103

104+
/// The 32-bit IPv4 address.
144105
@_alwaysEmitIntoClient
145106
public var address: Address {
146107
get {
@@ -151,38 +112,40 @@ extension SocketAddress.IPv4 {
151112
rawValue.sin_addr.s_addr = newValue.rawValue._networkOrder
152113
}
153114
}
115+
116+
@_alwaysEmitIntoClient
117+
public var port: SocketAddress.Port {
118+
get { SocketAddress.Port(CInterop.InPort(_networkOrder: rawValue.sin_port)) }
119+
set { rawValue.sin_port = newValue.rawValue._networkOrder }
120+
}
154121
}
155122

156123
extension SocketAddress.IPv4.Address {
157124
/// The IPv4 address 0.0.0.0.
158125
///
159126
/// This corresponds to the C constant `INADDR_ANY`.
160127
@_alwaysEmitIntoClient
161-
public static var any: Self { Self(_INADDR_ANY) }
128+
public static var any: Self { Self(rawValue: _INADDR_ANY) }
162129

163130
/// The IPv4 loopback address 127.0.0.1.
164131
///
165-
/// This corresponds to the C constant `INADDR_ANY`.
132+
/// This corresponds to the C constant `INADDR_LOOPBACK`.
166133
@_alwaysEmitIntoClient
167-
public static var loopback: Self { Self(_INADDR_LOOPBACK) }
134+
public static var loopback: Self { Self(rawValue: _INADDR_LOOPBACK) }
168135

169136
/// The IPv4 broadcast address 255.255.255.255.
170137
///
171138
/// This corresponds to the C constant `INADDR_BROADCAST`.
172139
@_alwaysEmitIntoClient
173-
public static var broadcast: Self { Self(_INADDR_BROADCAST) }
140+
public static var broadcast: Self { Self(rawValue: _INADDR_BROADCAST) }
174141
}
175142

176-
177-
178143
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
179144
extension SocketAddress.IPv4.Address: CustomStringConvertible {
180-
@_alwaysEmitIntoClient
181145
public var description: String {
182146
_inet_ntop()
183147
}
184148

185-
@usableFromInline
186149
internal func _inet_ntop() -> String {
187150
let addr = CInterop.InAddr(s_addr: rawValue._networkOrder)
188151
return withUnsafeBytes(of: addr) { src in
@@ -211,13 +174,11 @@ extension SocketAddress.IPv4.Address: CustomStringConvertible {
211174

212175
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
213176
extension SocketAddress.IPv4.Address: LosslessStringConvertible {
214-
@_alwaysEmitIntoClient
215177
public init?(_ description: String) {
216178
guard let value = Self._inet_pton(description) else { return nil }
217179
self = value
218180
}
219181

220-
@usableFromInline
221182
internal static func _inet_pton(_ string: String) -> Self? {
222183
string.withCString { ptr in
223184
var addr = CInterop.InAddr()

Sources/System/Sockets/SocketAddress+IPv6.swift

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,6 @@ extension SocketAddress {
1919
self.rawValue = rawValue
2020
self.rawValue.sin6_family = Family.ipv6.rawValue
2121
}
22-
23-
@_alwaysEmitIntoClient
24-
public init?(_ address: SocketAddress) {
25-
guard address.family == .ipv6 else { return nil }
26-
let value: CInterop.SockAddrIn6? = address.withUnsafeBytes { buffer in
27-
guard buffer.count >= MemoryLayout<CInterop.SockAddrIn6>.size else {
28-
return nil
29-
}
30-
return buffer.baseAddress!.load(as: CInterop.SockAddrIn6.self)
31-
}
32-
guard let value = value else { return nil }
33-
self.rawValue = value
34-
}
3522
}
3623
}
3724

@@ -44,13 +31,28 @@ extension SocketAddress {
4431
SocketAddress(buffer)
4532
}
4633
}
34+
35+
/// If `self` holds an IPv6 address, extract it, otherwise return `nil`.
36+
@_alwaysEmitIntoClient
37+
public var ipv6: IPv6? {
38+
guard family == .ipv6 else { return nil }
39+
let value: CInterop.SockAddrIn6? = self.withUnsafeBytes { buffer in
40+
guard buffer.count >= MemoryLayout<CInterop.SockAddrIn6>.size else {
41+
return nil
42+
}
43+
return buffer.baseAddress!.load(as: CInterop.SockAddrIn6.self)
44+
}
45+
guard let value = value else { return nil }
46+
return IPv6(rawValue: value)
47+
}
48+
4749
}
4850

4951
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
5052
extension SocketAddress.IPv6 {
5153
/// Create a socket address from an IPv6 address and port number.
5254
@_alwaysEmitIntoClient
53-
public init(address: Address, port: Port) {
55+
public init(address: Address, port: SocketAddress.Port) {
5456
// FIXME: We aren't modeling flowinfo & scope_id yet.
5557
// If we need to do that, we can add new arguments or define new
5658
// initializers/accessors later.
@@ -63,7 +65,7 @@ extension SocketAddress.IPv6 {
6365
}
6466

6567
@_alwaysEmitIntoClient
66-
public init?(address: String, port: Port) {
68+
public init?(address: String, port: SocketAddress.Port) {
6769
guard let address = Address(address) else { return nil }
6870
self.init(address: address, port: port)
6971
}
@@ -97,11 +99,9 @@ extension SocketAddress.IPv6: CustomStringConvertible {
9799

98100
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
99101
extension SocketAddress.IPv6 {
100-
public typealias Port = SocketAddress.IPv4.Port
101-
102102
@_alwaysEmitIntoClient
103-
public var port: Port {
104-
get { Port(CInterop.InPort(_networkOrder: rawValue.sin6_port)) }
103+
public var port: SocketAddress.Port {
104+
get { SocketAddress.Port(CInterop.InPort(_networkOrder: rawValue.sin6_port)) }
105105
set { rawValue.sin6_port = newValue.rawValue._networkOrder }
106106
}
107107
}
@@ -118,13 +118,9 @@ extension SocketAddress.IPv6 {
118118
public init(rawValue: CInterop.In6Addr) {
119119
self.rawValue = rawValue
120120
}
121-
122-
@_alwaysEmitIntoClient
123-
public init(_ value: CInterop.In6Addr) {
124-
self.rawValue = value
125-
}
126121
}
127122

123+
/// The 128-bit IPv6 address.
128124
@_alwaysEmitIntoClient
129125
public var address: Address {
130126
get {
@@ -142,7 +138,7 @@ extension SocketAddress.IPv6.Address {
142138
/// This corresponds to the C constant `IN6ADDR_ANY_INIT`.
143139
@_alwaysEmitIntoClient
144140
public static var any: Self {
145-
Self(CInterop.In6Addr())
141+
Self(rawValue: CInterop.In6Addr())
146142
}
147143

148144
/// The IPv4 loopback address "::1".
@@ -152,7 +148,7 @@ extension SocketAddress.IPv6.Address {
152148
public static var loopback: Self {
153149
var addr = CInterop.In6Addr()
154150
addr.__u6_addr.__u6_addr8.15 = 1
155-
return Self(addr)
151+
return Self(rawValue: addr)
156152
}
157153
}
158154

@@ -193,12 +189,10 @@ extension SocketAddress.IPv6.Address: Hashable {
193189

194190
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
195191
extension SocketAddress.IPv6.Address: CustomStringConvertible {
196-
@_alwaysEmitIntoClient
197192
public var description: String {
198193
_inet_ntop()
199194
}
200195

201-
@usableFromInline
202196
internal func _inet_ntop() -> String {
203197
return withUnsafeBytes(of: rawValue) { src in
204198
String(_unsafeUninitializedCapacity: Int(_INET6_ADDRSTRLEN)) { dst in
@@ -226,13 +220,11 @@ extension SocketAddress.IPv6.Address: CustomStringConvertible {
226220

227221
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
228222
extension SocketAddress.IPv6.Address: LosslessStringConvertible {
229-
@_alwaysEmitIntoClient
230223
public init?(_ description: String) {
231224
guard let value = Self._inet_pton(description) else { return nil }
232225
self = value
233226
}
234227

235-
@usableFromInline
236228
internal static func _inet_pton(_ string: String) -> Self? {
237229
string.withCString { ptr in
238230
var addr = CInterop.In6Addr()

Sources/System/Sockets/SocketAddress+Local.swift

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,26 @@ private var _pathOffset: Int {
1414

1515
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
1616
extension SocketAddress {
17+
/// A "local" (i.e. UNIX domain) socket address, for inter-process
18+
/// communication on the same machine.
19+
///
20+
/// The corresponding C type is `sockaddr_un`.
1721
public struct Local {
1822
internal let _path: FilePath
1923

24+
/// A "local" (i.e. UNIX domain) socket address, for inter-process
25+
/// communication on the same machine.
26+
///
27+
/// The corresponding C type is `sockaddr_un`.
2028
public init(_ path: FilePath) {
2129
self._path = path
2230
}
23-
24-
public init?(_ address: SocketAddress) {
25-
guard address.family == .local else { return nil }
26-
let path: FilePath? = address.withUnsafeBytes { buffer in
27-
guard buffer.count >= _pathOffset + 1 else {
28-
return nil
29-
}
30-
let path = (buffer.baseAddress! + _pathOffset)
31-
.assumingMemoryBound(to: CInterop.PlatformChar.self)
32-
return FilePath(platformString: path)
33-
}
34-
guard path != nil else { return nil }
35-
self._path = path!
36-
}
3731
}
3832
}
3933

4034
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
4135
extension SocketAddress {
36+
/// Create a SocketAddress from a local (i.e. UNIX domain) socket address.
4237
public init(_ local: Local) {
4338
let offset = _pathOffset
4439
let length = offset + local._path.length + 1
@@ -57,10 +52,28 @@ extension SocketAddress {
5752
return length
5853
}
5954
}
55+
56+
/// If `self` holds a local address, extract it, otherwise return `nil`.
57+
public var local: Local? {
58+
guard family == .local else { return nil }
59+
let path: FilePath? = self.withUnsafeBytes { buffer in
60+
guard buffer.count >= _pathOffset + 1 else {
61+
return nil
62+
}
63+
let path = (buffer.baseAddress! + _pathOffset)
64+
.assumingMemoryBound(to: CInterop.PlatformChar.self)
65+
return FilePath(platformString: path)
66+
}
67+
guard path != nil else { return nil }
68+
return Local(path!)
69+
}
6070
}
6171

6272
// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
6373
extension SocketAddress.Local {
74+
/// The path to the file used to advertise the socket name to clients.
75+
///
76+
/// The corresponding C struct member is `sun_path`.
6477
public var path: FilePath { _path }
6578
}
6679

0 commit comments

Comments
 (0)