@@ -5,4 +5,8 @@ | |||
<Nullable>enable</Nullable> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\Shadowsocks\Shadowsocks.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@@ -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<Server> | |||
{ | |||
/// <inheritdoc/> | |||
public int Version { get; set; } | |||
/// <inheritdoc/> | |||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)] | |||
public List<Server> Servers { get; set; } | |||
/// <summary> | |||
/// Gets or sets the listening address. | |||
/// </summary> | |||
public string LocalAddress { get; set; } | |||
/// <summary> | |||
/// Gets or sets the listening port. | |||
/// </summary> | |||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)] | |||
public int LocalPort { get; set; } | |||
/// <summary> | |||
/// Gets or sets the timeout for UDP associations in seconds. | |||
/// Defaults to 300 seconds (5 minutes). | |||
/// </summary> | |||
public int UdpTimeout { get; set; } | |||
/// <summary> | |||
/// Gets or sets the maximum number of UDP associations. | |||
/// Defaults to 0 (unlimited). | |||
/// </summary> | |||
public int UdpMaxAssociations { get; set; } | |||
/// <summary> | |||
/// Gets or sets the server manager address. | |||
/// </summary> | |||
public string ManagerAddress { get; set; } | |||
/// <summary> | |||
/// Gets or sets the server manager port. | |||
/// </summary> | |||
public int ManagerPort { get; set; } | |||
/// <summary> | |||
/// Gets or sets the DNS server used to resolve hostnames. | |||
/// </summary> | |||
public string Dns { get; set; } | |||
/// <summary> | |||
/// Gets or sets the mode. | |||
/// Defaults to tcp_only. | |||
/// Can also be tcp_and_udp or udp_only. | |||
/// </summary> | |||
public string Mode { get; set; } | |||
/// <summary> | |||
/// Gets or sets TCP_NODELAY. | |||
/// Defaults to false. | |||
/// </summary> | |||
public bool NoDelay { get; set; } | |||
/// <summary> | |||
/// Gets or sets the soft and hard limit of file descriptors. | |||
/// </summary> | |||
public int Nofile { get; set; } | |||
/// <summary> | |||
/// Gets or sets whether IPv6 addresses take precedence over IPv4 addresses for resolved hostnames. | |||
/// Defaults to false. | |||
/// </summary> | |||
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; | |||
} | |||
/// <summary> | |||
/// Gets the default configuration for Linux. | |||
/// </summary> | |||
public static Config DefaultLinux => new() | |||
{ | |||
LocalAddress = "::1", | |||
Mode = "tcp_and_udp", | |||
NoDelay = true, | |||
Nofile = 32768, | |||
Ipv6First = true, | |||
}; | |||
/// <summary> | |||
/// Gets the default configuration for Windows. | |||
/// </summary> | |||
public static Config DefaultWindows => new() | |||
{ | |||
LocalAddress = "::1", | |||
Mode = "tcp_and_udp", | |||
Ipv6First = true, | |||
}; | |||
} | |||
} |
@@ -0,0 +1,37 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray | |||
{ | |||
public class ApiObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets the outbound tag for the API. | |||
/// </summary> | |||
public string Tag { get; set; } | |||
/// <summary> | |||
/// Gets or sets the list of API services to enable. | |||
/// </summary> | |||
public List<string> Services { get; set; } | |||
public ApiObject() | |||
{ | |||
Tag = ""; | |||
Services = new(); | |||
} | |||
/// <summary> | |||
/// Gets the default API object. | |||
/// </summary> | |||
public static ApiObject Default => new() | |||
{ | |||
Tag = "api", | |||
Services = new() | |||
{ | |||
"HandlerService", | |||
"LoggerService", | |||
"StatsService", | |||
}, | |||
}; | |||
} | |||
} |
@@ -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(); | |||
} | |||
/// <summary> | |||
/// Gets the default configuration. | |||
/// </summary> | |||
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(), | |||
}; | |||
} | |||
} |
@@ -0,0 +1,39 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray.Dns | |||
{ | |||
public class ServerObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets the DNS server address. | |||
/// Supports UDP and DoH. | |||
/// </summary> | |||
public string Address { get; set; } | |||
/// <summary> | |||
/// Gets or sets the DNS server port. | |||
/// Defaults to 53. | |||
/// </summary> | |||
public int Port { get; set; } | |||
/// <summary> | |||
/// Gets or sets the list of domains | |||
/// that prefers this DNS server. | |||
/// </summary> | |||
public List<string> Domains { get; set; } | |||
/// <summary> | |||
/// Gets or sets the ranges of IP addresses | |||
/// this DNS server is expected to return. | |||
/// </summary> | |||
public List<string> ExpectIPs { get; set; } | |||
public ServerObject() | |||
{ | |||
Address = ""; | |||
Port = 53; | |||
Domains = new(); | |||
ExpectIPs = new(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,27 @@ | |||
using Shadowsocks.Interop.V2Ray.Dns; | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray | |||
{ | |||
public class DnsObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets the dictionary storing hosts. | |||
/// The key is the hostname. | |||
/// The value can either be a hostname or an IP address. | |||
/// </summary> | |||
public Dictionary<string, string> Hosts { get; set; } | |||
/// <summary> | |||
/// Gets or sets the list of DNS servers. | |||
/// A DNS server can either be a <see cref="ServerObject"/> or a string. | |||
/// </summary> | |||
public List<object> Servers { get; set; } | |||
public DnsObject() | |||
{ | |||
Hosts = new(); | |||
Servers = new(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,31 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Inbound | |||
{ | |||
public class AllocateObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets the port allocation strategy. | |||
/// Defaults to "always". | |||
/// Available values: "always" | "random" | |||
/// </summary> | |||
public string Strategy { get; set; } | |||
/// <summary> | |||
/// Gets or sets the random port refreshing interval in minutes. | |||
/// Defaults to 5 minutes. | |||
/// </summary> | |||
public int Refresh { get; set; } | |||
/// <summary> | |||
/// Gets or sets the number of random ports. | |||
/// Defaults to 3. | |||
/// </summary> | |||
public int Concurrency { get; set; } | |||
public AllocateObject() | |||
{ | |||
Strategy = "always"; | |||
Refresh = 5; | |||
Concurrency = 3; | |||
} | |||
} | |||
} |
@@ -0,0 +1,28 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray.Inbound | |||
{ | |||
public class SniffingObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets whether to enable sniffing. | |||
/// Defaults to true (enabled). | |||
/// </summary> | |||
public bool Enabled { get; set; } | |||
/// <summary> | |||
/// Gets or sets the list of protocols that destination override is enabled. | |||
/// </summary> | |||
public List<string> DestOverride { get; set; } | |||
public SniffingObject() | |||
{ | |||
Enabled = true; | |||
DestOverride = new() | |||
{ | |||
"http", | |||
"tls", | |||
}; | |||
} | |||
} | |||
} |
@@ -0,0 +1,54 @@ | |||
using Shadowsocks.Interop.V2Ray.Inbound; | |||
using Shadowsocks.Interop.V2Ray.Transport; | |||
namespace Shadowsocks.Interop.V2Ray | |||
{ | |||
public class InboundObject | |||
{ | |||
public string Tag { get; set; } | |||
public string Listen { get; set; } | |||
public object Port { get; set; } | |||
public string Protocol { get; set; } | |||
public object? Settings { get; set; } | |||
public StreamSettingsObject StreamSettings { get; set; } | |||
public SniffingObject Sniffing { get; set; } | |||
public AllocateObject Allocate { get; set; } | |||
public InboundObject() | |||
{ | |||
Tag = ""; | |||
Listen = "0.0.0.0"; | |||
Port = ""; | |||
Protocol = ""; | |||
Settings = null; | |||
StreamSettings = new(); | |||
Sniffing = new(); | |||
Allocate = new(); | |||
} | |||
public static InboundObject DefaultLocalSocks => new() | |||
{ | |||
Tag = "socks-in", | |||
Listen = "127.0.0.1", | |||
Port = 1080, | |||
Protocol = "socks", | |||
Settings = Protocols.Socks.InboundConfigurationObject.Default, | |||
Sniffing = new() | |||
{ | |||
Enabled = false, | |||
}, | |||
}; | |||
public static InboundObject DefaultLocalHttp => new() | |||
{ | |||
Tag = "http-in", | |||
Listen = "127.0.0.1", | |||
Port = 8080, | |||
Protocol = "http", | |||
Sniffing = new() | |||
{ | |||
Enabled = false, | |||
}, | |||
}; | |||
} | |||
} |
@@ -0,0 +1,31 @@ | |||
namespace Shadowsocks.Interop.V2Ray | |||
{ | |||
public class LogObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets the path to the access log file. | |||
/// Defaults to empty, which prints to stdout. | |||
/// </summary> | |||
public string Access { get; set; } | |||
/// <summary> | |||
/// Gets or sets the path to the error log file. | |||
/// Defaults to empty, which prints to stdout. | |||
/// </summary> | |||
public string Error { get; set; } | |||
/// <summary> | |||
/// Gets or sets the log level. | |||
/// Defaults to warning. | |||
/// Available values: "debug" | "info" | "warning" | "error" | "none" | |||
/// </summary> | |||
public string Loglevel { get; set; } | |||
public LogObject() | |||
{ | |||
Access = ""; | |||
Error = ""; | |||
Loglevel = "warning"; | |||
} | |||
} | |||
} |
@@ -0,0 +1,25 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Outbound | |||
{ | |||
public class MuxObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets whether to enable mux. | |||
/// Defaults to false (disabled). | |||
/// </summary> | |||
public bool Enabled { get; set; } | |||
/// <summary> | |||
/// Gets or sets the concurrency for a single TCP connection when using mux. | |||
/// Defaults to 8. | |||
/// Range: [1, 1024]. | |||
/// Set to -1 to disable the mux module. | |||
/// </summary> | |||
public int Concurrency { get; set; } | |||
public MuxObject() | |||
{ | |||
Enabled = false; | |||
Concurrency = 8; | |||
} | |||
} | |||
} |
@@ -0,0 +1,16 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Outbound | |||
{ | |||
public class ProxySettingsObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets the tag of the outbound | |||
/// used as the proxy. | |||
/// </summary> | |||
public string Tag { get; set; } | |||
public ProxySettingsObject() | |||
{ | |||
Tag = ""; | |||
} | |||
} | |||
} |
@@ -0,0 +1,86 @@ | |||
using Shadowsocks.Interop.V2Ray.Outbound; | |||
using Shadowsocks.Interop.V2Ray.Transport; | |||
using Shadowsocks.Models; | |||
using System.Net; | |||
namespace Shadowsocks.Interop.V2Ray | |||
{ | |||
public class OutboundObject | |||
{ | |||
public string Tag { get; set; } | |||
public string SendThrough { get; set; } | |||
public string Protocol { get; set; } | |||
public object? Settings { get; set; } | |||
public StreamSettingsObject StreamSettings { get; set; } | |||
public ProxySettingsObject ProxySettings { get; set; } | |||
public MuxObject Mux { get; set; } | |||
public OutboundObject() | |||
{ | |||
Tag = ""; | |||
SendThrough = "0.0.0.0"; | |||
Protocol = ""; | |||
Settings = null; | |||
StreamSettings = new(); | |||
ProxySettings = new(); | |||
Mux = new(); | |||
} | |||
/// <summary> | |||
/// Gets the <see cref="OutboundObject"/> for the SOCKS server. | |||
/// </summary> | |||
/// <param name="name">SOCKS server name. Used as outbound tag.</param> | |||
/// <param name="socksEndPoint">The SOCKS server.</param> | |||
/// <param name="username"></param> | |||
/// <param name="password"></param> | |||
/// <returns></returns> | |||
public static OutboundObject GetSocks(string name, DnsEndPoint socksEndPoint, string username = "", string password = "") => new() | |||
{ | |||
Tag = name, | |||
Protocol = "socks", | |||
Settings = new Protocols.Socks.OutboundConfigurationObject(socksEndPoint, username, password), | |||
}; | |||
/// <summary> | |||
/// Gets the <see cref="OutboundObject"/> for the Shadowsocks server. | |||
/// Plugins are not supported. Plugin information is silently discarded. | |||
/// </summary> | |||
/// <param name="server"></param> | |||
/// <returns></returns> | |||
public static OutboundObject GetShadowsocks(IServer server) => new() | |||
{ | |||
Tag = server.Name, | |||
Protocol = "shadowsocks", | |||
Settings = new Protocols.Shadowsocks.OutboundConfigurationObject(), | |||
}; | |||
/// <summary> | |||
/// Gets the <see cref="OutboundObject"/> for the Trojan server. | |||
/// </summary> | |||
/// <param name="address"></param> | |||
/// <param name="port"></param> | |||
/// <param name="password"></param> | |||
/// <returns></returns> | |||
public static OutboundObject GetTrojan(string name, string address, int port, string password) => new() | |||
{ | |||
Tag = name, | |||
Protocol = "trojan", | |||
Settings = new Protocols.Trojan.OutboundConfigurationObject(address, port, password), | |||
}; | |||
/// <summary> | |||
/// Gets the <see cref="OutboundObject"/> for the VMess server. | |||
/// </summary> | |||
/// <param name="name"></param> | |||
/// <param name="address"></param> | |||
/// <param name="port"></param> | |||
/// <param name="id"></param> | |||
/// <returns></returns> | |||
public static OutboundObject GetVMess(string name, string address, int port, string id) => new() | |||
{ | |||
Tag = name, | |||
Protocol = "vmess", | |||
Settings = new Protocols.VMess.OutboundConfigurationObject(address, port, id), | |||
}; | |||
} | |||
} |
@@ -0,0 +1,24 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Policy | |||
{ | |||
public class LevelPolicyObject | |||
{ | |||
public int Handshake { get; set; } | |||
public int ConnIdle { get; set; } | |||
public int UplinkOnly { get; set; } | |||
public int DownlinkOnly { get; set; } | |||
public bool StatsUserUplink { get; set; } | |||
public bool StatsUserDownlink { get; set; } | |||
public int BufferSize { get; set; } | |||
public LevelPolicyObject() | |||
{ | |||
Handshake = 4; | |||
ConnIdle = 300; | |||
UplinkOnly = 2; | |||
DownlinkOnly = 5; | |||
StatsUserUplink = false; | |||
StatsUserDownlink = false; | |||
BufferSize = 512; | |||
} | |||
} | |||
} |
@@ -0,0 +1,18 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Policy | |||
{ | |||
public class SystemPolicyObject | |||
{ | |||
public bool StatsInboundUplink { get; set; } | |||
public bool StatsInboundDownlink { get; set; } | |||
public bool StatsOutboundUplink { get; set; } | |||
public bool StatsOutboundDownlink { get; set; } | |||
public static SystemPolicyObject Default => new() | |||
{ | |||
StatsInboundUplink = true, | |||
StatsInboundDownlink = true, | |||
StatsOutboundUplink = true, | |||
StatsOutboundDownlink = true, | |||
}; | |||
} | |||
} |
@@ -0,0 +1,26 @@ | |||
using Shadowsocks.Interop.V2Ray.Policy; | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray | |||
{ | |||
public class PolicyObject | |||
{ | |||
public Dictionary<string, LevelPolicyObject> Levels { get; set; } | |||
public SystemPolicyObject System { get; set; } | |||
public PolicyObject() | |||
{ | |||
Levels = new(); | |||
System = new(); | |||
} | |||
/// <summary> | |||
/// Gets the default policy object. | |||
/// </summary> | |||
public static PolicyObject Default => new() | |||
{ | |||
Levels = new(), | |||
System = SystemPolicyObject.Default, | |||
}; | |||
} | |||
} |
@@ -0,0 +1,14 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Protocols | |||
{ | |||
public class AccountObject | |||
{ | |||
public string User { get; set; } | |||
public string Pass { get; set; } | |||
public AccountObject() | |||
{ | |||
User = ""; | |||
Pass = ""; | |||
} | |||
} | |||
} |
@@ -0,0 +1,16 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.Freedom | |||
{ | |||
public class OutboundConfigurationObject | |||
{ | |||
public string DomainStrategy { get; set; } | |||
public string Redirect { get; set; } | |||
public int UserLevel { get; set; } | |||
public OutboundConfigurationObject() | |||
{ | |||
DomainStrategy = "AsIs"; | |||
Redirect = ""; | |||
UserLevel = 0; | |||
} | |||
} | |||
} |
@@ -0,0 +1,30 @@ | |||
using System; | |||
using System.Text.Json.Serialization; | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.Shadowsocks | |||
{ | |||
public class InboundConfigurationObject | |||
{ | |||
public string Email { get; set; } | |||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)] | |||
public string Method { get; set; } | |||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)] | |||
public string Password { get; set; } | |||
public int Level { get; set; } | |||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)] | |||
public string Network { get; set; } | |||
public InboundConfigurationObject() | |||
{ | |||
Email = ""; | |||
Method = "chacha20-ietf-poly1305"; | |||
Password = new Guid().ToString(); | |||
Level = 0; | |||
Network = "tcp,udp"; | |||
} | |||
} | |||
} |
@@ -0,0 +1,22 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.Shadowsocks | |||
{ | |||
public class OutboundConfigurationObject | |||
{ | |||
public List<ServerObject> Servers { get; set; } | |||
public OutboundConfigurationObject() | |||
{ | |||
Servers = new(); | |||
} | |||
public OutboundConfigurationObject(string address, int port, string method, string password) | |||
{ | |||
Servers = new() | |||
{ | |||
new(address, port, method, password), | |||
}; | |||
} | |||
} | |||
} |
@@ -0,0 +1,43 @@ | |||
using System.Text.Json.Serialization; | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.Shadowsocks | |||
{ | |||
public class ServerObject | |||
{ | |||
public string Email { get; set; } | |||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)] | |||
public string Address { get; set; } | |||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)] | |||
public int Port { get; set; } | |||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)] | |||
public string Method { get; set; } | |||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)] | |||
public string Password { get; set; } | |||
public int Level { get; set; } | |||
public ServerObject() | |||
{ | |||
Email = ""; | |||
Address = ""; | |||
Port = 8388; | |||
Method = "chacha20-ietf-poly1305"; | |||
Password = ""; | |||
Level = 0; | |||
} | |||
public ServerObject(string address, int port, string method, string password) | |||
{ | |||
Email = ""; | |||
Address = address; | |||
Port = port; | |||
Method = method; | |||
Password = password; | |||
Level = 0; | |||
} | |||
} | |||
} |
@@ -0,0 +1,27 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.Socks | |||
{ | |||
public class InboundConfigurationObject | |||
{ | |||
public string Auth { get; set; } | |||
public List<AccountObject> Accounts { get; set; } | |||
public bool Udp { get; set; } | |||
public string Ip { get; set; } | |||
public int UserLevel { get; set; } | |||
public InboundConfigurationObject() | |||
{ | |||
Auth = "noauth"; | |||
Accounts = new(); | |||
Udp = false; | |||
Ip = "127.0.0.1"; | |||
UserLevel = 0; | |||
} | |||
public static InboundConfigurationObject Default => new() | |||
{ | |||
Udp = true, | |||
}; | |||
} | |||
} |
@@ -0,0 +1,23 @@ | |||
using System.Collections.Generic; | |||
using System.Net; | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.Socks | |||
{ | |||
public class OutboundConfigurationObject | |||
{ | |||
public List<ServerObject> Servers { get; set; } | |||
public OutboundConfigurationObject() | |||
{ | |||
Servers = new(); | |||
} | |||
public OutboundConfigurationObject(DnsEndPoint socksEndPoint, string username = "", string password = "") | |||
{ | |||
Servers = new() | |||
{ | |||
new(socksEndPoint, username, password), | |||
}; | |||
} | |||
} | |||
} |
@@ -0,0 +1,33 @@ | |||
using System.Collections.Generic; | |||
using System.Net; | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.Socks | |||
{ | |||
public class ServerObject | |||
{ | |||
public string Address { get; set; } | |||
public int Port { get; set; } | |||
public List<UserObject> Users { get; set; } | |||
public ServerObject() | |||
{ | |||
Address = ""; | |||
Port = 0; | |||
Users = new(); | |||
} | |||
public ServerObject(DnsEndPoint socksEndPoint, string username = "", string password = "") | |||
{ | |||
Address = socksEndPoint.Host; | |||
Port = socksEndPoint.Port; | |||
Users = new(); | |||
var hasCredential = !string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password); | |||
if (hasCredential) | |||
Users.Add(new() | |||
{ | |||
User = username, | |||
Pass = password, | |||
}); | |||
} | |||
} | |||
} |
@@ -0,0 +1,16 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.Trojan | |||
{ | |||
public class ClientObject | |||
{ | |||
public string Password { get; set; } | |||
public string Email { get; set; } | |||
public int Level { get; set; } | |||
public ClientObject() | |||
{ | |||
Password = ""; | |||
Email = ""; | |||
Level = 0; | |||
} | |||
} | |||
} |
@@ -0,0 +1,18 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.Trojan | |||
{ | |||
public class FallbackObject | |||
{ | |||
public string Alpn { get; set; } | |||
public string Path { get; set; } | |||
public object Dest { get; set; } | |||
public int Xver { get; set; } | |||
public FallbackObject() | |||
{ | |||
Alpn = ""; | |||
Path = ""; | |||
Dest = 0; | |||
Xver = 0; | |||
} | |||
} | |||
} |
@@ -0,0 +1,16 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.Trojan | |||
{ | |||
public class InboundConfigurationObject | |||
{ | |||
public List<ClientObject> Clients { get; set; } | |||
public List<FallbackObject> Fallbacks { get; set; } | |||
public InboundConfigurationObject() | |||
{ | |||
Clients = new(); | |||
Fallbacks = new(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,22 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.Trojan | |||
{ | |||
public class OutboundConfigurationObject | |||
{ | |||
public List<ServerObject> Servers { get; set; } | |||
public OutboundConfigurationObject() | |||
{ | |||
Servers = new(); | |||
} | |||
public OutboundConfigurationObject(string address, int port, string password) | |||
{ | |||
Servers = new() | |||
{ | |||
new(address, port, password), | |||
}; | |||
} | |||
} | |||
} |
@@ -0,0 +1,29 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.Trojan | |||
{ | |||
public class ServerObject | |||
{ | |||
public string Address { get; set; } | |||
public int Port { get; set; } | |||
public string Password { get; set; } | |||
public string Email { get; set; } | |||
public int Level { get; set; } | |||
public ServerObject() | |||
{ | |||
Address = ""; | |||
Port = 0; | |||
Password = ""; | |||
Email = ""; | |||
Level = 0; | |||
} | |||
public ServerObject(string address, int port, string password) | |||
{ | |||
Address = address; | |||
Port = port; | |||
Password = password; | |||
Email = ""; | |||
Level = 0; | |||
} | |||
} | |||
} |
@@ -0,0 +1,7 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Protocols | |||
{ | |||
public class UserObject : AccountObject | |||
{ | |||
public int Level { get; set; } | |||
} | |||
} |
@@ -0,0 +1,12 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.VMess | |||
{ | |||
public class DetourObject | |||
{ | |||
public string To { get; set; } | |||
public DetourObject() | |||
{ | |||
To = ""; | |||
} | |||
} | |||
} |
@@ -0,0 +1,18 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.VMess | |||
{ | |||
public class InboundConfigurationObject | |||
{ | |||
public List<UserObject> Clients { get; set; } | |||
public UserObject Default { get; set; } | |||
public DetourObject Detour { get; set; } | |||
public InboundConfigurationObject() | |||
{ | |||
Clients = new(); | |||
Default = new(); | |||
Detour = new(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,22 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.VMess | |||
{ | |||
public class OutboundConfigurationObject | |||
{ | |||
public List<ServerObject> Vnext { get; set; } | |||
public OutboundConfigurationObject() | |||
{ | |||
Vnext = new(); | |||
} | |||
public OutboundConfigurationObject(string address, int port, string id) | |||
{ | |||
Vnext = new() | |||
{ | |||
new(address, port, id), | |||
}; | |||
} | |||
} | |||
} |
@@ -0,0 +1,28 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.VMess | |||
{ | |||
public class ServerObject | |||
{ | |||
public string Address { get; set; } | |||
public int Port { get; set; } | |||
public List<UserObject> Users { get; set; } | |||
public ServerObject() | |||
{ | |||
Address = ""; | |||
Port = 0; | |||
Users = new(); | |||
} | |||
public ServerObject(string address, int port, string id) | |||
{ | |||
Address = address; | |||
Port = port; | |||
Users = new() | |||
{ | |||
new(id), | |||
}; | |||
} | |||
} | |||
} |
@@ -0,0 +1,26 @@ | |||
using System; | |||
namespace Shadowsocks.Interop.V2Ray.Protocols.VMess | |||
{ | |||
/// <summary> | |||
/// The user object for VMess AEAD. | |||
/// </summary> | |||
public class UserObject | |||
{ | |||
public string Id { get; set; } | |||
public string Email { get; set; } | |||
public int Level { get; set; } | |||
public UserObject(string id = "") | |||
{ | |||
Id = id; | |||
Email = ""; | |||
Level = 0; | |||
} | |||
public static UserObject Default => new() | |||
{ | |||
Id = new Guid().ToString(), | |||
}; | |||
} | |||
} |
@@ -0,0 +1,22 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Reverse | |||
{ | |||
public class BridgeObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets the inbound tag for the bridge. | |||
/// </summary> | |||
public string Tag { get; set; } | |||
/// <summary> | |||
/// Gets or sets the domain name for the bridge. | |||
/// Can be omitted. | |||
/// </summary> | |||
public string Domain { get; set; } | |||
public BridgeObject() | |||
{ | |||
Tag = ""; | |||
Domain = ""; | |||
} | |||
} | |||
} |
@@ -0,0 +1,21 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Reverse | |||
{ | |||
public class PortalObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets the outbound tag for the portal. | |||
/// </summary> | |||
public string Tag { get; set; } | |||
/// <summary> | |||
/// Gets or sets the domain name for the portal. | |||
/// </summary> | |||
public string Domain { get; set; } | |||
public PortalObject() | |||
{ | |||
Tag = ""; | |||
Domain = ""; | |||
} | |||
} | |||
} |
@@ -0,0 +1,17 @@ | |||
using Shadowsocks.Interop.V2Ray.Reverse; | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray | |||
{ | |||
public class ReverseObject | |||
{ | |||
public List<BridgeObject> Bridges { get; set; } | |||
public List<PortalObject> Portals { get; set; } | |||
public ReverseObject() | |||
{ | |||
Bridges = new(); | |||
Portals = new(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,24 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray.Routing | |||
{ | |||
public class BalancerObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets the outbound tag for the load balancer. | |||
/// </summary> | |||
public string Tag { get; set; } | |||
/// <summary> | |||
/// Gets or sets a list of outbound tags | |||
/// to include in the load balancer. | |||
/// </summary> | |||
public List<string> Selector { get; set; } | |||
public BalancerObject() | |||
{ | |||
Tag = ""; | |||
Selector = new(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,40 @@ | |||
using System.Collections.Generic; | |||
using System.Text.Json.Serialization; | |||
namespace Shadowsocks.Interop.V2Ray.Routing | |||
{ | |||
public class RuleObject | |||
{ | |||
[JsonIgnore(Condition = JsonIgnoreCondition.Never)] | |||
public string Type { get; set; } | |||
public List<string> Domain { get; set; } | |||
public List<string> Ip { get; set; } | |||
public object Port { get; set; } | |||
public object SourcePort { get; set; } | |||
public string Network { get; set; } | |||
public List<string> Source { get; set; } | |||
public List<string> User { get; set; } | |||
public List<string> InboundTag { get; set; } | |||
public List<string> Protocol { get; set; } | |||
public string Attrs { get; set; } | |||
public string OutboundTag { get; set; } | |||
public string BalancerTag { get; set; } | |||
public RuleObject() | |||
{ | |||
Type = "field"; | |||
Domain = new(); | |||
Ip = new(); | |||
Port = ""; | |||
SourcePort = ""; | |||
Network = ""; | |||
Source = new(); | |||
User = new(); | |||
InboundTag = new(); | |||
Protocol = new(); | |||
Attrs = ""; | |||
OutboundTag = ""; | |||
BalancerTag = ""; | |||
} | |||
} | |||
} |
@@ -0,0 +1,32 @@ | |||
using Shadowsocks.Interop.V2Ray.Routing; | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray | |||
{ | |||
public class RoutingObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets the domain strategy used for routing. | |||
/// Default value: AsIs. | |||
/// Available values: "AsIs" | "IPIfNonMatch" | "IPOnDemand" | |||
/// </summary> | |||
public string DomainStrategy { get; set; } | |||
/// <summary> | |||
/// Gets or sets the list of routing rules. | |||
/// </summary> | |||
public List<RuleObject> Rules { get; set; } | |||
/// <summary> | |||
/// Gets or sets the list of load balancers. | |||
/// </summary> | |||
public List<BalancerObject> Balancers { get; set; } | |||
public RoutingObject() | |||
{ | |||
DomainStrategy = "AsIs"; | |||
Rules = new(); | |||
Balancers = new(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,6 @@ | |||
namespace Shadowsocks.Interop.V2Ray | |||
{ | |||
public class StatsObject | |||
{ | |||
} | |||
} |
@@ -0,0 +1,22 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray.Transport | |||
{ | |||
public class CertificateObject | |||
{ | |||
public string Usage { get; set; } | |||
public string CertificateFile { get; set; } | |||
public string KeyFile { get; set; } | |||
public List<string> Certificate { get; set; } | |||
public List<string> Key { get; set; } | |||
public CertificateObject() | |||
{ | |||
Usage = "encipherment"; | |||
CertificateFile = ""; | |||
KeyFile = ""; | |||
Certificate = new(); | |||
Key = new(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,29 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Transport | |||
{ | |||
public class DomainSocketObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets the path to the unix domain socket file. | |||
/// </summary> | |||
public string Path { get; set; } | |||
/// <summary> | |||
/// Gets or sets whether the domain socket is abstract. | |||
/// Defaults to false. | |||
/// </summary> | |||
public bool Abstract { get; set; } | |||
/// <summary> | |||
/// Gets or sets whether padding is used. | |||
/// Defaults to false. | |||
/// </summary> | |||
public bool Padding { get; set; } | |||
public DomainSocketObject() | |||
{ | |||
Path = ""; | |||
Abstract = false; | |||
Padding = false; | |||
} | |||
} | |||
} |
@@ -0,0 +1,23 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Transport.Header | |||
{ | |||
public class HeaderObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets the header type. | |||
/// Defaults to none. | |||
/// Available values: | |||
/// none | |||
/// srtp | |||
/// utp | |||
/// wechat-video | |||
/// dtls | |||
/// wireguard | |||
/// </summary> | |||
public string Type { get; set; } | |||
public HeaderObject() | |||
{ | |||
Type = "none"; | |||
} | |||
} | |||
} |
@@ -0,0 +1,47 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray.Transport.Header.Http | |||
{ | |||
public class HttpRequestObject | |||
{ | |||
public string Version { get; set; } | |||
public string Method { get; set; } | |||
public List<string> Path { get; set; } | |||
public Dictionary<string, List<string>> Headers { get; set; } | |||
public HttpRequestObject() | |||
{ | |||
Version = "1.1"; | |||
Method = "GET"; | |||
Path = new() | |||
{ | |||
"/", | |||
}; | |||
Headers = new() | |||
{ | |||
["Host"] = new() | |||
{ | |||
"www.baidu.com", | |||
"www.bing.com", | |||
}, | |||
["User-Agent"] = new() | |||
{ | |||
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36", | |||
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46", | |||
}, | |||
["Accept-Encoding"] = new() | |||
{ | |||
"gzip, deflate", | |||
}, | |||
["Connection"] = new() | |||
{ | |||
"keep-alive", | |||
}, | |||
["Pragma"] = new() | |||
{ | |||
"no-cache", | |||
}, | |||
}; | |||
} | |||
} | |||
} |
@@ -0,0 +1,44 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray.Transport.Header.Http | |||
{ | |||
public class HttpResponseObject | |||
{ | |||
public string Version { get; set; } | |||
public string Status { get; set; } | |||
public string Reason { get; set; } | |||
public Dictionary<string, List<string>> Headers { get; set; } | |||
public HttpResponseObject() | |||
{ | |||
Version = "1.1"; | |||
Status = "200"; | |||
Reason = "OK"; | |||
Headers = new() | |||
{ | |||
["Content-Type"] = new() | |||
{ | |||
"application/octet-stream", | |||
"video/mpeg", | |||
}, | |||
["Transfer-Encoding"] = new() | |||
{ | |||
"chunked", | |||
}, | |||
["Connection"] = new() | |||
{ | |||
"keep-alive", | |||
}, | |||
["Pragma"] = new() | |||
{ | |||
"no-cache", | |||
}, | |||
["Cache-Control"] = new() | |||
{ | |||
"private", | |||
"no-cache", | |||
}, | |||
}; | |||
} | |||
} | |||
} |
@@ -0,0 +1,18 @@ | |||
using Shadowsocks.Interop.V2Ray.Transport.Header.Http; | |||
namespace Shadowsocks.Interop.V2Ray.Transport.Header | |||
{ | |||
public class HttpHeaderObject : HeaderObject | |||
{ | |||
public HttpRequestObject request { get; set; } | |||
public HttpResponseObject response { get; set; } | |||
public HttpHeaderObject() | |||
{ | |||
Type = "http"; | |||
request = new(); | |||
response = new(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,16 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray.Transport | |||
{ | |||
public class HttpObject | |||
{ | |||
public List<string> Host { get; set; } | |||
public string Path { get; set; } | |||
public HttpObject() | |||
{ | |||
Host = new(); | |||
Path = "/"; | |||
} | |||
} | |||
} |
@@ -0,0 +1,30 @@ | |||
using Shadowsocks.Interop.V2Ray.Transport.Header; | |||
namespace Shadowsocks.Interop.V2Ray.Transport | |||
{ | |||
public class KcpObject | |||
{ | |||
public int Mtu { get; set; } | |||
public int Tti { get; set; } | |||
public int UplinkCapacity { get; set; } | |||
public int DownlinkCapacity { get; set; } | |||
public bool Congestion { get; set; } | |||
public int ReadBufferSize { get; set; } | |||
public int WriteBufferSize { get; set; } | |||
public HeaderObject Header { get; set; } | |||
public string Seed { get; set; } | |||
public KcpObject() | |||
{ | |||
Mtu = 1350; | |||
Tti = 50; | |||
UplinkCapacity = 5; | |||
DownlinkCapacity = 20; | |||
Congestion = false; | |||
ReadBufferSize = 2; | |||
WriteBufferSize = 2; | |||
Header = new(); | |||
Seed = ""; | |||
} | |||
} | |||
} |
@@ -0,0 +1,31 @@ | |||
using Shadowsocks.Interop.V2Ray.Transport.Header; | |||
namespace Shadowsocks.Interop.V2Ray.Transport | |||
{ | |||
public class QuicObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets the encryption method. | |||
/// Defaults to "none" (no encryption). | |||
/// Available values: "none" | "aes-128-gcm" | "chacha20-poly1305" | |||
/// </summary> | |||
public string Security { get; set; } | |||
/// <summary> | |||
/// Gets or sets the encryption key. | |||
/// </summary> | |||
public string Key { get; set; } | |||
/// <summary> | |||
/// Gets or sets the header options. | |||
/// </summary> | |||
public HeaderObject Header { get; set; } | |||
public QuicObject() | |||
{ | |||
Security = "none"; | |||
Key = ""; | |||
Header = new(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,16 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Transport | |||
{ | |||
public class SockoptObject | |||
{ | |||
public int Mark { get; set; } | |||
public bool TcpFastOpen { get; set; } | |||
public string Tproxy { get; set; } | |||
public SockoptObject() | |||
{ | |||
Mark = 0; | |||
TcpFastOpen = false; | |||
Tproxy = "off"; | |||
} | |||
} | |||
} |
@@ -0,0 +1,30 @@ | |||
namespace Shadowsocks.Interop.V2Ray.Transport | |||
{ | |||
public class StreamSettingsObject : TransportObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets the transport protocol type. | |||
/// Defaults to "tcp". | |||
/// Available values: "tcp" | "kcp" | "ws" | "http" | "domainsocket" | "quic" | |||
/// </summary> | |||
public string Network { get; set; } | |||
/// <summary> | |||
/// Gets or sets the transport encryption type. | |||
/// Defaults to "none" (no encryption). | |||
/// Available values: "none" | "tls" | |||
/// </summary> | |||
public string Security { get; set; } | |||
public TlsObject TlsSettings { get; set; } | |||
public SockoptObject Sockopt { get; set; } | |||
public StreamSettingsObject() | |||
{ | |||
Network = "tcp"; | |||
Security = "none"; | |||
TlsSettings = new(); | |||
Sockopt = new(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,23 @@ | |||
using Shadowsocks.Interop.V2Ray.Transport.Header; | |||
namespace Shadowsocks.Interop.V2Ray.Transport | |||
{ | |||
public class TcpObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets whether to use PROXY protocol. | |||
/// </summary> | |||
public bool AcceptProxyProtocol { get; set; } | |||
/// <summary> | |||
/// Gets or sets the header options. | |||
/// </summary> | |||
public object Header { get; set; } | |||
public TcpObject() | |||
{ | |||
AcceptProxyProtocol = false; | |||
Header = new HeaderObject(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,26 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray.Transport | |||
{ | |||
public class TlsObject | |||
{ | |||
public string ServerName { get; set; } | |||
public bool AllowInsecure { get; set; } | |||
public List<string> Alpn { get; set; } | |||
public List<CertificateObject> Certificates { get; set; } | |||
public bool DisableSystemRoot { get; set; } | |||
public TlsObject() | |||
{ | |||
ServerName = ""; | |||
AllowInsecure = false; | |||
Alpn = new() | |||
{ | |||
"h2", | |||
"http/1.1", | |||
}; | |||
Certificates = new(); | |||
DisableSystemRoot = false; | |||
} | |||
} | |||
} |
@@ -0,0 +1,29 @@ | |||
using System.Collections.Generic; | |||
namespace Shadowsocks.Interop.V2Ray.Transport | |||
{ | |||
public class WebSocketObject | |||
{ | |||
/// <summary> | |||
/// Gets or sets whether to use PROXY protocol. | |||
/// </summary> | |||
public bool AcceptProxyProtocol { get; set; } | |||
/// <summary> | |||
/// Gets or sets the HTTP query path. | |||
/// </summary> | |||
public string Path { get; set; } | |||
/// <summary> | |||
/// Gets or sets HTTP header key-value pairs. | |||
/// </summary> | |||
public Dictionary<string, string> Headers { get; set; } | |||
public WebSocketObject() | |||
{ | |||
AcceptProxyProtocol = false; | |||
Path = "/"; | |||
Headers = new(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,24 @@ | |||
using Shadowsocks.Interop.V2Ray.Transport; | |||
namespace Shadowsocks.Interop.V2Ray | |||
{ | |||
public class TransportObject | |||
{ | |||
public TcpObject TcpSettings { get; set; } | |||
public KcpObject KcpSettings { get; set; } | |||
public WebSocketObject WsSettings { get; set; } | |||
public HttpObject HttpSettings { get; set; } | |||
public QuicObject QuicSettings { get; set; } | |||
public DomainSocketObject DsSettings { get; set; } | |||
public TransportObject() | |||
{ | |||
TcpSettings = new(); | |||
KcpSettings = new(); | |||
WsSettings = new(); | |||
HttpSettings = new(); | |||
QuicSettings = new(); | |||
DsSettings = new(); | |||
} | |||
} | |||
} |