diff --git a/lite/rrpp_core/tun_backend.py b/lite/rrpp_core/tun_backend.py index 68f9bf2..739ae78 100644 --- a/lite/rrpp_core/tun_backend.py +++ b/lite/rrpp_core/tun_backend.py @@ -641,9 +641,11 @@ class TunBackend: raise TunBackendError("自定义 DNS 不能为空") try: for item in cleaned: - socket.inet_pton(socket.AF_INET, item) - except OSError as exc: - raise TunBackendError("当前 TUN 仅支持 IPv4 DNS 服务器") from exc + address = ipaddress.ip_address(item) + if address.is_unspecified or address.is_multicast: + raise ValueError(item) + except ValueError as exc: + raise TunBackendError("自定义 DNS 必须是有效的 IPv4/IPv6 地址") from exc self._tun_dns_servers = cleaned[:3] engine = self.resolve_engine() interface = self._physical_interface() diff --git a/lite/rrpp_core/tun_mode.py b/lite/rrpp_core/tun_mode.py index 93a1355..dec494c 100644 --- a/lite/rrpp_core/tun_mode.py +++ b/lite/rrpp_core/tun_mode.py @@ -124,17 +124,22 @@ class TunModeController: def _request(self, command: str, payload: dict[str, Any] | None = None) -> Any: if self._socket is None or self._reader is None: raise TunModeError("TUN 工作进程未连接") - _send(self._socket, {"command": command, "payload": payload or {}}) - while True: - message = _receive(self._reader) - if message.get("type") == "log": - self.log(str(message.get("message") or "")) - continue - if message.get("type") != "result": - raise TunModeError("TUN 工作进程响应无效") - if not message.get("ok"): - raise TunModeError(str(message.get("error") or "TUN 操作失败")) - return message.get("value") + try: + _send(self._socket, {"command": command, "payload": payload or {}}) + while True: + message = _receive(self._reader) + if message.get("type") == "log": + self.log(str(message.get("message") or "")) + continue + if message.get("type") != "result": + raise TunModeError("TUN 工作进程响应无效") + if not message.get("ok"): + raise TunModeError(str(message.get("error") or "TUN 操作失败")) + return message.get("value") + except TunModeError: + raise + except OSError as exc: + raise TunModeError(f"TUN 工作进程连接中止: {exc}") from exc def status(self) -> dict[str, Any]: with self._lock: @@ -195,7 +200,6 @@ def run_tun_worker(port: int, token: str, backend_factory, backend = None try: - backend = backend_factory(emit) while True: try: request = _receive(reader) @@ -206,6 +210,10 @@ def run_tun_worker(port: int, token: str, backend_factory, if command == "start": if not isinstance(request.get("payload"), dict): raise TunModeError("TUN 启动参数无效") + # 延迟创建后端,使初始化失败也能通过控制协议返回具体原因, + # 避免 GUI 只看到 Windows 的 10053 连接中止错误。 + if backend is None: + backend = backend_factory(emit) start_backend(backend, request["payload"]) value = None elif command == "stop":