Files
OpenStats/Packages/OpenStatsKit/Sources/HelperShared/DNSConfiguration.swift
T
gentpan 8875b6e709 每项独立菜单栏与详情弹窗、网络详情与 DNS、侧边栏主窗口与统一外观
- 菜单栏可每项独立(点击弹出该项窄详情)或合并为一个(点击打开主窗口),详情区块可在设置中勾选
- 网络详情:镜像流量历史、ICMP 连接探测格子、接口与 Wi-Fi、本地与公网 IPv4 / IPv6、SVG 国旗归属地与 ASN、各进程流量
- DNS:刷新缓存,一键切换自动 / Cloudflare / Google / 腾讯 / 阿里云或手动填写;辅助工具协议升至 3,服务名与地址二次校验
- 主窗口:侧边栏切换仪表盘、各指标详情与工具页,宽高可调,卡片按比例伸缩
- 统一外观:白底蓝 / 黑底蓝,窗口、设置与弹窗共用底色,去掉玻璃效果
- 新增网络解析、DNS 校验与国旗代码校验的单元测试;更新 README、架构文档与隐私说明
2026-09-13 05:39:10 +05:00

69 lines
2.7 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import Darwin
import Foundation
/// 常用公共 DNS。只用 IPv4 地址:没有 IPv6 的网络里写入 IPv6 服务器会拖慢解析
public enum DNSPreset: String, CaseIterable, Identifiable, Sendable {
case automatic, cloudflare, google, tencent, aliyun
public var id: String { rawValue }
public var title: String {
switch self {
case .automatic: "自动"
case .cloudflare: "Cloudflare"
case .google: "Google"
case .tencent: "腾讯 DNSPod"
case .aliyun: "阿里云"
}
}
public var servers: [String] {
switch self {
case .automatic: []
case .cloudflare: ["1.1.1.1", "1.0.0.1"]
case .google: ["8.8.8.8", "8.8.4.4"]
case .tencent: ["119.29.29.29", "182.254.116.116"]
case .aliyun: ["223.5.5.5", "223.6.6.6"]
}
}
/// 当前手动设置的地址与哪个预设一致;无手动地址即“自动”
public static func matching(_ servers: [String]) -> DNSPreset? {
allCases.first { $0.servers == servers }
}
}
public enum DNSConfiguration {
public static let maxServers = 6
/// 只接受数字形式的 IPv4 / IPv6 地址
public static func isValidAddress(_ text: String) -> Bool {
var v4 = in_addr()
var v6 = in6_addr()
return inet_pton(AF_INET, text, &v4) == 1 || inet_pton(AF_INET6, text, &v6) == 1
}
/// 把用户输入(逗号、空格或换行分隔)拆成地址列表;有无效地址时返回 nil
public static func parse(_ input: String) -> [String]? {
let parts = input.split { $0 == "," || $0 == "," || $0.isWhitespace }.map(String.init)
guard parts.count <= maxServers, parts.allSatisfy(isValidAddress) else { return nil }
return parts
}
/// 服务名来自系统,可能包含空格或引号;只拒绝控制字符
public static func isValidServiceName(_ name: String) -> Bool {
!name.isEmpty && name.count <= 128 && !name.unicodeScalars.contains { CharacterSet.controlCharacters.contains($0) }
}
public static func networksetupArguments(service: String, servers: [String]) -> [String] {
["-setdnsservers", service] + (servers.isEmpty ? ["Empty"] : servers)
}
/// 未安装辅助工具时通过管理员授权执行的 shell 命令。服务名按单引号转义,地址已校验为纯数字形式
public static func shellCommand(service: String, servers: [String]) -> String {
let quoted = "'" + service.replacingOccurrences(of: "'", with: "'\\''") + "'"
let arguments = ["-setdnsservers", quoted] + (servers.isEmpty ? ["Empty"] : servers)
return (["/usr/sbin/networksetup"] + arguments).joined(separator: " ")
}
}