mirror of
https://github.com/2dust/v2rayN.git
synced 2026-05-17 20:54:36 +03:00
Wireguard (#9241)
* Adjust mtu * Add Wireguard PresharedKey * WireGuard config import * AI opt * Opt
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
using AwesomeAssertions;
|
||||
using ServiceLib.Handler.Fmt;
|
||||
using Xunit;
|
||||
|
||||
namespace ServiceLib.Tests.Fmt;
|
||||
|
||||
public class WireguardFmtTests
|
||||
{
|
||||
[Fact]
|
||||
public void ResolveConfig_ShouldParsePeersAndIgnoreInlineComments()
|
||||
{
|
||||
const string config =
|
||||
"""
|
||||
[Interface]
|
||||
PrivateKey = interface-private-key
|
||||
Address = 10.0.0.2/32, fd00::2/128 ; inline comment
|
||||
MTU = 1420
|
||||
|
||||
[Peer]
|
||||
PublicKey = peer-public-key
|
||||
PresharedKey = peer-preshared-key
|
||||
Reserved = 1, 2, 3 # inline comment
|
||||
Endpoint = [2001:db8::1]:51820 # inline comment
|
||||
|
||||
[Peer]
|
||||
PublicKey = peer-public-key-2
|
||||
Endpoint = example.com:12345
|
||||
""";
|
||||
|
||||
var resolved = WireguardFmt.ResolveConfig(config);
|
||||
|
||||
resolved.Should().NotBeNull();
|
||||
resolved.Should().HaveCount(2);
|
||||
|
||||
var first = resolved![0];
|
||||
first.Address.Should().Be("2001:db8::1");
|
||||
first.Port.Should().Be(51820);
|
||||
first.Password.Should().Be("interface-private-key");
|
||||
first.GetProtocolExtra().WgReserved.Should().Be("1, 2, 3");
|
||||
first.GetProtocolExtra().WgInterfaceAddress.Should().Be("10.0.0.2/32, fd00::2/128");
|
||||
first.GetProtocolExtra().WgMtu.Should().Be(1420);
|
||||
|
||||
var second = resolved[1];
|
||||
second.Address.Should().Be("example.com");
|
||||
second.Port.Should().Be(12345);
|
||||
}
|
||||
}
|
||||
@@ -790,12 +790,30 @@ public static class ConfigHandler
|
||||
|
||||
profileItem.Address = profileItem.Address.TrimEx();
|
||||
profileItem.Password = profileItem.Password.TrimEx();
|
||||
var wgReserved = profileItem.GetProtocolExtra().WgReserved?.TrimEx();
|
||||
if (!wgReserved.IsNullOrEmpty()
|
||||
&& !wgReserved.Contains(','))
|
||||
{
|
||||
// Base64 format, convert to standard format
|
||||
try
|
||||
{
|
||||
var bytes = Convert.FromBase64String(wgReserved);
|
||||
var reserved = new byte[3];
|
||||
Array.Copy(bytes, reserved, Math.Min(bytes.Length, 3));
|
||||
|
||||
wgReserved = string.Join(", ", reserved);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// If conversion fails, keep the original value
|
||||
}
|
||||
}
|
||||
profileItem.SetProtocolExtra(profileItem.GetProtocolExtra() with
|
||||
{
|
||||
WgPublicKey = profileItem.GetProtocolExtra().WgPublicKey?.TrimEx(),
|
||||
WgPresharedKey = profileItem.GetProtocolExtra().WgPresharedKey?.TrimEx(),
|
||||
WgInterfaceAddress = profileItem.GetProtocolExtra().WgInterfaceAddress?.TrimEx(),
|
||||
WgReserved = profileItem.GetProtocolExtra().WgReserved?.TrimEx(),
|
||||
WgReserved = wgReserved,
|
||||
WgMtu = profileItem.GetProtocolExtra().WgMtu is null or <= 0 ? Global.TunMtus.First() : profileItem.GetProtocolExtra().WgMtu,
|
||||
});
|
||||
|
||||
@@ -1639,30 +1657,18 @@ public static class ConfigHandler
|
||||
|
||||
ProfileItem? profileItem = null;
|
||||
//Is sing-box configuration
|
||||
if (profileItem is null)
|
||||
{
|
||||
profileItem = SingboxFmt.ResolveFull(strData, subRemarks);
|
||||
}
|
||||
profileItem ??= SingboxFmt.ResolveFull(strData, subRemarks);
|
||||
//Is v2ray configuration
|
||||
if (profileItem is null)
|
||||
{
|
||||
profileItem = V2rayFmt.ResolveFull(strData, subRemarks);
|
||||
}
|
||||
profileItem ??= V2rayFmt.ResolveFull(strData, subRemarks);
|
||||
//Is Html Page
|
||||
if (profileItem is null && HtmlPageFmt.IsHtmlPage(strData))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
//Is Clash configuration
|
||||
if (profileItem is null)
|
||||
{
|
||||
profileItem = ClashFmt.ResolveFull(strData, subRemarks);
|
||||
}
|
||||
profileItem ??= ClashFmt.ResolveFull(strData, subRemarks);
|
||||
//Is hysteria configuration
|
||||
if (profileItem is null)
|
||||
{
|
||||
profileItem = Hysteria2Fmt.ResolveFull2(strData, subRemarks);
|
||||
}
|
||||
profileItem ??= Hysteria2Fmt.ResolveFull2(strData, subRemarks);
|
||||
if (profileItem is null || profileItem.Address.IsNullOrEmpty())
|
||||
{
|
||||
return -1;
|
||||
@@ -1727,6 +1733,40 @@ public static class ConfigHandler
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static async Task<int> AddBatchServers4Wireguard(Config config, string strData, string subid, bool isSub)
|
||||
{
|
||||
if (strData.IsNullOrEmpty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (!(strData.Contains("[Interface]", StringComparison.OrdinalIgnoreCase)
|
||||
&& strData.Contains("[Peer]", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (isSub && subid.IsNotEmpty())
|
||||
{
|
||||
await RemoveServersViaSubid(config, subid, isSub);
|
||||
}
|
||||
var lstServer = WireguardFmt.ResolveConfig(strData);
|
||||
if (lstServer?.Count > 0)
|
||||
{
|
||||
var counter = 0;
|
||||
foreach (var item in lstServer)
|
||||
{
|
||||
item.Subid = subid;
|
||||
item.IsSub = isSub;
|
||||
if (await AddWireguardServer(config, item) == 0)
|
||||
{
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
await SaveConfig(config);
|
||||
return counter;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Main entry point for adding batch servers from various formats
|
||||
/// Tries different parsing methods to import as many servers as possible
|
||||
@@ -1769,6 +1809,12 @@ public static class ConfigHandler
|
||||
counter = await AddBatchServers4SsSIP008(config, strData, subid, isSub);
|
||||
}
|
||||
|
||||
//maybe wireguard config
|
||||
if (counter < 1)
|
||||
{
|
||||
counter = await AddBatchServers4Wireguard(config, strData, subid, isSub);
|
||||
}
|
||||
|
||||
//maybe other sub
|
||||
if (counter < 1)
|
||||
{
|
||||
|
||||
@@ -27,9 +27,10 @@ public class WireguardFmt : BaseFmt
|
||||
item.SetProtocolExtra(item.GetProtocolExtra() with
|
||||
{
|
||||
WgPublicKey = GetQueryDecoded(query, "publickey"),
|
||||
WgPresharedKey = GetQueryDecoded(query, "presharedkey"),
|
||||
WgReserved = GetQueryDecoded(query, "reserved"),
|
||||
WgInterfaceAddress = GetQueryDecoded(query, "address"),
|
||||
WgMtu = int.TryParse(GetQueryDecoded(query, "mtu"), out var mtuVal) ? mtuVal : 1280,
|
||||
WgMtu = int.TryParse(GetQueryDecoded(query, "mtu"), out var mtuVal) ? mtuVal : null,
|
||||
});
|
||||
|
||||
return item;
|
||||
@@ -48,20 +49,183 @@ public class WireguardFmt : BaseFmt
|
||||
remark = "#" + Utils.UrlEncode(item.Remarks);
|
||||
}
|
||||
|
||||
var protoExtra = item.GetProtocolExtra();
|
||||
var dicQuery = new Dictionary<string, string>();
|
||||
if (!item.GetProtocolExtra().WgPublicKey.IsNullOrEmpty())
|
||||
if (!protoExtra.WgPublicKey.IsNullOrEmpty())
|
||||
{
|
||||
dicQuery.Add("publickey", Utils.UrlEncode(item.GetProtocolExtra().WgPublicKey));
|
||||
dicQuery.Add("publickey", Utils.UrlEncode(protoExtra.WgPublicKey));
|
||||
}
|
||||
if (!item.GetProtocolExtra().WgReserved.IsNullOrEmpty())
|
||||
if (!protoExtra.WgPresharedKey.IsNullOrEmpty())
|
||||
{
|
||||
dicQuery.Add("reserved", Utils.UrlEncode(item.GetProtocolExtra().WgReserved));
|
||||
dicQuery.Add("presharedkey", Utils.UrlEncode(protoExtra.WgPresharedKey));
|
||||
}
|
||||
if (!item.GetProtocolExtra().WgInterfaceAddress.IsNullOrEmpty())
|
||||
if (!protoExtra.WgReserved.IsNullOrEmpty())
|
||||
{
|
||||
dicQuery.Add("address", Utils.UrlEncode(item.GetProtocolExtra().WgInterfaceAddress));
|
||||
dicQuery.Add("reserved", Utils.UrlEncode(protoExtra.WgReserved));
|
||||
}
|
||||
if (!protoExtra.WgInterfaceAddress.IsNullOrEmpty())
|
||||
{
|
||||
dicQuery.Add("address", Utils.UrlEncode(protoExtra.WgInterfaceAddress));
|
||||
}
|
||||
if (protoExtra.WgMtu > 0)
|
||||
{
|
||||
dicQuery.Add("mtu", protoExtra.WgMtu.ToString());
|
||||
}
|
||||
dicQuery.Add("mtu", Utils.UrlEncode(item.GetProtocolExtra().WgMtu > 0 ? item.GetProtocolExtra().WgMtu.ToString() : "1280"));
|
||||
return ToUri(EConfigType.WireGuard, item.Address, item.Port, item.Password, dicQuery, remark);
|
||||
}
|
||||
|
||||
public static List<ProfileItem>? ResolveConfig(string strData)
|
||||
{
|
||||
var interfaceDic = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
var peerDicList = new List<Dictionary<string, string>>();
|
||||
var currentDicRef = interfaceDic;
|
||||
using (var reader = new StringReader(strData))
|
||||
{
|
||||
while (reader.ReadLine() is { } line)
|
||||
{
|
||||
if (line.IsNullOrEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var trimmedLine = line.Trim();
|
||||
|
||||
if (trimmedLine.Equals("[Interface]", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
currentDicRef = interfaceDic;
|
||||
continue;
|
||||
}
|
||||
if (trimmedLine.Equals("[Peer]", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var peerDic = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
peerDicList.Add(peerDic);
|
||||
currentDicRef = peerDic;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (trimmedLine.StartsWith('[') || trimmedLine.StartsWith('#') || trimmedLine.StartsWith(';'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var idx = line.IndexOf('=');
|
||||
if (idx <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var key = line[..idx].Trim();
|
||||
var value = line[(idx + 1)..].Trim();
|
||||
var commentPos = value.IndexOfAny(['#', ';']);
|
||||
if (commentPos >= 0)
|
||||
{
|
||||
value = value[..commentPos].TrimEnd();
|
||||
}
|
||||
|
||||
currentDicRef[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (!interfaceDic.TryGetValue("PrivateKey", out var privateKey) || privateKey.IsNullOrEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var wgMtu = interfaceDic.TryGetValue("MTU", out var mtuStr) && int.TryParse(mtuStr, out var mtuVal) ? mtuVal : 0;
|
||||
var wgInterfaceAddress = interfaceDic.TryGetValue("Address", out var interfaceAddress) ? interfaceAddress : string.Empty;
|
||||
|
||||
var index = 0;
|
||||
var resultList = new List<ProfileItem>();
|
||||
|
||||
foreach (var peerDic in peerDicList)
|
||||
{
|
||||
if (!peerDic.TryGetValue("Endpoint", out var endpoint) || endpoint.IsNullOrEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!TryParseEndpoint(endpoint, out var peerAddress, out var peerPort))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var protoExtra = new ProtocolExtraItem
|
||||
{
|
||||
WgPublicKey = (peerDic.TryGetValue("PublicKey", out var publicKey) ? publicKey : string.Empty).NullIfEmpty(),
|
||||
WgPresharedKey = (peerDic.TryGetValue("PresharedKey", out var presharedKey) ? presharedKey : string.Empty).NullIfEmpty(),
|
||||
WgInterfaceAddress = wgInterfaceAddress,
|
||||
WgReserved = (peerDic.TryGetValue("Reserved", out var reserved) ? reserved : string.Empty).NullIfEmpty(),
|
||||
WgMtu = wgMtu > 0 ? wgMtu : null,
|
||||
};
|
||||
|
||||
var item = new ProfileItem
|
||||
{
|
||||
Remarks = $"{nameof(EConfigType.WireGuard)} Peer {index + 1}",
|
||||
ConfigType = EConfigType.WireGuard,
|
||||
Address = peerAddress,
|
||||
Port = peerPort,
|
||||
Password = privateKey,
|
||||
};
|
||||
item.SetProtocolExtra(protoExtra);
|
||||
resultList.Add(item);
|
||||
|
||||
index += 1;
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
private static bool TryParseEndpoint(string endpoint, out string address, out int port)
|
||||
{
|
||||
address = string.Empty;
|
||||
port = 2408;
|
||||
|
||||
var trimmedEndpoint = endpoint.Trim();
|
||||
if (trimmedEndpoint.IsNullOrEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (trimmedEndpoint[0] == '[')
|
||||
{
|
||||
var closeIndex = trimmedEndpoint.IndexOf(']');
|
||||
if (closeIndex <= 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
address = trimmedEndpoint[1..closeIndex].Trim();
|
||||
var portIndex = closeIndex + 1;
|
||||
if (portIndex < trimmedEndpoint.Length && trimmedEndpoint[portIndex] == ':' &&
|
||||
int.TryParse(trimmedEndpoint[(portIndex + 1)..].Trim(), out var bracketedPort) && bracketedPort is > 0 and <= 65535)
|
||||
{
|
||||
port = bracketedPort;
|
||||
}
|
||||
|
||||
return address.IsNotEmpty();
|
||||
}
|
||||
|
||||
var lastColonIndex = trimmedEndpoint.LastIndexOf(':');
|
||||
if (lastColonIndex <= 0)
|
||||
{
|
||||
address = trimmedEndpoint;
|
||||
return true;
|
||||
}
|
||||
|
||||
address = trimmedEndpoint[..lastColonIndex].Trim();
|
||||
var portText = trimmedEndpoint[(lastColonIndex + 1)..].Trim();
|
||||
if (address.IsNullOrEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (int.TryParse(portText, out var parsedPortValue) && parsedPortValue is > 0 and <= 65535)
|
||||
{
|
||||
port = parsedPortValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
address = trimmedEndpoint;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ public class Peer4Sbox
|
||||
public string? pre_shared_key { get; set; }
|
||||
public List<string> allowed_ips { get; set; }
|
||||
public int? persistent_keepalive_interval { get; set; }
|
||||
public List<int> reserved { get; set; }
|
||||
public List<int>? reserved { get; set; }
|
||||
}
|
||||
|
||||
public class Tls4Sbox
|
||||
|
||||
@@ -163,6 +163,7 @@ public class WireguardPeer4Ray
|
||||
{
|
||||
public string endpoint { get; set; }
|
||||
public string publicKey { get; set; }
|
||||
public string? preSharedKey { get; set; }
|
||||
}
|
||||
|
||||
public class VnextItem4Ray
|
||||
|
||||
Generated
+19
-10
@@ -3222,6 +3222,15 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 MTU 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbMtu {
|
||||
get {
|
||||
return ResourceManager.GetString("TbMtu", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Transport protocol(network) 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -3312,6 +3321,15 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 PreSharedKey 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbPreSharedKey {
|
||||
get {
|
||||
return ResourceManager.GetString("TbPreSharedKey", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Socks port 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -3430,7 +3448,7 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Reserved (2,3,4) 的本地化字符串。
|
||||
/// 查找类似 Reserved 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbReserved {
|
||||
get {
|
||||
@@ -4365,15 +4383,6 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 MTU 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbSettingsTunMtu {
|
||||
get {
|
||||
return ResourceManager.GetString("TbSettingsTunMtu", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Stack 的本地化字符串。
|
||||
/// </summary>
|
||||
|
||||
@@ -1062,7 +1062,7 @@
|
||||
<data name="TbSettingsTunStack" xml:space="preserve">
|
||||
<value>پشته شبکه</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunMtu" xml:space="preserve">
|
||||
<data name="TbMtu" xml:space="preserve">
|
||||
<value>MTU</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableIPv6Address" xml:space="preserve">
|
||||
@@ -1075,7 +1075,7 @@
|
||||
<value>کلید خصوصی</value>
|
||||
</data>
|
||||
<data name="TbReserved" xml:space="preserve">
|
||||
<value>Reserved (2,3,4)</value>
|
||||
<value>Reserved</value>
|
||||
</data>
|
||||
<data name="TbLocalAddress" xml:space="preserve">
|
||||
<value>آدرس (IPv4, IPv6)</value>
|
||||
@@ -1725,4 +1725,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||
<data name="TbSettingsBindInterfaceTip" xml:space="preserve">
|
||||
<value>For multi-interface environments, enter the name of the interface to bind. Only effective on Windows systems and TUN mode</value>
|
||||
</data>
|
||||
<data name="TbPreSharedKey" xml:space="preserve">
|
||||
<value>PreSharedKey</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1059,7 +1059,7 @@
|
||||
<data name="TbSettingsTunStack" xml:space="preserve">
|
||||
<value>Pile de protocoles</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunMtu" xml:space="preserve">
|
||||
<data name="TbMtu" xml:space="preserve">
|
||||
<value>MTU</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableIPv6Address" xml:space="preserve">
|
||||
@@ -1072,7 +1072,7 @@
|
||||
<value>PrivateKey</value>
|
||||
</data>
|
||||
<data name="TbReserved" xml:space="preserve">
|
||||
<value>Reserved (2,3,4)</value>
|
||||
<value>Reserved</value>
|
||||
</data>
|
||||
<data name="TbLocalAddress" xml:space="preserve">
|
||||
<value>Address (IPv4,IPv6)</value>
|
||||
@@ -1716,4 +1716,13 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||
<data name="TbSettingsBindInterfaceTip" xml:space="preserve">
|
||||
<value>Pour les environnements multi-interfaces, entrez le nom de l'interface à lier. Ne fonctionne que sur les systèmes Windows et en mode TUN</value>
|
||||
</data>
|
||||
<data name="menuUdpTestServer" xml:space="preserve">
|
||||
<value>Test Configurations UDP Delay</value>
|
||||
</data>
|
||||
<data name="TbSettingsUdpTestUrl" xml:space="preserve">
|
||||
<value>UDP Test Url</value>
|
||||
</data>
|
||||
<data name="TbPreSharedKey" xml:space="preserve">
|
||||
<value>PreSharedKey</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1062,7 +1062,7 @@
|
||||
<data name="TbSettingsTunStack" xml:space="preserve">
|
||||
<value>Hálózati verem</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunMtu" xml:space="preserve">
|
||||
<data name="TbMtu" xml:space="preserve">
|
||||
<value>MTU</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableIPv6Address" xml:space="preserve">
|
||||
@@ -1075,7 +1075,7 @@
|
||||
<value>Privát kulcs</value>
|
||||
</data>
|
||||
<data name="TbReserved" xml:space="preserve">
|
||||
<value>Fenntartott (2,3,4)</value>
|
||||
<value>Fenntartott</value>
|
||||
</data>
|
||||
<data name="TbLocalAddress" xml:space="preserve">
|
||||
<value>Cím (IPv4, IPv6)</value>
|
||||
@@ -1725,4 +1725,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||
<data name="TbSettingsBindInterfaceTip" xml:space="preserve">
|
||||
<value>For multi-interface environments, enter the name of the interface to bind. Only effective on Windows systems and TUN mode</value>
|
||||
</data>
|
||||
<data name="TbPreSharedKey" xml:space="preserve">
|
||||
<value>PreSharedKey</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1062,7 +1062,7 @@
|
||||
<data name="TbSettingsTunStack" xml:space="preserve">
|
||||
<value>Stack</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunMtu" xml:space="preserve">
|
||||
<data name="TbMtu" xml:space="preserve">
|
||||
<value>MTU</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableIPv6Address" xml:space="preserve">
|
||||
@@ -1075,7 +1075,7 @@
|
||||
<value>Private Key</value>
|
||||
</data>
|
||||
<data name="TbReserved" xml:space="preserve">
|
||||
<value>Reserved (2,3,4)</value>
|
||||
<value>Reserved</value>
|
||||
</data>
|
||||
<data name="TbLocalAddress" xml:space="preserve">
|
||||
<value>Address (IPv4, IPv6)</value>
|
||||
@@ -1725,4 +1725,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||
<data name="TbSettingsBindInterfaceTip" xml:space="preserve">
|
||||
<value>For multi-interface environments, enter the name of the interface to bind. Only effective on Windows systems and TUN mode</value>
|
||||
</data>
|
||||
<data name="TbPreSharedKey" xml:space="preserve">
|
||||
<value>PreSharedKey</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1062,7 +1062,7 @@
|
||||
<data name="TbSettingsTunStack" xml:space="preserve">
|
||||
<value>Сетевой стек</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunMtu" xml:space="preserve">
|
||||
<data name="TbMtu" xml:space="preserve">
|
||||
<value>MTU</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableIPv6Address" xml:space="preserve">
|
||||
@@ -1075,7 +1075,7 @@
|
||||
<value>Приватный ключ</value>
|
||||
</data>
|
||||
<data name="TbReserved" xml:space="preserve">
|
||||
<value>Зарезервировано (2, 3, 4)</value>
|
||||
<value>Зарезервировано</value>
|
||||
</data>
|
||||
<data name="TbLocalAddress" xml:space="preserve">
|
||||
<value>Адрес (IPv4, IPv6)</value>
|
||||
@@ -1725,4 +1725,7 @@
|
||||
<data name="TbSettingsBindInterfaceTip" xml:space="preserve">
|
||||
<value>Для среды с несколькими сетевыми интерфейсами укажите имя интерфейса для привязки. Работает только в Windows и режиме TUN</value>
|
||||
</data>
|
||||
<data name="TbPreSharedKey" xml:space="preserve">
|
||||
<value>PreSharedKey</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1059,7 +1059,7 @@
|
||||
<data name="TbSettingsTunStack" xml:space="preserve">
|
||||
<value>协议栈</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunMtu" xml:space="preserve">
|
||||
<data name="TbMtu" xml:space="preserve">
|
||||
<value>MTU</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableIPv6Address" xml:space="preserve">
|
||||
@@ -1072,7 +1072,7 @@
|
||||
<value>PrivateKey</value>
|
||||
</data>
|
||||
<data name="TbReserved" xml:space="preserve">
|
||||
<value>Reserved (2,3,4)</value>
|
||||
<value>Reserved</value>
|
||||
</data>
|
||||
<data name="TbLocalAddress" xml:space="preserve">
|
||||
<value>Address (IPv4,IPv6)</value>
|
||||
@@ -1722,4 +1722,7 @@
|
||||
<data name="TbSettingsBindInterfaceTip" xml:space="preserve">
|
||||
<value>用于多网口环境,填写要绑定的网口名称,仅生效于 Windows 系统和 TUN 模式</value>
|
||||
</data>
|
||||
<data name="TbPreSharedKey" xml:space="preserve">
|
||||
<value>PreSharedKey</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1059,7 +1059,7 @@
|
||||
<data name="TbSettingsTunStack" xml:space="preserve">
|
||||
<value>協定堆疊</value>
|
||||
</data>
|
||||
<data name="TbSettingsTunMtu" xml:space="preserve">
|
||||
<data name="TbMtu" xml:space="preserve">
|
||||
<value>MTU</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableIPv6Address" xml:space="preserve">
|
||||
@@ -1072,7 +1072,7 @@
|
||||
<value>PrivateKey</value>
|
||||
</data>
|
||||
<data name="TbReserved" xml:space="preserve">
|
||||
<value>Reserved (2,3,4)</value>
|
||||
<value>Reserved</value>
|
||||
</data>
|
||||
<data name="TbLocalAddress" xml:space="preserve">
|
||||
<value>Address (Ipv4,Ipv6)</value>
|
||||
@@ -1722,4 +1722,7 @@
|
||||
<data name="TbSettingsBindInterfaceTip" xml:space="preserve">
|
||||
<value>For multi-interface environments, enter the name of the interface to bind. Only effective on Windows systems and TUN mode</value>
|
||||
</data>
|
||||
<data name="TbPreSharedKey" xml:space="preserve">
|
||||
<value>PreSharedKey</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -309,7 +309,7 @@ public partial class CoreConfigSingboxService
|
||||
{
|
||||
var protocolExtra = _node.GetProtocolExtra();
|
||||
|
||||
endpoint.address = Utils.String2List(protocolExtra.WgInterfaceAddress);
|
||||
endpoint.address = Utils.String2List(protocolExtra.WgInterfaceAddress)?.Select(s => s.Trim()).ToList() ?? ["172.16.0.2/32"];
|
||||
endpoint.type = Global.ProtocolTypes[_node.ConfigType];
|
||||
|
||||
switch (_node.ConfigType)
|
||||
@@ -318,13 +318,12 @@ public partial class CoreConfigSingboxService
|
||||
{
|
||||
var peer = new Peer4Sbox
|
||||
{
|
||||
public_key = protocolExtra.WgPublicKey,
|
||||
public_key = protocolExtra.WgPublicKey ?? string.Empty,
|
||||
pre_shared_key = protocolExtra.WgPresharedKey,
|
||||
reserved = Utils.String2List(protocolExtra.WgReserved)?.Select(int.Parse).ToList(),
|
||||
reserved = Utils.String2List(protocolExtra.WgReserved)?.Select(s => s.Trim()).Select(int.Parse).ToList(),
|
||||
address = _node.Address,
|
||||
port = _node.Port,
|
||||
// TODO default ["0.0.0.0/0", "::/0"]
|
||||
allowed_ips = new() { "0.0.0.0/0", "::/0" },
|
||||
allowed_ips = ["0.0.0.0/0", "::/0"],
|
||||
};
|
||||
endpoint.private_key = _node.Password;
|
||||
endpoint.mtu = protocolExtra.WgMtu > 0 ? protocolExtra.WgMtu : Global.TunMtus.First();
|
||||
|
||||
@@ -258,13 +258,14 @@ public partial class CoreConfigV2rayService
|
||||
var peer = new WireguardPeer4Ray
|
||||
{
|
||||
publicKey = protocolExtra.WgPublicKey ?? "",
|
||||
endpoint = address + ":" + _node.Port.ToString()
|
||||
endpoint = address + ":" + _node.Port.ToString(),
|
||||
preSharedKey = protocolExtra.WgPresharedKey,
|
||||
};
|
||||
var setting = new Outboundsettings4Ray
|
||||
{
|
||||
address = Utils.String2List(protocolExtra.WgInterfaceAddress),
|
||||
address = Utils.String2List(protocolExtra.WgInterfaceAddress)?.Select(s => s.Trim()).ToList() ?? ["172.16.0.2/32"],
|
||||
secretKey = _node.Password,
|
||||
reserved = Utils.String2List(protocolExtra.WgReserved)?.Select(int.Parse).ToList(),
|
||||
reserved = Utils.String2List(protocolExtra.WgReserved)?.Select(s => s.Trim()).Select(int.Parse).ToList(),
|
||||
mtu = protocolExtra.WgMtu > 0 ? protocolExtra.WgMtu : Global.TunMtus.First(),
|
||||
peers = [peer]
|
||||
};
|
||||
|
||||
@@ -53,8 +53,9 @@ public class AddServerViewModel : MyReactiveObject
|
||||
[Reactive]
|
||||
public string WgPublicKey { get; set; }
|
||||
|
||||
//[Reactive]
|
||||
//public string WgPresharedKey { get; set; }
|
||||
[Reactive]
|
||||
public string WgPresharedKey { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string WgInterfaceAddress { get; set; }
|
||||
|
||||
@@ -159,17 +160,8 @@ public class AddServerViewModel : MyReactiveObject
|
||||
switch (SelectedSource.GetNetwork())
|
||||
{
|
||||
case nameof(ETransport.raw):
|
||||
Host = value;
|
||||
break;
|
||||
|
||||
case nameof(ETransport.ws):
|
||||
Host = value;
|
||||
break;
|
||||
|
||||
case nameof(ETransport.httpupgrade):
|
||||
Host = value;
|
||||
break;
|
||||
|
||||
case nameof(ETransport.xhttp):
|
||||
Host = value;
|
||||
break;
|
||||
@@ -202,13 +194,7 @@ public class AddServerViewModel : MyReactiveObject
|
||||
break;
|
||||
|
||||
case nameof(ETransport.ws):
|
||||
Path = value;
|
||||
break;
|
||||
|
||||
case nameof(ETransport.httpupgrade):
|
||||
Path = value;
|
||||
break;
|
||||
|
||||
case nameof(ETransport.xhttp):
|
||||
Path = value;
|
||||
break;
|
||||
@@ -303,6 +289,7 @@ public class AddServerViewModel : MyReactiveObject
|
||||
VlessEncryption = protocolExtra.VlessEncryption?.IsNullOrEmpty() == false ? protocolExtra.VlessEncryption : Global.None;
|
||||
SsMethod = protocolExtra.SsMethod ?? string.Empty;
|
||||
WgPublicKey = protocolExtra.WgPublicKey ?? string.Empty;
|
||||
WgPresharedKey = protocolExtra.WgPresharedKey ?? string.Empty;
|
||||
WgInterfaceAddress = protocolExtra.WgInterfaceAddress ?? string.Empty;
|
||||
WgReserved = protocolExtra.WgReserved ?? string.Empty;
|
||||
WgMtu = protocolExtra.WgMtu ?? 1280;
|
||||
@@ -401,6 +388,7 @@ public class AddServerViewModel : MyReactiveObject
|
||||
VlessEncryption = VlessEncryption.NullIfEmpty(),
|
||||
SsMethod = SsMethod.NullIfEmpty(),
|
||||
WgPublicKey = WgPublicKey.NullIfEmpty(),
|
||||
WgPresharedKey = WgPresharedKey.NullIfEmpty(),
|
||||
WgInterfaceAddress = WgInterfaceAddress.NullIfEmpty(),
|
||||
WgReserved = WgReserved.NullIfEmpty(),
|
||||
WgMtu = WgMtu >= 576 ? WgMtu : null,
|
||||
|
||||
@@ -508,7 +508,7 @@
|
||||
Grid.Row="2"
|
||||
ColumnDefinitions="300,Auto"
|
||||
IsVisible="False"
|
||||
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto">
|
||||
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto">
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
@@ -542,43 +542,57 @@
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbReserved}" />
|
||||
Text="{x:Static resx:ResUI.TbPreSharedKey}" />
|
||||
<TextBox
|
||||
x:Name="txtPath9"
|
||||
x:Name="txtPreSharedKey9"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Watermark="2,3,4" />
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbReserved}" />
|
||||
<TextBox
|
||||
x:Name="txtPath9"
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Watermark="0, 0, 0" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbLocalAddress}" />
|
||||
<TextBox
|
||||
x:Name="txtRequestHost9"
|
||||
Grid.Row="4"
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Watermark="Ipv4,Ipv6" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Row="6"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSettingsTunMtu}" />
|
||||
Text="{x:Static resx:ResUI.TbMtu}" />
|
||||
<TextBox
|
||||
x:Name="txtShortId9"
|
||||
Grid.Row="5"
|
||||
Grid.Row="6"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Watermark="1500" />
|
||||
Watermark="1280" />
|
||||
</Grid>
|
||||
<Grid
|
||||
x:Name="gridAnytls"
|
||||
@@ -850,7 +864,7 @@
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="MTU" />
|
||||
Text="{x:Static resx:ResUI.TbMtu}" />
|
||||
<TextBox
|
||||
x:Name="txtKcpMtu"
|
||||
Grid.Row="1"
|
||||
|
||||
@@ -185,6 +185,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
case EConfigType.WireGuard:
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId9.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.WgPublicKey, v => v.txtPublicKey9.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.WgPresharedKey, v => v.txtPreSharedKey9.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.WgReserved, v => v.txtPath9.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.WgInterfaceAddress, v => v.txtRequestHost9.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.WgMtu, v => v.txtShortId9.Text).DisposeWith(disposables);
|
||||
|
||||
@@ -869,7 +869,7 @@
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbSettingsTunMtu}" />
|
||||
Text="{x:Static resx:ResUI.TbMtu}" />
|
||||
<ComboBox
|
||||
x:Name="cmbMtu"
|
||||
Grid.Row="5"
|
||||
|
||||
@@ -678,6 +678,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="300" />
|
||||
@@ -721,14 +722,14 @@
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbReserved}" />
|
||||
Text="{x:Static resx:ResUI.TbPreSharedKey}" />
|
||||
<TextBox
|
||||
x:Name="txtPath9"
|
||||
x:Name="txtPreSharedKey9"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
materialDesign:HintAssist.Hint="2,3,4"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
@@ -737,10 +738,26 @@
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbReserved}" />
|
||||
<TextBox
|
||||
x:Name="txtPath9"
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
materialDesign:HintAssist.Hint="0, 0, 0"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbLocalAddress}" />
|
||||
<TextBox
|
||||
x:Name="txtRequestHost9"
|
||||
Grid.Row="4"
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
@@ -748,20 +765,20 @@
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Row="6"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsTunMtu}" />
|
||||
Text="{x:Static resx:ResUI.TbMtu}" />
|
||||
<TextBox
|
||||
x:Name="txtShortId9"
|
||||
Grid.Row="5"
|
||||
Grid.Row="6"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
materialDesign:HintAssist.Hint="1500"
|
||||
materialDesign:HintAssist.Hint="1280"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
</Grid>
|
||||
<Grid
|
||||
@@ -1119,7 +1136,7 @@
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="MTU" />
|
||||
Text="{x:Static resx:ResUI.TbMtu}" />
|
||||
<TextBox
|
||||
x:Name="txtKcpMtu"
|
||||
Grid.Row="1"
|
||||
|
||||
@@ -184,6 +184,7 @@ public partial class AddServerWindow
|
||||
case EConfigType.WireGuard:
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId9.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.WgPublicKey, v => v.txtPublicKey9.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.WgPresharedKey, v => v.txtPreSharedKey9.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.WgReserved, v => v.txtPath9.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.WgInterfaceAddress, v => v.txtRequestHost9.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.WgMtu, v => v.txtShortId9.Text).DisposeWith(disposables);
|
||||
|
||||
@@ -469,7 +469,7 @@
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsTunMtu}" />
|
||||
Text="{x:Static resx:ResUI.TbMtu}" />
|
||||
<TextBox Style="{StaticResource DefTextBox}"
|
||||
x:Name="txtKcpmtu"
|
||||
Grid.Row="1"
|
||||
@@ -1133,7 +1133,7 @@
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbSettingsTunMtu}" />
|
||||
Text="{x:Static resx:ResUI.TbMtu}" />
|
||||
<ComboBox
|
||||
x:Name="cmbMtu"
|
||||
Grid.Row="5"
|
||||
|
||||
Reference in New Issue
Block a user