Browse Source

🎒 CLI: legacy backend

pull/3127/head
database64128 3 years ago
parent
commit
a8f0f58ed5
No known key found for this signature in database GPG Key ID: 1CA27546BEDB8B01
7 changed files with 172 additions and 19 deletions
  1. +10
    -0
      Shadowsocks.CLI/Backend.cs
  2. +57
    -0
      Shadowsocks.CLI/Client/Legacy.cs
  3. +29
    -0
      Shadowsocks.CLI/Client/Pipelines.cs
  4. +72
    -16
      Shadowsocks.CLI/Program.cs
  5. +1
    -0
      Shadowsocks.CLI/Shadowsocks.CLI.csproj
  6. +2
    -2
      Shadowsocks.Net/TCPRelay.cs
  7. +1
    -1
      Shadowsocks.Net/UDPRelay.cs

+ 10
- 0
Shadowsocks.CLI/Backend.cs View File

@@ -0,0 +1,10 @@
namespace Shadowsocks.CLI
{
public enum Backend
{
SsRust,
V2Ray,
Legacy,
Pipelines,
}
}

+ 57
- 0
Shadowsocks.CLI/Client/Legacy.cs View File

@@ -0,0 +1,57 @@
using Shadowsocks.Models;
using Shadowsocks.Net;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Shadowsocks.CLI.Client
{
public class Legacy
{
private TCPListener? _tcpListener;
private UDPListener? _udpListener;
public void Start(string listenSocks, string serverAddress, int serverPort, string method, string password, string? plugin, string? pluginOpts, string? pluginArgs)
{
var localEP = IPEndPoint.Parse(listenSocks);
var server = new Server()
{
Host = serverAddress,
Port = serverPort,
Method = method,
Password = password,
Plugin = plugin,
PluginOpts = pluginOpts,
};
if (!string.IsNullOrEmpty(plugin) && !string.IsNullOrEmpty(pluginArgs))
{
var processStartInfo = new ProcessStartInfo(plugin, pluginArgs);
server.PluginArgs = processStartInfo.ArgumentList.ToList();
}

var tcpRelay = new TCPRelay(server);
_tcpListener = new TCPListener(localEP, new List<IStreamService>()
{
tcpRelay,
});
_tcpListener.Start();

var udpRelay = new UDPRelay(server);
_udpListener = new UDPListener(localEP, new List<IDatagramService>()
{
udpRelay,
});
_udpListener.Start();
}

public void Stop()
{
_tcpListener?.Stop();
_udpListener?.Stop();
}
}
}

+ 29
- 0
Shadowsocks.CLI/Client/Pipelines.cs View File

@@ -0,0 +1,29 @@
using Shadowsocks.Protocol;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Shadowsocks.CLI.Client
{
public class Pipelines
{
private TcpPipeListener? _tcpPipeListener;
public Task Start(string listenSocks, string serverAddress, int serverPort, string method, string? password, string? key, string? plugin, string? pluginOpts, string? pluginArgs)
{
// TODO
var localEP = IPEndPoint.Parse(listenSocks);
var remoteEp = new DnsEndPoint(serverAddress, serverPort);
byte[]? mainKey = null;
if (!string.IsNullOrEmpty(key))
mainKey = Encoding.UTF8.GetBytes(key);
_tcpPipeListener = new(localEP);
return _tcpPipeListener.Start(localEP, remoteEp, method, password, mainKey);
}

public void Stop() => _tcpPipeListener?.Stop();
}
}

+ 72
- 16
Shadowsocks.CLI/Program.cs View File

