void PipeUdp(IClient localClient, IClient targetClient, Cipher.IShadowsocksStreamCipher cipher, CancellationToken cancellationToken, params PipeFilter[] addFilters)
        {
            DefaultPipe p = new DefaultPipe(targetClient, localClient, 1500, _logger);

            p.OnBroken += Pipe_OnBroken;

            Cipher.CipherUdpFilter      filterLocal1  = new Cipher.CipherUdpFilter(localClient, cipher, _logger);
            RemoteUdpRelayPackingFilter filterTarget1 = new RemoteUdpRelayPackingFilter(targetClient, _logger);

            p.ApplyFilter(filterLocal1).ApplyFilter(filterTarget1);
            if (addFilters.Length > 0)
            {
                p.ApplyFilter(addFilters);
            }

            lock (_pipesReadWriteLock)
            {
                this._pipes.Add(p);
            }
            p.Pipe();
        }
        void PipeTcp(IClient client, IClient relayClient, IShadowsocksStreamCipher cipher, CancellationToken cancellationToken)
        {
            DefaultPipe pipe   = new DefaultPipe(client, relayClient, Defaults.ReceiveBufferSize, _logger);
            PipeFilter  filter = new Cipher.CipherTcpFilter(relayClient, cipher, _logger);

            pipe.ApplyFilter(filter);

            pipe.OnBroken += this.Pipe_OnBroken;
            lock (_pipesReadWriteLock)
            {
                this._pipes.Add(pipe);
            }
            pipe.Pipe();
        }
        void PipeUdp(IClient client, IClient relayClient, IShadowsocksStreamCipher cipher, CancellationToken cancellationToken)
        {
            //authentication //TODO udp assoc
            DefaultPipe pipe = new DefaultPipe(relayClient, client, Defaults.ReceiveBufferSize, _logger);

            PipeFilter filter  = new Cipher.CipherUdpFilter(relayClient, cipher, _logger);
            PipeFilter filter2 = new LocalUdpRelayPackingFilter(relayClient, _logger);

            pipe.ApplyFilter(filter)
            .ApplyFilter(filter2);

            pipe.OnBroken += this.Pipe_OnBroken;

            lock (_pipesReadWriteLock)
            {
                this._pipes.Add(pipe);
            }
            pipe.Pipe();
        }
        void PipeTcp(IClient localClient, IClient targetClient, Cipher.IShadowsocksStreamCipher cipher, CancellationToken cancellationToken, params PipeFilter[] addFilters)
        {
            DefaultPipe p = new DefaultPipe(localClient, targetClient, Defaults.ReceiveBufferSize, _logger);

            p.OnBroken += Pipe_OnBroken;

            Cipher.CipherTcpFilter filter1 = new Cipher.CipherTcpFilter(localClient, cipher, _logger);

            p.ApplyFilter(filter1);

            //if (addFilters.Length > 0)
            //{
            //    foreach (var f in addFilters)
            //    {
            //        p.ApplyFilter(f);
            //    }
            //}
            lock (_pipesReadWriteLock)
            {
                this._pipes.Add(p);
            }
            p.Pipe();
        }