Пример #1
0
        private async Task Socks5DataReceived(object Sender, P2P.SOCKS5.DataReceivedEventArgs e)
        {
            Socks5Receiver Rx = (Socks5Receiver)e.State;

            if (HttpxChunks.chunkedStreams.TryGetValue(Rx.Key, out ChunkRecord Rec))
            {
#if LOG_SOCKS5_EVENTS
                this.client.Information(e.Count.ToString() + " bytes received over SOCKS5 stream " + Rx.Key + ".");
#endif
                byte[] Buffer = e.Buffer;
                int    Offset = e.Offset;
                int    Count  = e.Count;
                int    d;

                while (Count > 0)
                {
                    switch (Rx.State)
                    {
                    case 0:
                        Rx.BlockSize = Buffer[Offset++];
                        Count--;
                        Rx.State++;
                        break;

                    case 1:
                        Rx.BlockSize <<= 8;
                        Rx.BlockSize  |= Buffer[Offset++];
                        Count--;

                        if (Rx.BlockSize == 0)
                        {
                            HttpxChunks.chunkedStreams.Remove(Rx.Key);
                            await Rec.ChunkReceived(Rx.Nr++, true, new byte[0]);

                            e.Stream.Dispose();
                            return;
                        }

                        Rx.BlockPos = 0;

                        if (Rx.Block is null || Rx.Block.Length != Rx.BlockSize)
                        {
                            Rx.Block = new byte[Rx.BlockSize];
                        }

                        Rx.State++;
                        break;

                    case 2:
                        d = Math.Min(Count, Rx.BlockSize - Rx.BlockPos);

                        Array.Copy(Buffer, Offset, Rx.Block, Rx.BlockPos, d);
                        Offset      += d;
                        Rx.BlockPos += d;
                        Count       -= d;

                        if (Rx.BlockPos >= Rx.BlockSize)
                        {
                            if (Rx.E2e)
                            {
                                string Id = Rec.NextId().ToString();
                                Rx.Block = this.e2e.Decrypt(Rx.EndpointReference, Id, Rx.StreamId, Rx.From, Rx.To, Rx.Block, Rx.SymmetricCipher);
                                if (Rx.Block is null)
                                {
                                    string Message = "Decryption of chunk " + Rx.Nr.ToString() + " failed.";
#if LOG_SOCKS5_EVENTS
                                    this.client.Error(Message);
#endif
                                    await Rec.Fail(Message);

                                    e.Stream.Dispose();
                                    return;
                                }
                            }

#if LOG_SOCKS5_EVENTS
                            this.client.Information("Chunk " + Rx.Nr.ToString() + " received and forwarded.");
#endif
                            await Rec.ChunkReceived(Rx.Nr++, false, Rx.Block);

                            Rx.State = 0;
                        }
                        break;
                    }
                }
            }
            else
            {
#if LOG_SOCKS5_EVENTS
                this.client.Warning(e.Count.ToString() + " bytes received over SOCKS5 stream " + Rx.Key + " and discarded.");
#endif
                e.Stream.Dispose();
            }
        }