You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Program.cs 7.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using Shadowsocks.Protocol;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.CommandLine;
  5. using System.CommandLine.Invocation;
  6. using System.Net;
  7. using System.Text;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. namespace Shadowsocks.CLI
  11. {
  12. internal class Program
  13. {
  14. private static Task<int> Main(string[] args)
  15. {
  16. var clientCommand = new Command("client", "Shadowsocks client.");
  17. clientCommand.AddAlias("c");
  18. clientCommand.AddOption(new Option<string?>("--listen", "The address and port to listen on for both SOCKS5 and HTTP proxy."));
  19. clientCommand.AddOption(new Option<string?>("--listen-socks", "The address and port to listen on for SOCKS5 proxy."));
  20. clientCommand.AddOption(new Option<string?>("--listen-http", "The address and port to listen on for HTTP proxy."));
  21. clientCommand.AddOption(new Option<string>("--server-address", "Address of the remote Shadowsocks server to connect to."));
  22. clientCommand.AddOption(new Option<int>("--server-port", "Port of the remote Shadowsocks server to connect to."));
  23. clientCommand.AddOption(new Option<string>("--method", "Encryption method to use for the remote Shadowsocks server."));
  24. clientCommand.AddOption(new Option<string?>("--password", "Password to use for the remote Shadowsocks server."));
  25. clientCommand.AddOption(new Option<string?>("--key", "Encryption key (NOT password!) to use for the remote Shadowsocks server."));
  26. clientCommand.AddOption(new Option<string?>("--plugin", "Plugin binary path."));
  27. clientCommand.AddOption(new Option<string?>("--plugin-opts", "Plugin options."));
  28. clientCommand.AddOption(new Option<string?>("--plugin-args", "Plugin startup arguments."));
  29. clientCommand.Handler = CommandHandler.Create(
  30. async (string? listen, string? listenSocks, string? listenHttp, string serverAddress, int serverPort, string method, string? password, string? key, string? plugin, string? pluginOpts, string? pluginArgs) =>
  31. {
  32. // TODO
  33. var localEP = IPEndPoint.Parse(listenSocks);
  34. var remoteEp = new DnsEndPoint(serverAddress, serverPort);
  35. byte[]? mainKey = null;
  36. if (!string.IsNullOrEmpty(key))
  37. mainKey = Encoding.UTF8.GetBytes(key);
  38. var tcpPipeListener = new TcpPipeListener(localEP);
  39. tcpPipeListener.Start(localEP, remoteEp, method, password, mainKey).Wait();
  40. });
  41. var serverCommand = new Command("server", "Shadowsocks server.");
  42. serverCommand.AddAlias("s");
  43. serverCommand.Handler = CommandHandler.Create(
  44. () =>
  45. {
  46. Console.WriteLine("Not implemented.");
  47. });
  48. var convertConfigCommand = new Command("convert-config", "Convert between different config formats. Supported formats: SIP002 links, SIP008 delivery JSON, and V2Ray JSON (outbound only).");
  49. convertConfigCommand.AddOption(new Option<string[]?>("--from-urls", "URL conversion sources. Multiple URLs are supported. Supported protocols are ss:// and https://."));
  50. convertConfigCommand.AddOption(new Option<string[]?>("--from-sip008-json", "SIP008 JSON conversion sources. Multiple JSON files are supported."));
  51. convertConfigCommand.AddOption(new Option<string[]?>("--from-v2ray-json", "V2Ray JSON conversion sources. Multiple JSON files are supported."));
  52. convertConfigCommand.AddOption(new Option<bool>("--prefix-group-name", "Whether to prefix group name to server names after conversion."));
  53. convertConfigCommand.AddOption(new Option<bool>("--to-urls", "Convert to ss:// links and print."));
  54. convertConfigCommand.AddOption(new Option<string?>("--to-sip008-json", "Convert to SIP008 JSON and save to the specified path."));
  55. convertConfigCommand.AddOption(new Option<string?>("--to-v2ray-json", "Convert to V2Ray JSON and save to the specified path."));
  56. convertConfigCommand.Handler = CommandHandler.Create(
  57. async (string[]? fromUrls, string[]? fromSip008Json, string[]? fromV2rayJson, bool prefixGroupName, bool toUrls, string? toSip008Json, string? toV2rayJson, CancellationToken cancellationToken) =>
  58. {
  59. var configConverter = new ConfigConverter(prefixGroupName);
  60. try
  61. {
  62. if (fromUrls != null)
  63. {
  64. var uris = new List<Uri>();
  65. foreach (var url in fromUrls)
  66. {
  67. if (Uri.TryCreate(url, UriKind.Absolute, out var uri))
  68. uris.Add(uri);
  69. else
  70. Console.WriteLine($"Invalid URL: {url}");
  71. }
  72. await configConverter.FromUrls(uris, cancellationToken);
  73. }
  74. if (fromSip008Json != null)
  75. await configConverter.FromSip008Json(fromSip008Json, cancellationToken);
  76. if (fromV2rayJson != null)
  77. await configConverter.FromV2rayJson(fromV2rayJson, cancellationToken);
  78. if (toUrls)
  79. {
  80. var uris = configConverter.ToUrls();
  81. foreach (var uri in uris)
  82. Console.WriteLine(uri.AbsoluteUri);
  83. }
  84. if (!string.IsNullOrEmpty(toSip008Json))
  85. await configConverter.ToSip008Json(toSip008Json, cancellationToken);
  86. if (!string.IsNullOrEmpty(toV2rayJson))
  87. await configConverter.ToV2rayJson(toV2rayJson, cancellationToken);
  88. }
  89. catch (Exception ex)
  90. {
  91. Console.WriteLine(ex.Message);
  92. }
  93. });
  94. var utilitiesCommand = new Command("utilities", "Shadowsocks-related utilities.")
  95. {
  96. convertConfigCommand,
  97. };
  98. utilitiesCommand.AddAlias("u");
  99. utilitiesCommand.AddAlias("util");
  100. utilitiesCommand.AddAlias("utils");
  101. var rootCommand = new RootCommand("CLI for Shadowsocks server and client implementation in C#.")
  102. {
  103. clientCommand,
  104. serverCommand,
  105. utilitiesCommand,
  106. };
  107. Console.OutputEncoding = Encoding.UTF8;
  108. return rootCommand.InvokeAsync(args);
  109. }
  110. }
  111. }