Skip to content

Commit ef5f7f5

Browse files
lorenteymilseman
authored andcommitted
Implement getnameinfo.
1 parent 008dc40 commit ef5f7f5

File tree

10 files changed

+306
-14
lines changed

10 files changed

+306
-14
lines changed

Sources/Samples/Connect.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ struct Connect: ParsableCommand {
6464
}
6565

6666
func run() throws {
67-
let addresses = try SocketAddress.resolve(
67+
let addresses = try SocketAddress.resolveName(
6868
hostname: nil,
6969
service: service,
7070
family: ipv6 ? .ipv6 : .ipv4,

Sources/Samples/Listen.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ struct Listen: ParsableCommand {
7676
}
7777

7878
func run() throws {
79-
let addresses = try SocketAddress.resolve(
79+
let addresses = try SocketAddress.resolveName(
8080
hostname: nil,
8181
service: service,
8282
flags: .canonicalName,

Sources/Samples/Resolve.swift

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ import System
1515
#endif
1616

1717
struct Resolve: ParsableCommand {
18+
static var configuration = CommandConfiguration(
19+
commandName: "resolve",
20+
abstract: "Resolve a pair of hostname/servicename strings to a list of socket addresses."
21+
)
22+
1823
@Argument(help: "The hostname to resolve")
1924
var hostname: String?
2025

@@ -39,8 +44,11 @@ struct Resolve: ParsableCommand {
3944
@Flag(help: "Resolve IPv6 addresses")
4045
var ipv6: Bool = false
4146

47+
@Flag(help: "Print the raw SocketAddress structures")
48+
var raw: Bool = false
49+
4250
func run() throws {
43-
var flags: SocketAddress.ResolverFlags = [.default, .all]
51+
var flags: SocketAddress.NameResolverFlags = [.default, .all]
4452
if canonicalName { flags.insert(.canonicalName) }
4553
if passive { flags.insert(.passive) }
4654
if numericHost { flags.insert(.numericHost) }
@@ -50,7 +58,7 @@ struct Resolve: ParsableCommand {
5058
if ipv4 { family = .ipv4 }
5159
if ipv6 { family = .ipv6 }
5260

53-
let results = try SocketAddress.resolve(
61+
let results = try SocketAddress.resolveName(
5462
hostname: hostname, service: service,
5563
flags: flags,
5664
family: family
@@ -59,7 +67,11 @@ struct Resolve: ParsableCommand {
5967
print("No results found")
6068
} else {
6169
for entry in results {
62-
print(entry)
70+
if raw {
71+
print(entry)
72+
} else {
73+
print(entry.niceDescription)
74+
}
6375
}
6476
}
6577
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
This source file is part of the Swift System open source project
3+
4+
Copyright (c) 2021 Apple Inc. and the Swift System project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See https://swift.org/LICENSE.txt for license information
8+
*/
9+
10+
import ArgumentParser
11+
#if SYSTEM_PACKAGE
12+
import SystemPackage
13+
#else
14+
import System
15+
#endif
16+
17+
struct ReverseResolve: ParsableCommand {
18+
static var configuration = CommandConfiguration(
19+
commandName: "reverse",
20+
abstract: "Resolve a numerical IP address and port number into a hostname/service string"
21+
)
22+
23+
@Argument(help: "The IP address to resolve")
24+
var address: String?
25+
26+
@Argument(help: "The port number to resolve")
27+
var port: String?
28+
29+
@Flag(help: "No fully qualified domain for local addresses")
30+
var nofqdn: Bool = false
31+
32+
@Flag(help: "Disable hostname resolution; hostname must be numeric address")
33+
var numericHost: Bool = false
34+
35+
@Flag(help: "Disable service resolution; service name must be numeric")
36+
var numericService: Bool = false
37+
38+
@Flag(help: "Look up a datagram service")
39+
var datagram: Bool = false
40+
41+
@Flag(help: "Allow IPv6 scope identifiers")
42+
var scopeid: Bool = false
43+
44+
func run() throws {
45+
// First, we need to get a sockaddr, so things start with forward resolution.
46+
let infos = try SocketAddress.resolveName(
47+
hostname: address,
48+
service: port,
49+
flags: [.numericHost, .numericService])
50+
51+
var results: Set<String> = []
52+
for info in infos {
53+
// Now try a reverse lookup.
54+
var flags: SocketAddress.AddressResolverFlags = []
55+
if nofqdn {
56+
flags.insert(.noFullyQualifiedDomain)
57+
}
58+
if numericHost {
59+
flags.insert(.numericHost)
60+
}
61+
if numericService {
62+
flags.insert(.numericService)
63+
}
64+
if datagram {
65+
flags.insert(.datagram)
66+
}
67+
if scopeid {
68+
flags.insert(.scopeIdentifier)
69+
}
70+
let (hostname, service) = try SocketAddress.resolveAddress(info.address, flags: flags)
71+
results.insert("\(hostname) \(service)")
72+
}
73+
for r in results.sorted() {
74+
print(r)
75+
}
76+
}
77+
}

Sources/Samples/Util.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ internal func complain(_ message: String) {
4040
}
4141
}
4242

43+
extension SocketAddress.Info {
44+
var niceDescription: String {
45+
var proto = ""
46+
switch self.protocol {
47+
case .udp: proto = "udp"
48+
case .tcp: proto = "tcp"
49+
default: proto = "\(self.protocol)"
50+
}
51+
return "\(address.niceDescription) (\(proto))"
52+
}
53+
}
54+
4355
extension SocketAddress {
4456
var niceDescription: String {
4557
if let ipv4 = self.ipv4 { return ipv4.description }

Sources/Samples/main.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ internal struct SystemSamples: ParsableCommand {
66
abstract: "A collection of little programs exercising some System features.",
77
subcommands: [
88
Resolve.self,
9+
ReverseResolve.self,
910
Connect.self,
1011
Listen.self,
1112
])

Sources/System/Internals/Constants.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,30 @@ internal var _AI_DEFAULT: CInt { AI_DEFAULT }
886886
@_alwaysEmitIntoClient
887887
internal var _AI_UNUSABLE: CInt { AI_UNUSABLE }
888888

889+
@_alwaysEmitIntoClient
890+
internal var _NI_NOFQDN: CInt { NI_NOFQDN }
891+
892+
@_alwaysEmitIntoClient
893+
internal var _NI_NUMERICHOST: CInt { NI_NUMERICHOST }
894+
895+
@_alwaysEmitIntoClient
896+
internal var _NI_NAMEREQD: CInt { NI_NAMEREQD }
897+
898+
@_alwaysEmitIntoClient
899+
internal var _NI_NUMERICSERV: CInt { NI_NUMERICSERV }
900+
901+
@_alwaysEmitIntoClient
902+
internal var _NI_DGRAM: CInt { NI_DGRAM }
903+
904+
@_alwaysEmitIntoClient
905+
internal var _NI_WITHSCOPEID: CInt { NI_WITHSCOPEID }
906+
907+
@_alwaysEmitIntoClient
908+
internal var _NI_MAXHOST: CInt { NI_MAXHOST }
909+
910+
@_alwaysEmitIntoClient
911+
internal var _NI_MAXSERV: CInt { NI_MAXSERV }
912+
889913
@_alwaysEmitIntoClient
890914
internal var _EAI_ADDRFAMILY: CInt { EAI_ADDRFAMILY }
891915

Sources/System/Internals/Exports.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ internal func system_strerror(_ __errnum: Int32) -> UnsafeMutablePointer<Int8>!
6060
strerror(__errnum)
6161
}
6262

63-
internal func system_strlen(_ s: UnsafePointer<Int8>) -> Int {
63+
internal func system_strlen(_ s: UnsafePointer<CChar>) -> Int {
64+
strlen(s)
65+
}
66+
internal func system_strlen(_ s: UnsafeMutablePointer<CChar>) -> Int {
6467
strlen(s)
6568
}
6669

Sources/System/Internals/Syscalls.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,23 @@ internal func system_getaddrinfo(
307307
return getaddrinfo(hostname, servname, hints, res)
308308
}
309309

310+
internal func system_getnameinfo(
311+
_ sa: UnsafePointer<CInterop.SockAddr>?,
312+
_ salen: CInterop.SockLen,
313+
_ host: UnsafeMutablePointer<CChar>?,
314+
_ hostlen: CInterop.SockLen,
315+
_ serv: UnsafeMutablePointer<CChar>?,
316+
_ servlen: CInterop.SockLen,
317+
_ flags: CInt
318+
) -> CInt {
319+
#if ENABLE_MOCKING
320+
if mockingEnabled {
321+
return _mock(sa, salen, host, hostlen, serv, servlen, flags)
322+
}
323+
#endif
324+
return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
325+
}
326+
310327
internal func system_freeaddrinfo(
311328
_ addrinfo: UnsafeMutablePointer<CInterop.AddrInfo>?
312329
) {

0 commit comments

Comments
 (0)