Skip to content

Commit

Permalink
🐚 Shadowsocks.CLI and Shadowsocks.Protocol
Browse files Browse the repository at this point in the history
- CLI: client, server, utilities (unfinished)
- Merge v5/pipelines by @studentmain into main (unfinished)
  • Loading branch information
database64128 committed Feb 25, 2021
1 parent 73bc7ea commit 4bdb134
Show file tree
Hide file tree
Showing 37 changed files with 1,957 additions and 19 deletions.
97 changes: 86 additions & 11 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,122 @@ on:
- 'rm'
paths-ignore:
- 'README.md'
- 'LICENSE'
- 'LICENSE.txt'
pull_request:
branches-ignore:
- 'v4'
- 'rm'
paths-ignore:
- 'README.md'
- 'LICENSE'
- 'LICENSE.txt'

jobs:
build:
name: Build
runs-on: windows-latest
strategy:
matrix:
os: [ubuntu-20.04, windows-latest]
fail-fast: false
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash

steps:
- uses: actions/checkout@v2
- name: Restore dependencies
if: matrix.os == 'windows-latest'
run: dotnet restore
- name: Build
if: matrix.os == 'windows-latest'
run: dotnet build --no-restore
- name: Test
if: matrix.os == 'windows-latest'
run: dotnet test --no-build --verbosity normal
# Publish
- name: Publish framework-dependent
# Publish CLI
- name: Define MSBuild properties
run: echo "MSBUILD_PROPS=-p:PublishSingleFile=true -p:PublishTrimmed=true -p:TrimMode=link -p:DebuggerSupport=false -p:EnableUnsafeBinaryFormatterSerialization=false -p:EnableUnsafeUTF7Encoding=false -p:InvariantGlobalization=true" >> $GITHUB_ENV
- name: Publish CLI framework-dependent
run: |
dotnet publish Shadowsocks.CLI -c Release
- name: Publish CLI self-contained for Linux ARM64
if: matrix.os == 'ubuntu-20.04'
run: |
dotnet publish Shadowsocks.CLI -c Release $MSBUILD_PROPS -r linux-arm64 --self-contained
- name: Publish CLI self-contained for Linux x64
if: matrix.os == 'ubuntu-20.04'
run: |
dotnet publish Shadowsocks.CLI -c Release $MSBUILD_PROPS -r linux-x64 --self-contained
- name: Publish CLI self-contained for Windows ARM64
if: matrix.os == 'windows-latest'
run: |
dotnet publish Shadowsocks.CLI -c Release $MSBUILD_PROPS -r win-arm64 --self-contained
- name: Publish CLI self-contained for Windows x64
if: matrix.os == 'windows-latest'
run: |
dotnet publish Shadowsocks.CLI -c Release $MSBUILD_PROPS -r win-x64 --self-contained
# Publish WPF
- name: Publish WPF framework-dependent
if: matrix.os == 'windows-latest'
run: dotnet publish Shadowsocks.WPF -c Release --no-restore
# - name: Publish self-contained for Windows ARM64
# - name: Publish WPF self-contained for Windows ARM64
# if: matrix.os == 'windows-latest'
# run: dotnet publish Shadowsocks.WPF -c Release -r win-arm64 --self-contained
- name: Publish self-contained for Windows x64
- name: Publish WPF self-contained for Windows x64
if: matrix.os == 'windows-latest'
run: dotnet publish Shadowsocks.WPF -c Release -r win-x64 --self-contained
# Upload
# - name: Upload artifacts for Windows ARM64
# Upload CLI
- name: Upload CLI artifacts for Linux ARM64
if: matrix.os == 'ubuntu-20.04'
uses: actions/upload-artifact@v2
with:
name: shadowsocks-cli-${{ github.sha }}-linux-arm64
path: Shadowsocks.CLI/bin/Release/net5.0/linux-arm64/publish/
- name: Upload CLI artifacts for Linux x64
if: matrix.os == 'ubuntu-20.04'
uses: actions/upload-artifact@v2
with:
name: shadowsocks-cli-${{ github.sha }}-linux-x64
path: Shadowsocks.CLI/bin/Release/net5.0/linux-x64/publish/
- name: Upload CLI artifacts for Linux framework-dependent
if: matrix.os == 'ubuntu-20.04'
uses: actions/upload-artifact@v2
with:
name: shadowsocks-cli-${{ github.sha }}-linux
path: Shadowsocks.CLI/bin/Release/net5.0/publish/
- name: Upload CLI artifacts for Windows ARM64
if: matrix.os == 'windows-latest'
uses: actions/upload-artifact@v2
with:
name: shadowsocks-cli-${{ github.sha }}-windows-arm64
path: Shadowsocks.CLI/bin/Release/net5.0/win-arm64/publish/
- name: Upload CLI artifacts for Windows x64
if: matrix.os == 'windows-latest'
uses: actions/upload-artifact@v2
with:
name: shadowsocks-cli-${{ github.sha }}-windows-x64
path: Shadowsocks.CLI/bin/Release/net5.0/win-x64/publish/
- name: Upload CLI artifacts for Windows framework-dependent
if: matrix.os == 'windows-latest'
uses: actions/upload-artifact@v2
with:
name: shadowsocks-cli-${{ github.sha }}-windows
path: Shadowsocks.CLI/bin/Release/net5.0/publish/
# Upload WPF
# - name: Upload WPF artifacts for Windows ARM64
# if: matrix.os == 'windows-latest'
# uses: actions/upload-artifact@v2
# with:
# name: shadowsocks-wpf-${{ github.sha }}-windows-arm64
# path: Shadowsocks.WPF/bin/Release/net5.0-windows10.0.19041.0/win-arm64/publish/
- name: Upload artifacts for Windows x64
- name: Upload WPF artifacts for Windows x64
if: matrix.os == 'windows-latest'
uses: actions/upload-artifact@v2
with:
name: shadowsocks-wpf-${{ github.sha }}-windows-x64
path: Shadowsocks.WPF/bin/Release/net5.0-windows10.0.19041.0/win-x64/publish/
- name: Upload artifacts for Windows framework-dependent
- name: Upload WPF artifacts for Windows framework-dependent
if: matrix.os == 'windows-latest'
uses: actions/upload-artifact@v2
with:
name: shadowsocks-wpf-${{ github.sha }}-windows
Expand Down
91 changes: 85 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,81 @@ on:
jobs:
publish_upload:
name: Publish and upload
runs-on: windows-latest
strategy:
matrix:
os: [ubuntu-20.04, windows-latest]
fail-fast: false
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash

