Esempio n. 1
0
    public virtual void Start(ShadowsocksServerInfo info)
    {
        Verify.NotDisposed(this);
        Verify.Operation(Process is null || Process.HasExited, @"Process has started!");
        Requires.NotNullAllowStructs(info.Plugin, nameof(info.Plugin));

        LocalEndPoint = GetFreeLocalEndpoint();

        Process = new Process
        {
            StartInfo = new ProcessStartInfo(info.Plugin)
            {
                UseShellExecute = false,
                CreateNoWindow  = true,
                Environment     =
                {
                    [EnvRemoteHost] = info.Address,
                    [EnvRemotePort] = info.Port.ToString(),
                    [EnvLocalHost]  = LocalEndPoint.Address.ToString(),
                    [EnvLocalPort]  = LocalEndPoint.Port.ToString(),
                    [EnvPluginOpts] = info.PluginOpts
                }
            }
        };

        Process.Start();
    public ValueTask <IUdpClient> GetServerUdpAsync(string target, ushort targetPort)
    {
        ShadowsocksServerInfo info = GetInfo();

        IUdpClient client = new ShadowsocksUdpClient(info);

        return(ValueTask.FromResult(client));
    }
    public async ValueTask <IPipeClient> GetServerAsync(string target, ushort targetPort)
    {
        if (target.Contains(@"baidu", StringComparison.OrdinalIgnoreCase))
        {
            return(ConnectionRefusedTcpClient.Default);
        }

        if (target.Contains(@"ip.sb", StringComparison.OrdinalIgnoreCase) || IPAddress.TryParse(target, out _))
        {
            return(await DirectConnectAsync(TimeSpan.FromSeconds(3)));
        }

        ShadowsocksServerInfo info = GetInfo();

        if (string.IsNullOrEmpty(info.Plugin))
        {
            return(await ConnectAsync(info, TimeSpan.FromSeconds(3)));
        }

        IPEndPoint            pluginIpEndPoint = PluginServices.GetPluginService(info);
        ShadowsocksServerInfo newInfo          = info with {
            Address = pluginIpEndPoint.Address.ToString(), Port = (ushort)pluginIpEndPoint.Port
        };

        try
        {
            return(await ConnectAsync(newInfo, TimeSpan.FromSeconds(1)));
        }
        catch
        {
            PluginServices.RemoveService(info);
            pluginIpEndPoint = PluginServices.GetPluginService(info);
            newInfo          = info with {
                Address = pluginIpEndPoint.Address.ToString(), Port = (ushort)pluginIpEndPoint.Port
            };
            return(await ConnectAsync(newInfo, TimeSpan.FromSeconds(1)));
        }

        async ValueTask <IPipeClient> ConnectAsync(ShadowsocksServerInfo serverInfo, TimeSpan timeout)
        {
            IPipeClient client = new ShadowsocksTcpClient(serverInfo, target, targetPort);

            using CancellationTokenSource cts = new(timeout);
            await client.ConnectAsync(cts.Token);

            return(client);
        }

        async ValueTask <IPipeClient> DirectConnectAsync(TimeSpan timeout)
        {
            IPipeClient client = new DirectConnectTcpClient(target, targetPort);

            using CancellationTokenSource cts = new(timeout);
            await client.ConnectAsync(cts.Token);

            return(client);
        }
    }
Esempio n. 4
0
    public ShadowsocksUdpClient(ShadowsocksServerInfo serverInfo)
    {
        Requires.NotNull(serverInfo, nameof(serverInfo));
        Requires.NotNullAllowStructs(serverInfo.Method, nameof(serverInfo));
        Requires.NotNullAllowStructs(serverInfo.Password, nameof(serverInfo));
        Requires.NotNullAllowStructs(serverInfo.Address, nameof(serverInfo));

        _serverInfo = serverInfo;

        _client = new Socket(SocketType.Dgram, ProtocolType.Udp);
        _client.Connect(serverInfo.Address, serverInfo.Port);
    }
    public static IDuplexPipe AsShadowsocksPipe(
        this IDuplexPipe pipe,
        ShadowsocksServerInfo serverInfo,
        string targetAddress, ushort targetPort,
        PipeOptions?readerOptions = null,
        PipeOptions?writerOptions = null)
    {
        PipeReader reader = pipe.Input.AsShadowsocksPipeReader(serverInfo, readerOptions);
        PipeWriter writer = pipe.Output.AsShadowsocksPipeWriter(serverInfo, writerOptions);

        writer.WriteShadowsocksHeader(targetAddress, targetPort);

        return(DefaultDuplexPipe.Create(reader, writer));
    }
    public ShadowsocksPipeReader(
        PipeReader reader,
        ShadowsocksServerInfo serverInfo,
        PipeOptions?pipeOptions = null)
    {
        Requires.NotNull(reader, nameof(reader));
        Requires.NotNull(serverInfo, nameof(serverInfo));
        Requires.NotNullAllowStructs(serverInfo.Method, nameof(serverInfo));
        Requires.NotNullAllowStructs(serverInfo.Password, nameof(serverInfo));

        IShadowsocksCrypto decryptor = ShadowsocksCrypto.Create(serverInfo.Method, serverInfo.Password);

        InternalReader           = reader;
        _pipe                    = new Pipe(pipeOptions ?? PipeOptions.Default);
        _cancellationTokenSource = new CancellationTokenSource();

        WrapAsync(decryptor, _cancellationTokenSource.Token).Forget();
    }
Esempio n. 7
0
    public void Sip002UriSchemeTest(string uri,
                                    string?remark,
                                    string?address, ushort port,
                                    string?password, string?method,
                                    string?plugin, string?pluginOpts)
    {
        ShadowsocksServerInfo serverInfo = new()
        {
            Remarks    = remark,
            Address    = address,
            Port       = port,
            Password   = password,
            Method     = method,
            Plugin     = plugin,
            PluginOpts = pluginOpts
        };

        Assert.AreEqual(uri, serverInfo.ToSip002UriSchemeString());
        Assert.IsTrue(ShadowsocksServerInfo.TryParse(uri, out ShadowsocksServerInfo? newInfo));
        newInfo.Id = serverInfo.Id;
        Assert.AreEqual(serverInfo, newInfo);
    }
}
 public ShadowsocksTcpClient(ShadowsocksServerInfo serverInfo, string targetAddress, ushort targetPort)
 {
     _serverInfo    = serverInfo;
     _targetAddress = targetAddress;
     _targetPort    = targetPort;
 }