Skip to content

Commit

Permalink
ajust netaddr & more test (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
MacOMNI authored Oct 22, 2024
1 parent 52fde8a commit 1fd9381
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 26 deletions.
87 changes: 61 additions & 26 deletions Networking/Sources/MsQuicSwift/NetAddr.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import CHelpers
import Foundation
import msquic

#if canImport(Glibc)
import Glibc
#elseif canImport(Darwin)
Expand Down Expand Up @@ -74,11 +75,12 @@ extension NetAddr: CustomStringConvertible {

private func parseQuicAddr(_ addr: QUIC_ADDR) -> (String, UInt16, Bool)? {
let ipv6 = addr.Ip.sa_family == QUIC_ADDRESS_FAMILY(QUIC_ADDRESS_FAMILY_INET6)
let port = if ipv6 {
helper_ntohs(addr.Ipv6.sin6_port)
} else {
helper_ntohs(addr.Ipv4.sin_port)
}
let port =
if ipv6 {
helper_ntohs(addr.Ipv6.sin6_port)
} else {
helper_ntohs(addr.Ipv4.sin_port)
}
var addr = addr
if ipv6 {
addr.Ipv6.sin6_port = 0
Expand All @@ -99,29 +101,62 @@ private func parseQuicAddr(_ addr: QUIC_ADDR) -> (String, UInt16, Bool)? {
return (ipAddr, port, ipv6)
}

private func parseIpv6Addr(_ address: String) -> (String, UInt16)? {
let parts = address.split(separator: "]:")
guard parts.count == 2 else {
return nil
}
let host = String(parts[0])
let port = parts[1].dropFirst()
guard let portNum = UInt16(port, radix: 10) else {
return nil
private func parseIpv4Addr(_ address: String) -> (String, UInt16)? {
let ipv4Pattern =
#"((?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"#
let ipv4WithPortPattern = #"(\#(ipv4Pattern)):(\d{1,5})"#

let regex = try? NSRegularExpression(pattern: ipv4WithPortPattern, options: [])
let range = NSRange(location: 0, length: address.utf16.count)

if let match = regex?.firstMatch(in: address, options: [], range: range) {
let ipRange = Range(match.range(at: 1), in: address)!
let portRange = Range(match.range(at: 3), in: address)!

let ip = String(address[ipRange])
let portString = String(address[portRange])

if let port = UInt16(portString) {
return (ip, port)
}
}
return (host, portNum)
return nil
}

private func parseIpv4Addr(_ address: String) -> (String, UInt16)? {
print(address)
let parts = address.split(separator: ":")
guard parts.count == 2 else {
return nil
}
let host = String(parts[0])
let port = parts[1].dropFirst()
guard let portNum = UInt16(port, radix: 10) else {
return nil
private func parseIpv6Addr(_ address: String) -> (String, UInt16)? {
let ipv6Pattern = [
"(?:",
"(?:(?:[0-9A-Fa-f]{1,4}:){6}",
"|::(?:[0-9A-Fa-f]{1,4}:){5}",
"|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}",
"|(?:(?:[0-9A-Fa-f]{1,4}:){0,1}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}",
"|(?:(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}",
"|(?:(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:",
"|(?:(?:[0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})?::)",
"(?:",
"[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}",
"|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}",
"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",
")",
"|(?:(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}",
"|(?:(?:[0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})?::",
")",
].reduce("", +)
let ipv6WithPortPattern = #"\[(\#(ipv6Pattern))\]:(\d{1,5})"#

let regex = try? NSRegularExpression(pattern: ipv6WithPortPattern, options: [])
let range = NSRange(location: 0, length: address.utf16.count)

if let match = regex?.firstMatch(in: address, options: [], range: range) {
let ipRange = Range(match.range(at: 1), in: address)!
let portRange = Range(match.range(at: 2), in: address)!

let ip = String(address[ipRange])
let portString = String(address[portRange])

if let port = UInt16(portString) {
return (ip, port)
}
}
return (host, portNum)
return nil
}
90 changes: 90 additions & 0 deletions Networking/Tests/MsQuicSwiftTests/NetAddrTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import Foundation
import MsQuicSwift
@testable import Networking
import Testing

struct NetAddrTests {
@Test
func parseValidIPv4() async throws {
let address = "127.0.0.1:9955"
let netAddr1 = NetAddr(address: address)
let netAddr2 = NetAddr(ipAddress: "127.0.0.1", port: 9955)
#expect(netAddr1!.getAddressAndPort() == ("127.0.0.1", 9955))
#expect(netAddr2!.getAddressAndPort() == ("127.0.0.1", 9955))
}

@Test
func parseValidIPv6Full() async throws {
let address = "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:8080"
let netAddr1 = NetAddr(address: address)
let netAddr2 = NetAddr(ipAddress: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", port: 8080)
#expect(netAddr1!.getAddressAndPort() == ("2001:db8:85a3::8a2e:370:7334", 8080))
#expect(netAddr2!.getAddressAndPort() == ("2001:db8:85a3::8a2e:370:7334", 8080))
}

@Test
func parseValidIPv6Compressed() async throws {
let address = "[2001:db8:85a3::8a2e:370:7334]:8080"
let netAddr1 = NetAddr(address: address)
let netAddr2 = NetAddr(ipAddress: "2001:db8:85a3::8a2e:370:7334", port: 8080)
#expect(netAddr1 != nil)
#expect(netAddr2 != nil)
#expect(netAddr1!.getAddressAndPort() == ("2001:db8:85a3::8a2e:370:7334", 8080))
#expect(netAddr2!.getAddressAndPort() == ("2001:db8:85a3::8a2e:370:7334", 8080))
}

@Test
func parseValidIPv6Loopback() async throws {
let address = "[::1]:8080"
let netAddr1 = NetAddr(address: address)
let netAddr2 = NetAddr(ipAddress: "::1", port: 8080)
#expect(netAddr1!.getAddressAndPort() == ("::1", 8080))
#expect(netAddr2!.getAddressAndPort() == ("::1", 8080))
}

@Test
func parseInvalidMissingPort() async throws {
let address = "127.0.0.1"
let netAddr = NetAddr(address: address)
#expect(netAddr == nil)
}

@Test
func parseInvalidFormat() async throws {
let address = "abcd:::"
let netAddr = NetAddr(address: address)
#expect(netAddr == nil)
}

@Test
func parseInvalidPortIPv4() async throws {
let address = "127.0.0.1:75535"
let netAddr1 = NetAddr(address: address)
#expect(netAddr1 == nil)
}

@Test
func parseInvalidPortIPv6() async throws {
let address = "[2001:db8::1]:75535"
let netAddr1 = NetAddr(address: address)
#expect(netAddr1 == nil)
}

@Test
func parseInvalidIPv4Format() async throws {
let address = "256.256.256.256:8080"
let netAddr1 = NetAddr(address: address)
let netAddr2 = NetAddr(ipAddress: "256.256.256.256", port: 8080)
#expect(netAddr1 == nil)
#expect(netAddr2 == nil)
}

@Test
func parseInvalidIPv6Format() async throws {
let address = "[2001:db8:::1]:8080"
let netAddr1 = NetAddr(address: address)
let netAddr2 = NetAddr(ipAddress: "2001:db8:::1", port: 8080)
#expect(netAddr1 == nil)
#expect(netAddr2 == nil)
}
}

0 comments on commit 1fd9381

Please sign in to comment.