steps:
- uses: actions/checkout@v2
- name: Restore dependencies
if: matrix.os == 'windows-latest'
run: dotnet restore
- name: Build
if: matrix.os == 'windows-latest'
run: dotnet build --no-restore
- name: Test
if: matrix.os == 'windows-latest'
run: dotnet test --no-build --verbosity normal
# Publish
- name: Publish framework-dependent
# Publish CLI
- name: Define MSBuild properties
run: echo "MSBUILD_PROPS=-p:PublishSingleFile=true -p:PublishTrimmed=true -p:TrimMode=link -p:DebuggerSupport=false -p:EnableUnsafeBinaryFormatterSerialization=false -p:EnableUnsafeUTF7Encoding=false -p:InvariantGlobalization=true" >> $GITHUB_ENV
- name: Publish CLI framework-dependent
run: |
dotnet publish Shadowsocks.CLI -c Release
- name: Publish CLI self-contained for Linux ARM64
if: matrix.os == 'ubuntu-20.04'
run: |
dotnet publish Shadowsocks.CLI -c Release $MSBUILD_PROPS -r linux-arm64 --self-contained
- name: Publish CLI self-contained for Linux x64
if: matrix.os == 'ubuntu-20.04'
run: |
dotnet publish Shadowsocks.CLI -c Release $MSBUILD_PROPS -r linux-x64 --self-contained
- name: Publish CLI self-contained for Windows ARM64
if: matrix.os == 'windows-latest'
run: |
dotnet publish Shadowsocks.CLI -c Release $MSBUILD_PROPS -r win-arm64 --self-contained
- name: Publish CLI self-contained for Windows x64
if: matrix.os == 'windows-latest'
run: |
dotnet publish Shadowsocks.CLI -c Release $MSBUILD_PROPS -r win-x64 --self-contained
# Publish WPF
- name: Publish WPF framework-dependent
if: matrix.os == 'windows-latest'
run: dotnet publish Shadowsocks.WPF -c Release --no-restore
# - name: Publish self-contained for Windows ARM64
# - name: Publish WPF self-contained for Windows ARM64
# if: matrix.os == 'windows-latest'
# run: dotnet publish Shadowsocks.WPF -c Release -r win-arm64 --self-contained
- name: Publish self-contained for Windows x64
- name: Publish WPF self-contained for Windows x64
if: matrix.os == 'windows-latest'
run: dotnet publish Shadowsocks.WPF -c Release -r win-x64 --self-contained
# Get version
- name: Get version
id: get_version
shell: bash
run: echo ::set-output name=VERSION::$(echo $GITHUB_REF | cut -d / -f 3)
# Package
- name: Package for Linux
if: matrix.os == 'ubuntu-20.04'
env:
ZSTD_CLEVEL: 19
ZSTD_NBTHREADS: 2
run: |
# Shadowsocks.CLI
cd Shadowsocks.CLI/bin/Release/net5.0/publish
tar -acf ../shadowsocks-cli-${{ steps.get_version.outputs.VERSION }}-linux.tar.zst .
cd ../linux-arm64/publish
tar -acf ../../shadowsocks-cli-${{ steps.get_version.outputs.VERSION }}-linux-arm64.tar.zst .
cd ../../linux-x64/publish
tar -acf ../../shadowsocks-cli-${{ steps.get_version.outputs.VERSION }}-linux-x64.tar.zst .
- name: Package for Windows
if: matrix.os == 'windows-latest'
run: |
# WPF
cd Shadowsocks.WPF/bin/Release/net5.0-windows10.0.19041.0/publish
7z a -tzip -mx=9 -mfb=128 ../shadowsocks-wpf-${{ steps.get_version.outputs.VERSION }}-windows.zip .
7z a -t7z -m0=lzma2 -mx=9 -mfb=64 -md=64m -ms=on ../shadowsocks-wpf-${{ steps.get_version.outputs.VERSION }}-windows.7z .
Expand All @@ -42,8 +92,37 @@ jobs:
cd ../../win-x64/publish
7z a -tzip -mx=9 -mfb=128 ../../shadowsocks-wpf-${{ steps.get_version.outputs.VERSION }}-windows-x64.zip .
7z a -t7z -m0=lzma2 -mx=9 -mfb=64 -md=64m -ms=on ../../shadowsocks-wpf-${{ steps.get_version.outputs.VERSION }}-windows-x64.7z .
# CLI
cd ../../../../../Shadowsocks.CLI/bin/Release/net5.0/publish
7z a -tzip -mx=9 -mfb=128 ../shadowsocks-cli-${{ steps.get_version.outputs.VERSION }}-windows.zip .
7z a -t7z -m0=lzma2 -mx=9 -mfb=64 -md=64m -ms=on ../shadowsocks-cli-${{ steps.get_version.outputs.VERSION }}-windows.7z .
cd ../win-arm64/publish
7z a -tzip -mx=9 -mfb=128 ../../shadowsocks-cli-${{ steps.get_version.outputs.VERSION }}-windows-arm64.zip .
7z a -t7z -m0=lzma2 -mx=9 -mfb=64 -md=64m -ms=on ../../shadowsocks-cli-${{ steps.get_version.outputs.VERSION }}-windows-arm64.7z .
cd ../../win-x64/publish
7z a -tzip -mx=9 -mfb=128 ../../shadowsocks-cli-${{ steps.get_version.outputs.VERSION }}-windows-x64.zip .
7z a -t7z -m0=lzma2 -mx=9 -mfb=64 -md=64m -ms=on ../../shadowsocks-cli-${{ steps.get_version.outputs.VERSION }}-windows-x64.7z .
# Release
- name: Upload release assets for Windows
- name: Upload release assets for Linux
uses: svenstaro/upload-release-action@v2
if: matrix.os == 'ubuntu-20.04'
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: Shadowsocks.CLI/bin/Release/net5.0/*.tar.zst
tag: ${{ github.ref }}
file_glob: true
prerelease: true
- name: Upload CLI release assets for Windows
if: matrix.os == 'windows-latest'
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: Shadowsocks.CLI/bin/Release/net5.0/shadowsocks-wpf-*
tag: ${{ github.ref }}
file_glob: true
prerelease: true
- name: Upload WPF release assets for Windows
if: matrix.os == 'windows-latest'
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
Expand Down
65 changes: 65 additions & 0 deletions Shadowsocks.CLI/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Shadowsocks.Protocol;
using System;
using System.CommandLine;
using System.CommandLine.Invocation;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Shadowsocks.CLI
{
internal class Program
{
private static Task<int> Main(string[] args)
{
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<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?>("--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) =>
{
// 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();
});

var serverCommand = new Command("server", "Shadowsocks server.");
serverCommand.AddAlias("s");
serverCommand.Handler = CommandHandler.Create(
() =>
{
Console.WriteLine("Not implemented.");
});

var utilitiesCommand = new Command("utilities", "Shadowsocks-related utilities.");
utilitiesCommand.AddAlias("u");
utilitiesCommand.AddAlias("util");
utilitiesCommand.AddAlias("utils");

var rootCommand = new RootCommand("CLI for Shadowsocks server and client implementation in C#.")
{
clientCommand,
serverCommand,
utilitiesCommand,
};

Console.OutputEncoding = Encoding.UTF8;
return rootCommand.InvokeAsync(args);
}
}
}
40 changes: 40 additions & 0 deletions Shadowsocks.CLI/Shadowsocks.CLI.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
<AssemblyName>sscli</AssemblyName>
<PackageId>Shadowsocks.CLI</PackageId>
<Authors>Clowwindy &amp; The Community</Authors>
<Product>Shadowsocks CLI</Product>
<Description>CLI for Shadowsocks server and client implementation in C#.</Description>
<Copyright>© 2021 Clowwindy &amp; The Community</Copyright>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<PackageProjectUrl>https://github.com/shadowsocks/shadowsocks-windows</PackageProjectUrl>
<RepositoryUrl>https://github.com/shadowsocks/shadowsocks-windows</RepositoryUrl>
<RepositoryType>Public</RepositoryType>
<PackageIcon>ssw128.png</PackageIcon>
</PropertyGroup>

<ItemGroup>
<None Include="..\LICENSE.txt">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
<None Include="..\Shadowsocks.WPF\Resources\ssw128.png">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20574.7" />
</ItemGroup>

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

</Project>
12 changes: 12 additions & 0 deletions Shadowsocks.Protocol/Direct/PortForwardService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.IO.Pipelines;
using System.Threading.Tasks;

namespace Shadowsocks.Protocol.Direct
{
public class PortForwardService : IStreamService
{
public async Task<IDuplexPipe> Handle(IDuplexPipe pipe) => await Task.FromResult<IDuplexPipe>(null);

public Task<bool> IsMyClient(IDuplexPipe pipe) => Task.FromResult(true);
}
}
19 changes: 19 additions & 0 deletions Shadowsocks.Protocol/DuplexPipe.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.IO.Pipelines;
using System.Threading.Tasks;

namespace Shadowsocks.Protocol
{
class DuplexPipe : IDuplexPipe
{
public PipeReader Input { get; set; }
public PipeWriter Output { get; set; }

public static Task CopyDuplexPipe(IDuplexPipe p1, IDuplexPipe p2)
{
var t1 = p1.Input.CopyToAsync(p2.Output);
var t2 = p2.Input.CopyToAsync(p1.Output);

return Task.WhenAll(t1, t2);
}
}
}
Loading

0 comments on commit 4bdb134

Please sign in to comment.