diff --git a/v2rayN/ServiceLib.Tests/CoreConfig/V2ray/CoreConfigV2rayServiceTests.cs b/v2rayN/ServiceLib.Tests/CoreConfig/V2ray/CoreConfigV2rayServiceTests.cs index 06bd472b..f9c4ddea 100644 --- a/v2rayN/ServiceLib.Tests/CoreConfig/V2ray/CoreConfigV2rayServiceTests.cs +++ b/v2rayN/ServiceLib.Tests/CoreConfig/V2ray/CoreConfigV2rayServiceTests.cs @@ -2,6 +2,38 @@ namespace ServiceLib.Tests.CoreConfig.V2ray; public class CoreConfigV2rayServiceTests { + [Test] + [Arguments("demo-seed", "srtp", 2)] + [Arguments(null, "srtp", 2)] + [Arguments("demo-seed", "none", 1)] + [Arguments(null, "none", 1)] + public async Task GenerateClientConfigContent_KcpHeader_ShouldPreserveInnerMask(string? seed, string header, int expectedCount) + { + var config = CoreConfigTestFactory.CreateConfig(ECoreType.Xray); + CoreConfigTestFactory.BindAppManagerConfig(config); + var node = CoreConfigTestFactory.CreateVmessNode(ECoreType.Xray); + node.Network = nameof(ETransport.kcp); + node.SetTransportExtra(new TransportExtraItem { KcpSeed = seed, KcpHeaderType = header }); + var context = CoreConfigTestFactory.CreateContext(config, node, ECoreType.Xray); + + var result = new CoreConfigV2rayService(context).GenerateClientConfigContent(); + + await result.Success.Should().BeTrue(); + var generatedConfig = JsonNode.Parse(result.Data!.ToString()!)!; + var proxy = generatedConfig["outbounds"]!.AsArray() + .First(outbound => outbound!["tag"]!.GetValue() == Global.ProxyTag)!; + var masks = proxy["streamSettings"]!["finalmask"]!["udp"]!.AsArray(); + await masks.Count.Should().BeEqualTo(expectedCount); + await masks[0]!["type"]!.GetValue().Should().BeEqualTo("mkcp-legacy"); + await (masks[0]!["settings"]?["value"]?.GetValue()).Should().BeEqualTo(seed); + await (masks[0]!["settings"]?["header"]?.GetValue()).Should().BeNull(); + if (expectedCount == 2) + { + await masks[1]!["type"]!.GetValue().Should().BeEqualTo("mkcp-legacy"); + await masks[1]!["settings"]!["header"]!.GetValue().Should().BeEqualTo(header); + } + } + [Test] [Arguments(null)] [Arguments("")] diff --git a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs index 9e252c0a..47f9ce0c 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs @@ -412,14 +412,11 @@ public partial class CoreConfigV2rayService } if (Global.KcpHeaderMaskMap.TryGetValue(headerType, out var header)) { - kcpFinalmask.udp = - [ - new Mask4Ray - { - type = "mkcp-legacy", - settings = new MaskSettings4Ray { header = header }, - }, - ]; + kcpFinalmask.udp.Add(new Mask4Ray + { + type = "mkcp-legacy", + settings = new MaskSettings4Ray { header = header }, + }); } streamSettings.kcpSettings = kcpSettings; streamSettings.finalmask = (JsonObject)JsonUtils.SerializeToNode(kcpFinalmask);