The uIP code that seems responsible is found in the block below. If new data (UIP_NEWDATA != 0) arrives at uIP that does not ACK the previous sent data (UIP_ACKDATA == 0), and if the server has nothing to send itself (uip_slen == 0), then uip_connr->len is erroneously set to zero and the uip_outstanding function will evaluate to false next time so that no retransmission is issued.
The retransmission counter should also be reset (uip_connr->nrtx = 0) only when the sent data has been ACK'ed.
I have added a few changes to the code that seems to work correctly but I'm still testing it.
Has anybody experienced similar problems? Comments are invited.
BR
Peter Thomsen
if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
uip_slen = 0;
UIP_APPCALL();
appsend:
if(uip_flags & UIP_ABORT) {
uip_slen = 0;
uip_connr->tcpstateflags = CLOSED;
BUF->flags = TCP_RST | TCP_ACK;
goto tcp_send_nodata;
}
if(uip_flags & UIP_CLOSE) {
uip_slen = 0;
uip_connr->len = 1;
uip_connr->tcpstateflags = FIN_WAIT_1;
uip_connr->nrtx = 0;
BUF->flags = TCP_FIN | TCP_ACK;
goto tcp_send_nodata;
}
/* If uip_slen > 0, the application has data to be sent. */
if(uip_slen > 0) {
/* If the connection has acknowledged data, the contents of
the ->len variable should be discarded. */
if((uip_flags & UIP_ACKDATA) != 0) {
uip_connr->len = 0;
}
/* If the ->len variable is non-zero the connection has
already data in transit and cannot send anymore right
now. */
if(uip_connr->len == 0) {
/* The application cannot send more than what is allowed by
the mss (the minumum of the MSS and the available
window). */
if(uip_slen > uip_connr->mss) {
uip_slen = uip_connr->mss;
}
/* Remember how much data we send out now so that we know
when everything has been acknowledged. */
uip_connr->len = uip_slen;
} else {
/* If the application already had unacknowledged data, we
make sure that the application does not send (i.e.,
retransmit) out more than it previously sent out. */
uip_slen = uip_connr->len;
}
//******* Original code *****
} else {
uip_connr->len = 0;
}
uip_connr->nrtx = 0;
//******* Original code *****
//******* Changed code *****
} else if((uip_flags & UIP_ACKDATA) != 0) {
uip_connr->len = 0;
}
if((uip_flags & UIP_ACKDATA) != 0)
uip_connr->nrtx = 0;
//******* Changed code *****
apprexmit: