예제 #1
0
        public void Invalid_final_fragment_bit_but_zero_position_throws()
        {
            var    stream = new byte[] { 0, 0, 128, (byte)AddressType.Ipv4, 1, 2, 3, 4, 255, 254 };
            Action act    = () => Datagram.ReadFrom(stream, this._bufferPool);

            act.Should().Throw <InvalidDataException>().And.Message.Should().ContainEquivalentOf("fragment");
        }
예제 #2
0
        public void Incorrect_reserved_bytes_throws()
        {
            var    stream = new byte[] { 0, 1, 0, (byte)AddressType.Ipv4, 1, 2, 3, 4, 255, 254 };
            Action act    = () => Datagram.ReadFrom(stream, this._bufferPool);

            act.Should().Throw <InvalidDataException>().And.Message.Should().ContainEquivalentOf("corrupt");
        }
예제 #3
0
        public void Empty_payload()
        {
            var stream = new byte[] { 0, 0, 0, (byte)AddressType.Ipv4, 1, 2, 3, 4, 255, 254 };
            var packet = Datagram.ReadFrom(stream, this._bufferPool);

            packet.Header.IsFragment.Should().BeFalse();
            packet.Payload.Count.Should().Be(0);
        }
예제 #4
0
        public void Final_fragment_of_set()
        {
            var stream = new byte[] { 0, 0, 255, (byte)AddressType.Ipv4, 1, 2, 3, 4, 255, 254, 1 };
            var packet = Datagram.ReadFrom(stream, this._bufferPool);

            packet.Header.FragmentPosition.Should().Be(127);
            packet.Header.IsFragment.Should().BeTrue();
            packet.Header.IsFinalFragment.Should().BeTrue();
        }
예제 #5
0
        async Task DoSendLoopAsync(CancellationToken cancellationToken)
        {
            using (this._log.BeginScope("SendLoop"))
            {
                var buffer = this._bufferPool.Rent(DatagramHeader.MaxUdpSize);
                try
                {
                    while (!cancellationToken.IsCancellationRequested)
                    {
                        var result = await this._boundClient
                                     .ReceiveAsync(
                            buffer,
                            0,
                            this._boundClient.BindEndPoint)
                                     .ConfigureAwait(false);

                        if (!Equals(((IPEndPoint)result.RemoteEndPoint).Address, ((IPEndPoint)this._clientStream.RemoteEndPoint).Address))
                        {
                            this._log.LogWarning(
                                "Dropped {0} bytes from unknown source: {1}",
                                result.ReceivedBytes,
                                result.RemoteEndPoint);
                        }

                        this._log.LogDebug("Received {0} bytes from {1}", result.ReceivedBytes, result.RemoteEndPoint);

                        var datagram = Datagram.ReadFrom(
                            new ArraySegment <byte>(buffer, 0, result.ReceivedBytes),
                            this._bufferPool);

                        var fragments = this._reassembler.GetCompletedSetOrAdd(
                            datagram.Payload,
                            datagram.Header.FragmentPosition,
                            datagram.Header.IsFinalFragment);

                        if (fragments.Count == 0)
                        {
                            this._log.LogDebug("Buffering datagram segment #{0}", datagram.Header.FragmentPosition);
                            continue;
                        }

                        using (fragments)
                        {
                            int totalCount = 0;
                            for (int i = 0; i < fragments.Count; i++)
                            {
                                var fragment = fragments[i];
                                Buffer.BlockCopy(
                                    fragment.Array,
                                    fragment.Offset,
                                    buffer,
                                    totalCount,
                                    fragment.Count);
                                totalCount += fragment.Count;
                            }

                            if (!await this._interceptor
                                .TryInterceptOutgoingAsync(
                                    new ArraySegment <byte>(buffer, 0, totalCount),
                                    datagram.Header.RemoteEndPoint,
                                    this._relayClient)
                                .ConfigureAwait(false))
                            {
                                this._log.LogDebug(
                                    "Sending {0} bytes to {1}",
                                    totalCount,
                                    datagram.Header.RemoteEndPoint);
                                await this._relayClient
                                .SendAsync(
                                    buffer,
                                    0,
                                    totalCount,
                                    datagram.Header.RemoteEndPoint)
                                .ConfigureAwait(false);
                            }

                            this._clientEndPointTask.TrySetResult(result.RemoteEndPoint);
                        }
                    }
                }
                finally
                {
                    this._bufferPool.Return(buffer);
                }
            }
        }