[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dccp] DCCP-Ack Processing for CCID 2



I'm trying to understand specifically how DCCP senders and receivers manage Acks in conjuction with CCID 2 (TCP-Like congestion control). I've read through the draft (especially Appendix A) and I think I get the details, but I'm still fuzzy on the "big picture".

Can you clarify if my summary below is about right?

(To simplify, ignore ECN and sender-Acks for now, and assume an Ack ratio of 1; I'll pick up those later.)

---- Sender Variables ----
The sender maintains at least the following data for each connection:
- cwnd        (congestion window,              default 1 packet)
- ssthresh    (slow start threshold,           default 2 packets)
- pipe        (packets in-flight measure,      default 0 packets)
- seqnum      (last sequence number,           default specified in 7.2)
- rto         (transmit timeout,               default 1s)
- dropstart   (search for drops after this,    default segnum)
- dataVector  (recent history of Data packets)


---- Receiver Variables ---- The receiver maintains at least the following data for each connection: - ackVector (recent history of packet reception)


---- Send Process ----
When sending, the sender increments and inserts a sequence number. The sender also sets dataVector[segnum] if the packet is a Data packet, else it clears it.



---- Receive Process ----
When receiving, the receiver updates its reception history and sets ackVector[segnum] (actually it does RLE encoding in a circular buffer as described in Appendix A, but it's conceptually the same). If it's a DCCP-Data packet, it also returns a DCCP-Ack packet.



---- Ack Receive Process ---- When receiving a DCCP-Ack packet, the sender: 1) Updates 'rto' if it's Ack'ing the RTT sample 2) Increments 'cwnd' according the current rule in force 3) Decrements 'pipe' 4) Detects and responds to dropped packets (see below) 5) Possibly sends up to (cwnd-pipe) Data packets


---- Dropped Packet Detection ----
But this is where I get especially fuzzy. The closest I've come up with so far is the sender maintains 'dropstart', which is the last sequence number searched for drops (ie, the starting point for this search), and 'dataVector', which is (conceptually) a bit vector stating whether a particular segnum was sent as a data or non-data packet. It would generally work as follows:


onDrop( segnum )
{
	// Ignore if it's not a data packet
	if( dataVector[segnum] )
	{
		// Update for a dropped data packet
		pipe--;
		// ... update 'cwnd' and 'ssthresh' ...
	}
}

detectAndHandleDrops( ackStart, ackEnd, ackVector )
{
	// First check those that come before our Ack vector
	if( dropstart < ackStart )
	{
		// See if three or more have been delivered at all
		if( COUNTACKS( ackStart, ackEnd, ackVector ) >= 3 )
		{
			// All unacked packets have been dropped
			for( c=dropStart; c<ackStart; ++c )
				onDrop( c );
		}
		dropstart = ackStart;
	}

	// Skip past any segnums that have already been Ack'd
	while( ackVector[dropstart] ) ++dropstart;

	// Test remaining segnums that overlap this Ack vector
	for( c=dropstart; c<(ackEnd-3); ++c )
		if( !ackVector[c] )
		{
			// See if it is followed by 3 Acks
			if( COUNTACKS( c, ackEnd, ackVector ) >= 3 )
			{
				// Assume this has been dropped
				onDrop( c );
				dropstart = c;				
			}
		}
}

I think this gets me into the ballpark. But this whole area is full of subtle, unintented consequences, so I suspect there are more holes that I'm missing (both algorithmic, as well as due to my misunderstanding the spec). What flaws do you see?

Thanks!

-david