diff --git a/Shadowsocks.Interop/Shadowsocks.Interop.csproj b/Shadowsocks.Interop/Shadowsocks.Interop.csproj
index 2991887b..2e8a8b98 100644
--- a/Shadowsocks.Interop/Shadowsocks.Interop.csproj
+++ b/Shadowsocks.Interop/Shadowsocks.Interop.csproj
@@ -5,4 +5,8 @@
enable
+
+
+
+
diff --git a/Shadowsocks.Interop/SsRust/Config.cs b/Shadowsocks.Interop/SsRust/Config.cs
index 1be66e0c..b29e854e 100644
--- a/Shadowsocks.Interop/SsRust/Config.cs
+++ b/Shadowsocks.Interop/SsRust/Config.cs
@@ -1,16 +1,117 @@
-using System;
+using Shadowsocks.Models;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Text.Json.Serialization;
namespace Shadowsocks.Interop.SsRust
{
- public class Config
+ public class Config : IGroup
{
+ ///
+ public int Version { get; set; }
+
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.Never)]
+ public List Servers { get; set; }
+
+ ///
+ /// Gets or sets the listening address.
+ ///
+ public string LocalAddress { get; set; }
+
+ ///
+ /// Gets or sets the listening port.
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.Never)]
+ public int LocalPort { get; set; }
+
+ ///
+ /// Gets or sets the timeout for UDP associations in seconds.
+ /// Defaults to 300 seconds (5 minutes).
+ ///
+ public int UdpTimeout { get; set; }
+
+ ///
+ /// Gets or sets the maximum number of UDP associations.
+ /// Defaults to 0 (unlimited).
+ ///
+ public int UdpMaxAssociations { get; set; }
+
+ ///
+ /// Gets or sets the server manager address.
+ ///
+ public string ManagerAddress { get; set; }
+
+ ///
+ /// Gets or sets the server manager port.
+ ///
+ public int ManagerPort { get; set; }
+
+ ///
+ /// Gets or sets the DNS server used to resolve hostnames.
+ ///
+ public string Dns { get; set; }
+
+ ///
+ /// Gets or sets the mode.
+ /// Defaults to tcp_only.
+ /// Can also be tcp_and_udp or udp_only.
+ ///
+ public string Mode { get; set; }
+
+ ///
+ /// Gets or sets TCP_NODELAY.
+ /// Defaults to false.
+ ///
+ public bool NoDelay { get; set; }
+
+ ///
+ /// Gets or sets the soft and hard limit of file descriptors.
+ ///
+ public int Nofile { get; set; }
+
+ ///
+ /// Gets or sets whether IPv6 addresses take precedence over IPv4 addresses for resolved hostnames.
+ /// Defaults to false.
+ ///
+ public bool Ipv6First { get; set; }
+
public Config()
{
-
+ Version = 1;
+ Servers = new();
+ LocalAddress = "";
+ LocalPort = 1080;
+ UdpTimeout = 300;
+ UdpMaxAssociations = 0;
+ ManagerAddress = "";
+ ManagerPort = 0;
+ Dns = "";
+ Mode = "tcp_only";
+ NoDelay = false;
+ Nofile = 0;
+ Ipv6First = false;
}
+
+ ///
+ /// Gets the default configuration for Linux.
+ ///
+ public static Config DefaultLinux => new()
+ {
+ LocalAddress = "::1",
+ Mode = "tcp_and_udp",
+ NoDelay = true,
+ Nofile = 32768,
+ Ipv6First = true,
+ };
+
+ ///
+ /// Gets the default configuration for Windows.
+ ///
+ public static Config DefaultWindows => new()
+ {
+ LocalAddress = "::1",
+ Mode = "tcp_and_udp",
+ Ipv6First = true,
+ };
}
}
diff --git a/Shadowsocks.Interop/V2Ray/ApiObject.cs b/Shadowsocks.Interop/V2Ray/ApiObject.cs
new file mode 100644
index 00000000..5cb599e9
--- /dev/null
+++ b/Shadowsocks.Interop/V2Ray/ApiObject.cs
@@ -0,0 +1,37 @@
+using System.Collections.Generic;
+
+namespace Shadowsocks.Interop.V2Ray
+{
+ public class ApiObject
+ {
+ ///
+ /// Gets or sets the outbound tag for the API.
+ ///
+ public string Tag { get; set; }
+
+ ///
+ /// Gets or sets the list of API services to enable.
+ ///
+ public List Services { get; set; }
+
+ public ApiObject()
+ {
+ Tag = "";
+ Services = new();
+ }
+
+ ///
+ /// Gets the default API object.
+ ///
+ public static ApiObject Default => new()
+ {
+ Tag = "api",
+ Services = new()
+ {
+ "HandlerService",
+ "LoggerService",
+ "StatsService",
+ },
+ };
+ }
+}
diff --git a/Shadowsocks.Interop/V2Ray/Config.cs b/Shadowsocks.Interop/V2Ray/Config.cs
index 4ef63bfb..bc62cf65 100644
--- a/Shadowsocks.Interop/V2Ray/Config.cs
+++ b/Shadowsocks.Interop/V2Ray/Config.cs
@@ -1,16 +1,50 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Text.Json.Serialization;
namespace Shadowsocks.Interop.V2Ray
{
public class Config
{
- public Config()
+ public LogObject Log { get; set; }
+ public ApiObject Api { get; set; }
+ public DnsObject Dns { get; set; }
+ public RoutingObject Routing { get; set; }
+ public PolicyObject Policy { get; set; }
+ public InboundObject Inbounds { get; set; }
+ public OutboundObject Outbounds { get; set; }
+ public TransportObject Transport { get; set; }
+ [JsonIgnore(Condition = JsonIgnoreCondition.Never)]
+ public StatsObject? Stats { get; set; }
+ public ReverseObject Reverse { get; set; }
+
+ public Config(bool stats = true)
{
-
+ Log = new();
+ Api = new();
+ Dns = new();
+ Routing = new();
+ Policy = new();
+ Inbounds = new();
+ Outbounds = new();
+ Transport = new();
+ Stats = stats ? new() : null;
+ Reverse = new();
}
+
+ ///
+ /// Gets the default configuration.
+ ///
+ public static Config Default => new()
+ {
+ Log = new(),
+ Api = ApiObject.Default,
+ Dns = new(),
+ Routing = new(),
+ Policy = PolicyObject.Default,
+ Inbounds = new(),
+ Outbounds = new(),
+ Transport = new(),
+ Stats = new(),
+ Reverse = new(),
+ };
}
}
diff --git a/Shadowsocks.Interop/V2Ray/Dns/ServerObject.cs b/Shadowsocks.Interop/V2Ray/Dns/ServerObject.cs
new file mode 100644
index 00000000..c9a56681
--- /dev/null
+++ b/Shadowsocks.Interop/V2Ray/Dns/ServerObject.cs
@@ -0,0 +1,39 @@
+using System.Collections.Generic;
+
+namespace Shadowsocks.Interop.V2Ray.Dns
+{
+ public class ServerObject
+ {
+ ///
+ /// Gets or sets the DNS server address.
+ /// Supports UDP and DoH.
+ ///
+ public string Address { get; set; }
+
+ ///
+ /// Gets or sets the DNS server port.
+ /// Defaults to 53.
+ ///
+ public int Port { get; set; }
+
+ ///
+ /// Gets or sets the list of domains
+ /// that prefers this DNS server.
+ ///
+ public List Domains { get; set; }
+
+ ///
+ /// Gets or sets the ranges of IP addresses
+ /// this DNS server is expected to return.
+ ///
+ public List ExpectIPs { get; set; }
+
+ public ServerObject()
+ {
+ Address = "";
+ Port = 53;
+ Domains = new();
+ ExpectIPs = new();
+ }
+ }
+}
diff --git a/Shadowsocks.Interop/V2Ray/DnsObject.cs b/Shadowsocks.Interop/V2Ray/DnsObject.cs
new file mode 100644
index 00000000..42327eb7
--- /dev/null
+++ b/Shadowsocks.Interop/V2Ray/DnsObject.cs
@@ -0,0 +1,27 @@
+using Shadowsocks.Interop.V2Ray.Dns;
+using System.Collections.Generic;
+
+namespace Shadowsocks.Interop.V2Ray
+{
+ public class DnsObject
+ {
+ ///
+ /// Gets or sets the dictionary storing hosts.
+ /// The key is the hostname.
+ /// The value can either be a hostname or an IP address.
+ ///
+ public Dictionary Hosts { get; set; }
+
+ ///
+ /// Gets or sets the list of DNS servers.
+ /// A DNS server can either be a or a string.
+ ///
+ public List