mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-16 01:26:07 +00:00
feat(xray): add loopback sniffing and per-segment fragment masks
- Loopback outbound: add sniffing support (xray-core #6320) - FinalMask fragment: support per-segment lengths/delays arrays with legacy length/delay migration (xray-core #6334) - Consolidate sniffing into a shared SniffingFields component and the canonical SniffingSchema across inbound, VLESS reverse, and loopback
This commit is contained in:
@@ -101,6 +101,29 @@ exports[`FinalMaskStreamSettingsSchema fixtures > parses salamander-gecko byte-s
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`FinalMaskStreamSettingsSchema fixtures > parses tcp-fragment-segments byte-stably 1`] = `
|
||||
{
|
||||
"tcp": [
|
||||
{
|
||||
"settings": {
|
||||
"delays": [
|
||||
"5-10",
|
||||
"0",
|
||||
],
|
||||
"lengths": [
|
||||
"10-20",
|
||||
"50-100",
|
||||
],
|
||||
"maxSplit": "0",
|
||||
"packets": "tlshello",
|
||||
},
|
||||
"type": "fragment",
|
||||
},
|
||||
],
|
||||
"udp": [],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`FinalMaskStreamSettingsSchema fixtures > parses tcp-mask byte-stably 1`] = `
|
||||
{
|
||||
"tcp": [
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"tcp": [
|
||||
{
|
||||
"type": "fragment",
|
||||
"settings": {
|
||||
"packets": "tlshello",
|
||||
"lengths": ["10-20", "50-100"],
|
||||
"delays": ["5-10", "0"],
|
||||
"maxSplit": "0"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -359,6 +359,39 @@ describe('outbound-form-adapter: round-trip', () => {
|
||||
expect(back.settings).toEqual({ inboundTag: 'tagged-inbound' });
|
||||
});
|
||||
|
||||
it('loopback omits sniffing when disabled', () => {
|
||||
const form = rawOutboundToFormValues({
|
||||
protocol: 'loopback',
|
||||
settings: { inboundTag: 'tagged-inbound' },
|
||||
});
|
||||
if (form.protocol === 'loopback') {
|
||||
expect(form.settings.sniffing.enabled).toBe(false);
|
||||
}
|
||||
const back = formValuesToWirePayload(form);
|
||||
expect(back.settings).not.toHaveProperty('sniffing');
|
||||
});
|
||||
|
||||
it('loopback round-trips sniffing when enabled', () => {
|
||||
const wire = {
|
||||
protocol: 'loopback',
|
||||
settings: {
|
||||
inboundTag: 'tagged-inbound',
|
||||
sniffing: { enabled: true, destOverride: ['tls', 'http'], routeOnly: true },
|
||||
},
|
||||
};
|
||||
const form = rawOutboundToFormValues(wire);
|
||||
if (form.protocol === 'loopback') {
|
||||
expect(form.settings.sniffing.enabled).toBe(true);
|
||||
expect(form.settings.sniffing.destOverride).toEqual(['tls', 'http']);
|
||||
expect(form.settings.sniffing.routeOnly).toBe(true);
|
||||
}
|
||||
const back = formValuesToWirePayload(form);
|
||||
const sniffing = (back.settings as Record<string, unknown>).sniffing as Record<string, unknown>;
|
||||
expect(sniffing.enabled).toBe(true);
|
||||
expect(sniffing.destOverride).toEqual(['tls', 'http']);
|
||||
expect(sniffing.routeOnly).toBe(true);
|
||||
});
|
||||
|
||||
it('unknown protocol falls back to vless without throwing', () => {
|
||||
const form = rawOutboundToFormValues({ protocol: 'mysterious', settings: {} });
|
||||
expect(form.protocol).toBe('vless');
|
||||
|
||||
Reference in New Issue
Block a user