UltimaSerial Packet Retransmission in Dynamic C's TCP library
Data logger


Windaq add-ons
Windaq Add-ons




Ultimaserial XChart




Ultimaserial Classroom


This work note is from a project involving rabbit semiconductor's RCM3200 and Dynamic C

At a glance, Dynamic C follows all the rules in TCP retransmit logic (please refer to http://www.soi.wide.ad.jp/class/20020032/slides/11/1.html for more detail) and provides flexible controls over the TCP performance (search for the following key section in TCP.LIB for quick reference):

// Van jacobson RTT estimation parameters.  These are used to limit
// the values, and hence limit the overall timeout interval.
#define MAXVJSA         80000L /* 10 s (units of 1/8ms) */
#define MAXVJSD         80000L /* 10 s (units of 1/8ms) */

         // This is used for several purposes.  It is the minimum time granularity of
         // the retransmit process.  No timeout is set less than this value (ms).
         #define RETRAN_STRAT_TIME  10

#ifndef TCP_MAXRTO
         #define TCP_MAXRTO (MAXVJSA+(MAXVJSD<<2)>>3)

   #define TCP_TWTIMEOUT 2000L

#ifndef TCP_MINRTO
         #define TCP_MINRTO 10

s->rto <<= 1;   //This is rule #2 of Karn's algorithm    

if (chk_timeout(s->rtt_time)){ 

Unfortunately, it has Achilles' Heel: The timeout is reset in tcp_send on next transmission!

_tcp_nodebug void _tcp_send( tcp_Socket *s ) 
s->rtt_time = _SET_TIMEOUT(s->rto);

If data is sent out at low frequency burst only, i.e, a new packet is usually not send out until the receiving of ACK from previous packet,  or the TCP server waits for the response from the client before the next transmit, retransmit timeout logic works.

Yet, in today's high-speed TCP application, not every packet is ACKed, nor the server wait for the ACK from previous packets before sending out more.

Thus, if rabbit is used as a data pump for continuous operation, it will not retransmit the data until the transmit buffer is wrapped around!

To tackle the root of this problem, retransmit timeout will have to be managed in a FIFO, and the checking, chk_timeout(s->rtt_time), will have to deal to the oldest timeout in the FIFO.

Also, to match the resolution of timeout, tcp_tick should be called as fast as possible

Or, one can try a lazy patch without having to rewrite the TCP.LIB:

Add a second timeout variable to where the ACK is captured. If this timeout is say two times the number in s->rto and there are pending packets to be ACKed, activate the retransmit

 Last update: 02/24/12

Copyright: 2000-2005  www.UltimaSerial.com