Skip to content

Commit

Permalink
Release 1.0.5
Browse files Browse the repository at this point in the history
  • Loading branch information
shineRR committed Jun 9, 2024
1 parent 5e5602d commit 7c34ec8
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 20 deletions.
4 changes: 2 additions & 2 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PODS:
- pingx (1.0.4)
- pingx (1.0.5)

DEPENDENCIES:
- pingx (from `../`)
Expand All @@ -9,7 +9,7 @@ EXTERNAL SOURCES:
:path: "../"

SPEC CHECKSUMS:
pingx: 79bde65bdb1d8501b3dd442a41534aff26b91532
pingx: 59bea7dc11f0ebff026dbb82e018054c9307beff

PODFILE CHECKSUM: 51a1c6604e794a42ac9e68fbc4b6a076498be182

Expand Down
14 changes: 12 additions & 2 deletions Sources/pingx/Checksum/Impl/ICMPChecksum.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Foundation
// MARK: - ICMPChecksum

struct ICMPChecksum {
func callAsFunction(header: ICMPHeader) -> UInt16 {
func callAsFunction(header: ICMPHeader) throws -> UInt16 {
let typecode = Data([header.type, header.code]).withUnsafeBytes { $0.load(as: UInt16.self) }
var sum = UInt64(typecode) + UInt64(header.identifier) + UInt64(header.sequenceNumber)
let payload = arrayPayload(header.payload)
Expand All @@ -15,11 +15,21 @@ struct ICMPChecksum {
sum = (sum >> 16) + (sum & 0xFFFF)
sum += sum >> 16

guard sum >= UInt16.min, sum <= UInt16.max else { throw ChecksumError.outOfBounds }

return ~UInt16(sum)
}
}

// MARK: Private API
// MARK: - ChecksumError

extension ICMPChecksum {
enum ChecksumError: Error {
case outOfBounds
}
}

// MARK: - Private API

private extension ICMPChecksum {
private func arrayPayload(_ payload: Payload) -> [UInt8] {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// MARK: - PacketFactory

protocol PacketFactory {
func create(type: PacketType) -> Packet
func create(type: PacketType) throws -> Packet
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import Foundation
// MARK: - PacketFactoryImpl

final class PacketFactoryImpl: PacketFactory {
func create(type: PacketType) -> Packet {
func create(type: PacketType) throws -> Packet {
let packet: Packet

switch type {
case .icmp:
packet = icmpPacket()
packet = try icmpPacket()
}

return packet
Expand All @@ -18,14 +18,14 @@ final class PacketFactoryImpl: PacketFactory {
// MARK: - Private API

private extension PacketFactoryImpl {
func icmpPacket() -> Packet {
func icmpPacket() throws -> Packet {
var icmpHeader = ICMPHeader(
type: .echoRequest,
identifier: CFSwapInt16HostToBig(UInt16.random(in: 0..<UInt16.max)),
sequenceNumber: CFSwapInt16HostToBig(UInt16.random(in: 0..<UInt16.max)),
payload: Payload()
)
let checksum = ICMPChecksum()(header: icmpHeader)
let checksum = try ICMPChecksum()(header: icmpHeader)

icmpHeader.setChecksum(checksum)

Expand Down
8 changes: 7 additions & 1 deletion Sources/pingx/PacketSender/Impl/PacketSenderImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,14 @@ private extension PacketSenderImpl {
extension PacketSenderImpl: PacketSender {
func send(_ request: Request) throws {
try checkSocketCreation()
let packet: Packet

do {
packet = try packetFactory.create(type: request.type)
} catch {
throw PacketSenderError.error
}

let packet = packetFactory.create(type: request.type)
let error = pingxSocket.send(
address: request.destination.socketAddress as CFData,
data: packet.data as CFData,
Expand Down
10 changes: 7 additions & 3 deletions Sources/pingx/Pinger/Api/Pinger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,13 @@ extension Pinger {
throw ICMPResponseValidationError.invalidCode(icmpPackage.ipHeader)
}

let checksum = ICMPChecksum()(header: icmpPackage.icmpHeader)

guard icmpPackage.icmpHeader.checksum == checksum else {
do {
let checksum = try ICMPChecksum()(header: icmpPackage.icmpHeader)

guard icmpPackage.icmpHeader.checksum == checksum else {
throw ICMPResponseValidationError.checksumMismatch(icmpPackage.ipHeader)
}
} catch {
throw ICMPResponseValidationError.checksumMismatch(icmpPackage.ipHeader)
}
}
Expand Down
3 changes: 0 additions & 3 deletions Sources/pingx/Pinger/Impl/ContinuousPinger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,6 @@ extension ContinuousPinger: Pinger {
} catch _ as PacketSenderError {
outgoingRequests.removeValue(forKey: request.destination)
delegate?.pinger(self, request: request, didCompleteWithError: .socketFailed)
} catch let error as PingerError {
outgoingRequests.removeValue(forKey: request.destination)
delegate?.pinger(self, request: request, didCompleteWithError: error)
} catch {}
}

Expand Down
16 changes: 15 additions & 1 deletion Tests/pingxTests/PacketSender/PacketSenderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ final class PacketSenderTests: XCTestCase {
// MARK: Properties

private var pinger: MockPinger!
private var packetFactory: PacketFactoryFake!
private var socketFactory: SocketFactoryFake!
private var packetSender: PacketSenderImpl!

Expand All @@ -16,7 +17,8 @@ final class PacketSenderTests: XCTestCase {
override func setUp() {
super.setUp()
socketFactory = SocketFactoryFake()
packetSender = PacketSenderImpl(socketFactory: socketFactory)
packetFactory = PacketFactoryFake()
packetSender = PacketSenderImpl(socketFactory: socketFactory, packetFactory: packetFactory)
pinger = MockPinger(packetSender: packetSender)
}

Expand Down Expand Up @@ -85,6 +87,18 @@ final class PacketSenderTests: XCTestCase {
XCTAssertTrue(pinger.didReceiveInvoked)
XCTAssertEqual(pinger.didReceiveData, data)
}

func testPacketSender_packet_creation_error() {
let request = Request(destination: Constants.ipv4)

packetFactory.error = ICMPChecksum.ChecksumError.outOfBounds
pinger.ping(request: request)

XCTAssertFalse(socketFactory.socket.sendInvoked)
XCTAssertNotNil(pinger.receivedError)
XCTAssertEqual(pinger.receivedError as? PacketSenderError, PacketSenderError.error)
XCTAssertNil(pinger.didReceiveData)
}
}

// MARK: - Constants
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Foundation
@testable import pingx

// MARK: - PacketFactoryFake

final class PacketFactoryFake: PacketFactory {

// MARK: Properties

private let packetFactory = PacketFactoryImpl()
var error: Error?

// MARK: Methods

func create(type: PacketType) throws -> Packet {
if let error {
throw error
}

return try packetFactory.create(type: type)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,12 @@ extension PacketSenderFake: PacketSender {
)

if validationError != .checksumMismatch(ipHeader) {
let checksum = ICMPChecksum()(header: icmpHeader)
icmpHeader.setChecksum(checksum)
do {
let checksum = try ICMPChecksum()(header: icmpHeader)
icmpHeader.setChecksum(checksum)
} catch {
throw PacketSenderError.error
}
}

var icmp = ICMPPacket(ipHeader: ipHeader, icmpHeader: icmpHeader)
Expand Down
2 changes: 1 addition & 1 deletion pingx.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'pingx'
s.version = '1.0.4'
s.version = '1.0.5'
s.summary = 'pingx: iOS library for ping estimation using ICMP packets.'
s.description = 'This ultralight and easy-to-use library is designed to help developers accurately measure and analyze network ping latency in their applications using ICMP packets.'
s.homepage = 'https://github.com/shineRR/pingx'
Expand Down

0 comments on commit 7c34ec8

Please sign in to comment.