internal void RecalculateRTT(TimestampedPacket ackedPacket, Int32 timestamp) { rw_rttCalc.EnterWriteLock(); //optomistic calculation that assumes the last transmit is more indiciative of //future transmits in terms of RTT this.RoundTripTime = (int)(RTT_CONST * this.RoundTripTime) + (int)((1 - RTT_CONST) * (ackedPacket.lastTransmissionTime - timestamp)); rw_rttCalc.ExitWriteLock(); }
private void TimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs) { //send anything left in the queue if (EffectiveWindow > 0 && sendQueue.Count > 0) { int toSend = sendQueue.Count - EffectiveWindow; while (EffectiveWindow > 0 && toSend > 0) { TimestampedPacket timestampedPacket; if (this.sendQueue.TryDequeue(out timestampedPacket)) { this.SendTimestampedPacket(timestampedPacket); } } } //search over the ackqueue and look for anything that is over the transmission timeout to retransmit var enumerator = acks.GetEnumerator(); while (enumerator.MoveNext()) { TimestampedPacket tsp = enumerator.Current.Value; int tick = Environment.TickCount - tsp.lastTransmissionTime; if (tick >= RetransmitInterval) { Console.WriteLine(String.Format("Resending packet Seq#:{0}", tsp.packet.Seq)); this.packetSender.SendPacket(tsp.packet); tsp.lastTransmissionTime = Environment.TickCount; tsp.retransmissionCount++; if (tsp.retransmissionCount > this.RetransmitInterval) { tsp.timedOut = true; this.PacketDropped(tsp.retransmissionCount, tsp.lastTransmissionTime); } } } /*for (uint i = 0; i < acks.Count; i++) * { * Console.WriteLine ("Resending"); * TimestampedPacket tsp = acks.GetEnumerator (). * int tick = Environment.TickCount - tsp.lastTransmissionTime; * * if ( tick >= RetransmitInterval) * { * Console.WriteLine(String.Format("Resending packet Seq#:{0}", tsp.packet.Seq)); * this.packetSender.SendPacket(tsp.packet); * tsp.lastTransmissionTime = Environment.TickCount; * tsp.retransmissionCount++; * if (tsp.retransmissionCount > this.RetransmitInterval) * { * tsp.timedOut = true; * this.PacketDropped(tsp.retransmissionCount, tsp.lastTransmissionTime); * } * } * }*/ }
/// <summary> /// Enqueues a packet to be sent out the wire /// </summary> /// <param name="packet"></param> internal virtual void SendPacket(GenericPacket packet) { TimestampedPacket tsp = new TimestampedPacket(); tsp.packet = packet; tsp.lastTransmissionTime = Int32.MinValue; tsp.retransmissionCount = 0; tsp.timedOut = false; SendTimestampedPacket(tsp); }
void SendTimestampedPacket(TimestampedPacket tsp) { if (EffectiveWindow > 0) { //todo: have the packet sender itself manage applying the timestamp (in this case the tunnelsocket which may need to be made threadsafe) tsp.lastTransmissionTime = Environment.TickCount; if (tsp.initialTransmissionTime == Int32.MinValue) { tsp.initialTransmissionTime = tsp.lastTransmissionTime; } acks.TryAdd(tsp.packet.Seq, tsp); this.packetSender.SendPacket(tsp.packet); } else { sendQueue.Enqueue(tsp); } }
protected override void OnAcked(TimestampedPacket acked) { //do nothing }
protected override void OnAcked(TimestampedPacket acked) { //do nothing the congestion window should never change size }
protected abstract void OnAcked(TimestampedPacket acked);