@@ -1,8 +1,11 @@
using Shadowsocks.Protocol;
using Shadowsocks.Models;
using Splat;
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.Invocation;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
@@ -16,28 +19,81 @@ namespace Shadowsocks.CLI
{
var clientCommand = new Command("client", "Shadowsocks client.");
clientCommand.AddAlias("c");
clientCommand.AddOption(new Option<string?>("--listen", "The address and port to listen on for both SOCKS5 and HTTP proxy."));
clientCommand.AddOption(new Option<string?>("--listen-socks", "The address and port to listen on for SOCKS5 proxy."));
clientCommand.AddOption(new Option<string?>("--listen-http", "The address and port to listen on for HTTP proxy."));
clientCommand.AddOption(new Option<Backend>("--backend", "Shadowsocks backend to use. Available backends: shadowsocks-rust, v2ray, legacy, pipelines."));
clientCommand.AddOption(new Option<string?>("--listen", "Address and port to listen on for both SOCKS5 and HTTP proxy."));
clientCommand.AddOption(new Option<string?>("--listen-socks", "Address and port to listen on for SOCKS5 proxy."));
clientCommand.AddOption(new Option<string?>("--listen-http", "Address and port to listen on for HTTP proxy."));
clientCommand.AddOption(new Option<string>("--server-address", "Address of the remote Shadowsocks server to connect to."));
clientCommand.AddOption(new Option<int>("--server-port", "Port of the remote Shadowsocks server to connect to."));
clientCommand.AddOption(new Option<string>("--method", "Encryption method to use for the remote Shadowsocks server."));
clientCommand.AddOption(new Option<string?>("--password", "Password to use for the remote Shadowsocks server."));
clientCommand.AddOption(new Option<string?>("--key", "Encryption key (NOT password!) to use for the remote Shadowsocks server."));
clientCommand.AddOption(new Option<string>("--method", "Encryption method to use for remote Shadowsocks server."));
clientCommand.AddOption(new Option<string?>("--password", "Password to use for remote Shadowsocks server."));
clientCommand.AddOption(new Option<string?>("--key", "Encryption key (NOT password!) to use for remote Shadowsocks server."));
clientCommand.AddOption(new Option<string?>("--plugin", "Plugin binary path."));
clientCommand.AddOption(new Option<string?>("--plugin-opts", "Plugin options."));
clientCommand.AddOption(new Option<string?>("--plugin-args", "Plugin startup arguments."));
clientCommand.Handler = CommandHandler.Create(
async (string? listen, string? listenSocks, string? listenHttp, string serverAddress, int serverPort, string method, string? password, string? key, string? plugin, string? pluginOpts, string? pluginArgs) =>
async (Backend backend, string? listen, string? listenSocks, string? listenHttp, string serverAddress, int serverPort, string method, string? password, string? key, string? plugin, string? pluginOpts, string? pluginArgs, CancellationToken cancellationToken) =>
{
// TODO
var localEP = IPEndPoint.Parse(listenSocks);
var remoteEp = new DnsEndPoint(serverAddress, serverPort);
byte[]? mainKey = null;
if (!string.IsNullOrEmpty(key))
mainKey = Encoding.UTF8.GetBytes(key);
var tcpPipeListener = new TcpPipeListener(localEP);
tcpPipeListener.Start(localEP, remoteEp, method, password, mainKey).Wait();
Locator.CurrentMutable.RegisterConstant<ConsoleLogger>(new());
if (string.IsNullOrEmpty(listenSocks))
{
LogHost.Default.Error("You must specify SOCKS5 listen address and port.");
return;
}

Client.Legacy? legacyClient = null;
Client.Pipelines? pipelinesClient = null;

switch (backend)
{
case Backend.SsRust:
LogHost.Default.Error("Not implemented.");
break;
case Backend.V2Ray:
LogHost.Default.Error("Not implemented.");
break;
case Backend.Legacy:
if (!string.IsNullOrEmpty(password))
{
legacyClient = new();
legacyClient.Start(listenSocks, serverAddress, serverPort, method, password, plugin, pluginOpts, pluginArgs);
}
else
LogHost.Default.Error("The legacy backend requires password.");
break;
case Backend.Pipelines:
pipelinesClient = new();
await pipelinesClient.Start(listenSocks, serverAddress, serverPort, method, password, key, plugin, pluginOpts, pluginArgs);
break;
default:
LogHost.Default.Error("Not implemented.");
break;
}

while (!cancellationToken.IsCancellationRequested)
{
await Task.Delay(TimeSpan.FromHours(1.00), cancellationToken);
Console.WriteLine("An hour has passed.");
}

switch (backend)
{
case Backend.SsRust:
LogHost.Default.Error("Not implemented.");
break;
case Backend.V2Ray:
LogHost.Default.Error("Not implemented.");
break;
case Backend.Legacy:
legacyClient?.Stop();
break;
case Backend.Pipelines:
pipelinesClient?.Stop();
break;
default:
LogHost.Default.Error("Not implemented.");
break;
}
});

var serverCommand = new Command("server", "Shadowsocks server.");


+ 1
- 0
Shadowsocks.CLI/Shadowsocks.CLI.csproj View File

@@ -34,6 +34,7 @@

<ItemGroup>
<ProjectReference Include="..\Shadowsocks.Interop\Shadowsocks.Interop.csproj" />
<ProjectReference Include="..\Shadowsocks.Net\Shadowsocks.Net.csproj" />
<ProjectReference Include="..\Shadowsocks.Protocol\Shadowsocks.Protocol.csproj" />
</ItemGroup>



+ 2
- 2
Shadowsocks.Net/TCPRelay.cs View File

@@ -16,7 +16,7 @@ using Shadowsocks.Models;

namespace Shadowsocks.Net
{
class TCPRelay : StreamService, IEnableLogger
public class TCPRelay : StreamService, IEnableLogger
{
public event EventHandler<SSTCPConnectedEventArgs> OnConnected;
public event EventHandler<SSTransmitEventArgs> OnInbound;
@@ -182,7 +182,7 @@ namespace Shadowsocks.Net
}
}

internal class TCPHandler : IEnableLogger
public class TCPHandler : IEnableLogger
{
public event EventHandler<SSTCPConnectedEventArgs> OnConnected;
public event EventHandler<SSTransmitEventArgs> OnInbound;


+ 1
- 1
Shadowsocks.Net/UDPRelay.cs View File

@@ -12,7 +12,7 @@ using System.Threading.Tasks;

namespace Shadowsocks.Net
{
class UDPRelay : DatagramService
public class UDPRelay : DatagramService
{
Server _server;
// TODO: choose a smart number


Loading…
Cancel
Save