64 lines
1.8 KiB
Swift
64 lines
1.8 KiB
Swift
import Foundation
|
|
import Observation
|
|
|
|
@Observable
|
|
@MainActor
|
|
final class TTLManager {
|
|
private(set) var currentTTL: Int = 64
|
|
private(set) var currentIPv6HopLimit: Int = 64
|
|
private(set) var isProtected: Bool = false
|
|
private(set) var lastError: String?
|
|
|
|
var onStatusChanged: (() -> Void)?
|
|
|
|
let defaultTTL: Int = 64
|
|
let targetTTL: Int = 65
|
|
|
|
init() {
|
|
refreshStatus()
|
|
}
|
|
|
|
/// Reads the current system IPv4 TTL value using sysctlbyname (no root required)
|
|
func readCurrentTTL() -> Int {
|
|
var ttl: Int32 = 0
|
|
var size = MemoryLayout<Int32>.size
|
|
let result = sysctlbyname("net.inet.ip.ttl", &ttl, &size, nil, 0)
|
|
if result == 0 {
|
|
return Int(ttl)
|
|
}
|
|
return defaultTTL
|
|
}
|
|
|
|
/// Reads the current system IPv6 Hop Limit value using sysctlbyname (no root required)
|
|
func readCurrentIPv6HopLimit() -> Int {
|
|
var hlim: Int32 = 0
|
|
var size = MemoryLayout<Int32>.size
|
|
let result = sysctlbyname("net.inet6.ip6.hlim", &hlim, &size, nil, 0)
|
|
if result == 0 {
|
|
return Int(hlim)
|
|
}
|
|
return defaultTTL
|
|
}
|
|
|
|
/// Refreshes current IPv4 TTL, IPv6 Hop Limit, and protection status
|
|
func refreshStatus() {
|
|
currentTTL = readCurrentTTL()
|
|
currentIPv6HopLimit = readCurrentIPv6HopLimit()
|
|
isProtected = (currentTTL == targetTTL) && (currentIPv6HopLimit == targetTTL)
|
|
lastError = nil
|
|
onStatusChanged?()
|
|
}
|
|
|
|
func didSetTTL(_ value: Int) {
|
|
currentTTL = value
|
|
currentIPv6HopLimit = value
|
|
isProtected = value == targetTTL
|
|
lastError = nil
|
|
onStatusChanged?()
|
|
}
|
|
|
|
func setError(_ message: String) {
|
|
lastError = message
|
|
onStatusChanged?()
|
|
}
|
|
}
|