Ejemplo n.º 1
0
        internal virtual void Post(TcpFlags flags, uint ackno, uint seqno, uint length = 0, int retransmission = 0, bool timeout = false)
        {
            SegmentsContext segments = null;

            lock (this)
            {
                lock (this.SegmentsContexts)
                {
                    segments = new SegmentsContext()
                    {
                        AcknowledgeNo  = ackno,
                        SequenceNo     = seqno,
                        Flags          = flags,
                        Length         = length,
                        Stopwatch      = new Stopwatch(),
                        Retransmission = retransmission,
                        Pcb            = this,
                        Timeout        = timeout,
                    };
                    if (retransmission > 0)
                    {
                        long nackNo = segments.SequenceNo + segments.Length;
                        if (this.SegmentsContexts.TryAdd(nackNo, segments))
                        {
                            segments.Stopwatch.Start();
                        }
                    }
                }
            }
            TcpFrame frame = segments.CreateFrame(this);

            this.Locator.Tcp.Output(frame);
        }
Ejemplo n.º 2
0
        public override bool Send(BufferSegment payload)
        {
            if (payload == null || payload.Length <= 0)
            {
                return(false);
            }

            bool sendto(BufferSegment buffer)
            {
                if (buffer == null || buffer.Length <= 0)
                {
                    return(false);
                }

                SegmentsContext segments = null;

                lock (this)
                {
                    lock (this.SegmentsContexts)
                    {
                        segments = new SegmentsContext()
                        {
                            AcknowledgeNo  = this.SequenceNo,
                            SequenceNo     = this.AcknowledgeNo,
                            Flags          = TcpFlags.TCP_PSH | TcpFlags.TCP_ACK,
                            Length         = (uint)buffer.Length,
                            Stopwatch      = new Stopwatch(),
                            Pcb            = this,
                            Retransmission = 5,
                            Payload        = payload,
                        };
                        var ackNo = segments.SequenceNo + segments.Length;
                        if (this.SegmentsContexts.TryAdd(ackNo, segments))
                        {
                            segments.Stopwatch.Start();
                            this.AcknowledgeNo += segments.Length;
                        }
                    }
                }

                TcpFrame frame = segments.CreateFrame(this);

                this.Locator.Tcp.Output(frame);

                return(true);
            }

            foreach (BufferSegment buffer in Slices(payload))
            {
                if (!sendto(buffer))
                {
                    return(false);
                }
            }
            return(true);
        }
Ejemplo n.º 3
0
        internal virtual bool Ack(long ackno)
        {
            bool            ack      = false;
            SegmentsContext segments = null;

            lock (this.SegmentsContexts)
            {
                ack = this.SegmentsContexts.Remove(ackno, out segments);
                if (ack)
                {
                    segments.Stopwatch.Stop();
                    UpdateAckTime(segments.Stopwatch.ElapsedMilliseconds);

                    if (this.State == TcpState.SYN_RCVD)
                    {
                        this.State = TcpState.ESTABLISHED;
                        this.OnOpen(EventArgs.Empty);
                    }
                }

                if (this.SegmentsContexts.Count > 0 && ackno <= this.AcknowledgeNo)
                {
                    var rapids = new List <long>();
                    foreach (var key in this.SegmentsContexts.Keys)
                    {
                        if (key > ackno)
                        {
                            break;
                        }

                        rapids.Add(key);
                    }
                    foreach (var key in rapids)
                    {
                        this.SegmentsContexts.Remove(key, out segments);
                    }
                }
            }
            return(ack);
        }
Ejemplo n.º 4
0
        private void WorkThread(object state)
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            while (!this._disposed)
            {
                if (stopwatch.ElapsedTicks < TcpPcb.MIN_RTO)
                {
                    Thread.Sleep(1);
                    continue;
                }
                else
                {
                    stopwatch.Restart();
                }

                foreach (var pair in _pcbTable)
                {
                    TcpPcb pcb = pair.Value;
                    if (pcb == null)
                    {
                        continue;
                    }

                    SortedDictionary <long, SegmentsContext> segments = pcb.SegmentsContexts;
                    if (segments == null)
                    {
                        continue;
                    }

                    lock (segments)
                    {
                        var remove_segments_keys = new List <long>();
                        foreach (var segments_pair in segments)
                        {
                            SegmentsContext segments_context = segments_pair.Value;
                            if (segments_context == null)
                            {
                                continue;
                            }

                            double rto_radix = Math.Pow(1.5, Math.Min(segments_context.Retransmission, (1 + segments_context.Counter)));
                            if (segments_context.Stopwatch.ElapsedMilliseconds >= (Math.Max(pcb.RTO, TcpPcb.MIN_RTO)
                                                                                   * rto_radix))
                            {
                                if (segments_context.Counter++ < segments_context.Retransmission)
                                {
                                    segments_context.Stopwatch.Restart();
                                    this.Output(segments_context.CreateFrame(pcb));
                                }
                                else
                                {
                                    remove_segments_keys.Add(segments_pair.Key);
                                }
                            }
                        }

                        foreach (var segments_key in remove_segments_keys)
                        {
                            pcb.SegmentsContexts.Remove(segments_key, out SegmentsContext segments_x);
                        }
                    }
                }
            }
        }