Ejemplo n.º 1
0
        public void TryConsumeSynPacketWithOptions()
        {
            var span = _tcpSynPacketWithOptions.AsSpan();

            Assert.True(TcpHeaderWithOptions.TryConsume(span, out var header, out var data));
            Assert.True(header.SackPermitted);
            Assert.Equal(1460, header.MaximumSegmentSize);
            Assert.Equal(2, header.WindowScale);
        }
Ejemplo n.º 2
0
        public void ProcessPacket(TcpHeaderWithOptions header, ReadOnlySpan <byte> data)
        {
            // If there is backpressure just drop the packet
            if (!_flushTask.IsCompleted)
            {
                return;
            }

            _echoTimestamp = header.TimeStamp;
            switch (_state)
            {
            case TcpConnectionState.Listen:
                _maxSegmentSize        = header.MaximumSegmentSize <= 50 || header.MaximumSegmentSize > 1460 ? 1460 : header.MaximumSegmentSize;
                _sendSequenceNumber    = GetRandomSequenceStart();
                _receiveSequenceNumber = header.Header.SequenceNumber;
                // We know we checked for syn in the upper layer so we can ignore that for now
                _partialTcpHeader = Network.Header.Tcp.Create((ushort)LocalPort, (ushort)RemotePort);
                WriteSyncAckPacket();
                _state = TcpConnectionState.Syn_Rcvd;
                break;

            case TcpConnectionState.Syn_Rcvd:
                if (header.Header.SYN)
                {
                    //Console.WriteLine("Another Syn made");
                    return;
                }
                _connectionDispatcher.OnConnection(this);
                var ignore = TransmitLoop();
                _state = TcpConnectionState.Established;
                break;

            case TcpConnectionState.Established:
                if (header.Header.FIN)
                {
                    _receiveSequenceNumber++;
                    _state = TcpConnectionState.Fin_Wait_1;
                    return;
                }
                if (header.Header.RST)
                {
                    //Console.WriteLine("Got RST Should shut down!");
                    return;
                }

                // First lets update our acked squence number;
                _sendAckSequenceNumber = header.Header.AcknowledgmentNumber;

                if (_receiveSequenceNumber != header.Header.SequenceNumber)
                {
                    // We are just going to drop this and wait for a resend
                    return;
                }
                unchecked { _receiveSequenceNumber += (uint)data.Length; }
                var output = Input.GetMemory(data.Length);
                data.CopyTo(output.Span);
                Input.Advance(data.Length);
                // need to do something with the task and make sure we don't overlap the writes
                var task = Input.FlushAsync();
                if (!task.IsCompleted)
                {
                    _flushTask = task.AsTask();
                }
                PendingAck          = true;
                _totalBytesWritten += data.Length;
                break;

            case TcpConnectionState.Fin_Wait_1:
            case TcpConnectionState.Fin_Wait_2:
                break;

            default:
                throw new NotImplementedException($"Unknown tcp state?? {_state}");
            }
        }
Ejemplo n.º 3
0
 public void BadPacket()
 {
     Assert.True(TcpHeaderWithOptions.TryConsume(_tcpActualDataPacket.AsSpan(), out var header, out var data));
 }