mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-08 02:52:07 +08:00
feat(tun): validate route-exclude-address as CIDR (#6440)
* feat(tun): validate route-exclude-address as CIDR * refactor(network): replace ipaddr.js helpers with cidr-block and validator * docs: Changelog
This commit is contained in:
@@ -21,7 +21,7 @@ import {
|
||||
getWebdavStatus,
|
||||
setWebdavStatus,
|
||||
} from "@/services/webdav-status";
|
||||
import { isValidUrl } from "@/utils/helper";
|
||||
import { isValidUrl } from "@/utils/network";
|
||||
|
||||
interface BackupConfigViewerProps {
|
||||
onBackupSuccess: () => Promise<void>;
|
||||
|
||||
@@ -23,6 +23,7 @@ import { useClash } from "@/hooks/use-clash";
|
||||
import { enhanceProfiles } from "@/services/cmds";
|
||||
import { showNotice } from "@/services/notice-service";
|
||||
import getSystem from "@/utils/get-system";
|
||||
import { areValidIpCidrs } from "@/utils/network";
|
||||
|
||||
import { StackModeSwitch } from "./stack-mode-switch";
|
||||
|
||||
@@ -52,6 +53,17 @@ export function TunViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
mtu: 1500,
|
||||
});
|
||||
|
||||
const routeExcludeAddressItems = splitRouteExcludeAddress(
|
||||
values.routeExcludeAddress,
|
||||
);
|
||||
const routeExcludeAddressError =
|
||||
values.autoRoute &&
|
||||
routeExcludeAddressItems.length > 0 &&
|
||||
!areValidIpCidrs(routeExcludeAddressItems);
|
||||
const routeExcludeAddressHelperText = routeExcludeAddressError
|
||||
? t("settings.modals.tun.messages.invalidRouteExcludeAddress")
|
||||
: t("settings.modals.tun.messages.routeExcludeAddressHint");
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
open: () => {
|
||||
setOpen(true);
|
||||
@@ -78,9 +90,15 @@ export function TunViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
|
||||
const onSave = useLockFn(async () => {
|
||||
try {
|
||||
const routeExcludeAddress = splitRouteExcludeAddress(
|
||||
values.routeExcludeAddress,
|
||||
);
|
||||
const routeExcludeAddress = routeExcludeAddressItems;
|
||||
|
||||
if (routeExcludeAddressError) {
|
||||
showNotice.error(
|
||||
"settings.modals.tun.messages.invalidRouteExcludeAddress",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const tun: IConfigData["tun"] = {
|
||||
stack: values.stack,
|
||||
device:
|
||||
@@ -312,6 +330,8 @@ export function TunViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
placeholder="192.168.0.0/16"
|
||||
ariaLabel={t("settings.modals.tun.fields.routeExcludeAddress")}
|
||||
disabled={!values.autoRoute}
|
||||
error={routeExcludeAddressError}
|
||||
helperText={routeExcludeAddressHelperText}
|
||||
onChange={(nextValue) =>
|
||||
setValues((v) => ({ ...v, routeExcludeAddress: nextValue }))
|
||||
}
|
||||
|
||||
@@ -19,7 +19,12 @@ import { useClash } from "@/hooks/use-clash";
|
||||
import { useAppData } from "@/providers/app-data-context";
|
||||
import { isPortInUse } from "@/services/cmds";
|
||||
import { showNotice } from "@/services/notice-service";
|
||||
import { parseHost, parsedLocalhost, isValidPort } from "@/utils/helper";
|
||||
import {
|
||||
formatHostPort,
|
||||
isValidPort,
|
||||
normalizeHost,
|
||||
normalizeListenHost,
|
||||
} from "@/utils/network";
|
||||
|
||||
interface TunnelsViewerRef {
|
||||
open: () => void;
|
||||
@@ -127,8 +132,8 @@ export const TunnelsViewer = forwardRef<TunnelsViewerRef>((_, ref) => {
|
||||
}
|
||||
|
||||
// 本地地址校验(host)
|
||||
const parsedLocal = parsedLocalhost(localAddr);
|
||||
if (!parsedLocal) {
|
||||
const localHost = normalizeListenHost(localAddr);
|
||||
if (!localHost) {
|
||||
showNotice.error(
|
||||
"settings.sections.clash.form.fields.tunnels.messages.invalidLocalAddr",
|
||||
);
|
||||
@@ -151,8 +156,8 @@ export const TunnelsViewer = forwardRef<TunnelsViewerRef>((_, ref) => {
|
||||
}
|
||||
|
||||
// 目标地址校验 (host)
|
||||
const parsedTarget = parseHost(targetAddr);
|
||||
if (!parsedTarget) {
|
||||
const targetHost = normalizeHost(targetAddr);
|
||||
if (!targetHost) {
|
||||
showNotice.error(
|
||||
"settings.sections.clash.form.fields.tunnels.messages.invalidTargetAddr",
|
||||
);
|
||||
@@ -170,14 +175,8 @@ export const TunnelsViewer = forwardRef<TunnelsViewerRef>((_, ref) => {
|
||||
// 构造新 entry
|
||||
const entry: TunnelEntry = {
|
||||
network: network === "tcp+udp" ? ["tcp", "udp"] : [network],
|
||||
address:
|
||||
parsedLocal.kind === "ipv6"
|
||||
? `[${parsedLocal.host}]:${localPort}`
|
||||
: `${parsedLocal.host}:${localPort}`,
|
||||
target:
|
||||
parsedTarget.kind === "ipv6"
|
||||
? `[${parsedTarget.host}]:${targetPort}`
|
||||
: `${parsedTarget.host}:${targetPort}`,
|
||||
address: formatHostPort(localHost, localPort),
|
||||
target: formatHostPort(targetHost, targetPort),
|
||||
...(proxy ? { proxy } : {}),
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user