mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-11-08 22:25:00 +03:00
feat(xray): update xray-core to v26.9.30 and adapt panel
Bump xtls/xray-core to b26a91de4f (v26.9.30) and the three binary pins (DockerInit.sh, release.yml Linux + Windows) in lockstep. No deleted symbols; the sing and sing-shadowsocks indirect deps drop out with the SS2022 rewrite. XDNS finalmask (#6718) replaced its string lists with objects: domains are {name, types, edns0, lenLimit, labelLimit} and client resolvers {type, settings.addr}. The loader no longer parses the old lists, so a single stored xdns mask keeps the whole core from starting. The new leaf package internal/util/maskcompat converts them: "name[:type]" becomes a domain and "name[:type]+udp://addr" a domain plus a udp resolver. A bare name maps to TXT, the type legacy clients queried by default, and each converted domain keeps the 1232-byte EDNS0 the old code always used (without it the server caps answers at 512). It runs from: - the XdnsFinalmaskObjectsFix seeder, over inbound streams, hosts, the xray template, the global sub-JSON mask and cached subscription outbounds; - inbound save (normalizeStreamSettings) and GetXrayConfig, for rows that never went through the seeder; - both link importers, since fm= from an older panel carries the lists. The finalmask form edits the object shape (every key needs a registered field, or the finalmask watch drops it on save) and lifts legacy masks on open. The udp-mask golden fixture moves to the object shape, which TestGoldenStreamFixturesBuildInXray now builds through the core. The wire format changed as well, so pre-upgrade clients need the new core. WireGuard outbound (#6771) dropped settings.domainStrategy and the remoteDNS "local" mode. The endpoint lookup now follows sockopt.domainStrategy and in-tunnel targets the outbound's targetStrategy. The old key is silently ignored, which undid the IPv4-first endpoint lookup the WARP outbound depends on (#5205), and "local" now panics the core at startup because remoteDNS goes through netip.MustParseAddr. The WireguardDomainStrategyFix seeder moves a stored family preference to both keys (a value already set wins) and turns "local" into targetStrategy; the outbound form lifts legacy rows the same way and drops its select, the WARP modal writes the new placement, and the inbound form loses a field the server never read. ValidateOutboundConfig now refuses a non-IP remoteDNS entry, which conf.Build() lets through, on template save and for outbound subscriptions. Noise finalmask items accept type "exp" (#6862), a tag expression. The form offers it for noise items only: header-custom items go through the core's PraseByteSlice, which refuses it. TUN gained autoSystemDnsToGateway (Linux) and autoSystemWfpBlockLeak (Windows). Both pass through the settings schema so a value set in JSON survives the next form save. MASQUE (inbound, outbound, transport) and the XDRIVE transport are new protocols the panel does not offer yet; their new loader refusals only cover configs the panel never generates. The FakeDNS IPv6 pool default, the SS2022 rewrite (same gRPC account; emails are now deduped case-insensitively, as the panel already does), the restored udphop interval default and the rest change no panel-facing config.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button, Form, Input, InputNumber, Select, Space, Switch } from 'antd';
|
||||
import { Button, Form, Input, InputNumber, Space, Switch } from 'antd';
|
||||
import { ReloadOutlined } from '@ant-design/icons';
|
||||
|
||||
import { FormField } from '@/components/form/rhf';
|
||||
@@ -43,21 +43,6 @@ export default function WireguardFields({ wgPubKey, regenInboundWg }: WireguardF
|
||||
>
|
||||
<Switch />
|
||||
</FormField>
|
||||
<FormField
|
||||
name={['settings', 'domainStrategy']}
|
||||
label={t('pages.xray.wireguard.domainStrategy')}
|
||||
>
|
||||
<Select
|
||||
allowClear
|
||||
options={[
|
||||
{ value: 'ForceIP', label: 'ForceIP' },
|
||||
{ value: 'ForceIPv4', label: 'ForceIPv4' },
|
||||
{ value: 'ForceIPv4v6', label: 'ForceIPv4v6' },
|
||||
{ value: 'ForceIPv6', label: 'ForceIPv6' },
|
||||
{ value: 'ForceIPv6v4', label: 'ForceIPv6v4' },
|
||||
]}
|
||||
/>
|
||||
</FormField>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button, Form, Input, InputNumber, Select, Space, Switch } from 'antd';
|
||||
import { Button, Form, Input, InputNumber, Space, Switch } from 'antd';
|
||||
import { DeleteOutlined, MinusOutlined, PlusOutlined, ReloadOutlined } from '@ant-design/icons';
|
||||
import { useFieldArray, useFormContext } from 'react-hook-form';
|
||||
|
||||
@@ -7,7 +7,6 @@ import { Wireguard } from '@/utils';
|
||||
import { activateOnKey } from '@/utils/a11y';
|
||||
import { InputAddon } from '@/components/ui';
|
||||
import { FormField } from '@/components/form/rhf';
|
||||
import { WireguardDomainStrategy } from '@/schemas/primitives';
|
||||
|
||||
function AllowedIPsList({ peerIndex }: { peerIndex: number }) {
|
||||
const { t } = useTranslation();
|
||||
@@ -75,17 +74,6 @@ export default function WireguardFields() {
|
||||
<FormField label={t('pages.inbounds.publicKey')} name={['settings', 'pubKey']}>
|
||||
<Input disabled />
|
||||
</FormField>
|
||||
<FormField
|
||||
label={t('pages.xray.wireguard.domainStrategy')}
|
||||
name={['settings', 'domainStrategy']}
|
||||
>
|
||||
<Select
|
||||
options={[
|
||||
{ value: '', label: `(${t('none')})` },
|
||||
...WireguardDomainStrategy.map((s) => ({ value: s, label: s })),
|
||||
]}
|
||||
/>
|
||||
</FormField>
|
||||
<FormField label="MTU" name={['settings', 'mtu']}>
|
||||
<InputNumber min={0} />
|
||||
</FormField>
|
||||
|
||||
@@ -65,6 +65,34 @@ function reservedFor(clientId?: string): number[] {
|
||||
return out;
|
||||
}
|
||||
|
||||
export function buildWarpOutbound(
|
||||
data: WarpData | null,
|
||||
config: WarpConfig | null,
|
||||
): Record<string, unknown> | null {
|
||||
const cfg = config?.config;
|
||||
if (!cfg?.peers?.length) return null;
|
||||
const peer = cfg.peers[0];
|
||||
return {
|
||||
tag: 'warp',
|
||||
protocol: 'wireguard',
|
||||
// ForceIP may resolve engage.cloudflareclient.com to its AAAA and a half-configured IPv6
|
||||
// host blackholes the handshake silently (#5205); sockopt drives that lookup since 26.9.30.
|
||||
streamSettings: { sockopt: { domainStrategy: 'ForceIPv4v6' } },
|
||||
// Targets inside the tunnel keep the IPv4 preference the removed settings key gave them.
|
||||
targetStrategy: 'ForceIPv4v6',
|
||||
settings: {
|
||||
mtu: 1420,
|
||||
secretKey: data?.private_key,
|
||||
address: addressesFor(cfg.interface?.addresses || {}),
|
||||
reserved: reservedFor(cfg.client_id ?? data?.client_id),
|
||||
peers: [{ publicKey: peer.public_key, endpoint: peer.endpoint?.host }],
|
||||
// Userspace TUN: kernel TUN needs CAP_NET_ADMIN + fwmark routing, fails silently on many
|
||||
// VPS setups, and differs from the connectivity test's path (always noKernelTun=true).
|
||||
noKernelTun: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function mergeWarpRotation(
|
||||
existing: Record<string, unknown> | undefined,
|
||||
data: WarpData | null,
|
||||
@@ -127,31 +155,8 @@ export default function WarpModal({
|
||||
|
||||
const collectConfig = useCallback(
|
||||
(data: WarpData | null, config: WarpConfig | null): Record<string, unknown> | null => {
|
||||
const cfg = config?.config;
|
||||
if (!cfg?.peers?.length) return null;
|
||||
const peer = cfg.peers[0];
|
||||
const outbound: Record<string, unknown> = {
|
||||
tag: 'warp',
|
||||
protocol: 'wireguard',
|
||||
settings: {
|
||||
mtu: 1420,
|
||||
secretKey: data?.private_key,
|
||||
address: addressesFor(cfg.interface?.addresses || {}),
|
||||
reserved: reservedFor(cfg.client_id ?? data?.client_id),
|
||||
// Prefer IPv4 with IPv6 fallback: plain ForceIP may pick the AAAA
|
||||
// record for engage.cloudflareclient.com, and a host with
|
||||
// half-configured IPv6 then blackholes the handshake with no error
|
||||
// logged (#5205).
|
||||
domainStrategy: 'ForceIPv4v6',
|
||||
peers: [{ publicKey: peer.public_key, endpoint: peer.endpoint?.host }],
|
||||
// Userspace TUN: kernel TUN needs CAP_NET_ADMIN + fwmark routing and
|
||||
// fails silently on many VPS setups, and it is a different data path
|
||||
// than the panel's connectivity test (which always probes with
|
||||
// noKernelTun=true), so "test ok" and "traffic flows" can disagree.
|
||||
noKernelTun: true,
|
||||
},
|
||||
};
|
||||
setStagedOutbound(outbound);
|
||||
const outbound = buildWarpOutbound(data, config);
|
||||
if (outbound) setStagedOutbound(outbound);
|
||||
return outbound;
|
||||
},
|
||||
[],
|
||||
|
||||
Reference in New Issue
Block a user