A previous ACK could get lost, causing the peer to resend data. If the
retransmission doesn't contain any new data, we would consider this data
to be outside our receive window, and then not resend our ACK.
// Try to match the packet to an existing connection
struct utcp_connection *c = find_connection(utcp, hdr.dst, hdr.src);
// Try to match the packet to an existing connection
struct utcp_connection *c = find_connection(utcp, hdr.dst, hdr.src);
// It is for an existing connection.
// It is for an existing connection.
- uint32_t prevrcvnxt = c->rcv.nxt;
-
// 1. Drop invalid packets.
// 1a. Drop packets that should not happen in our current state.
// 1. Drop invalid packets.
// 1a. Drop packets that should not happen in our current state.
- // 1b. Drop packets with a sequence number not in our receive window.
+ // 1b. Discard data that is not in our receive window.
if(is_reliable(c)) {
bool acceptable;
if(is_reliable(c)) {
bool acceptable;
// 3. Advance snd.una
advanced = seqdiff(hdr.ack, c->snd.una);
// 3. Advance snd.una
advanced = seqdiff(hdr.ack, c->snd.una);
- prevrcvnxt = c->rcv.nxt;
if(advanced) {
// RTT measurement
if(advanced) {
// RTT measurement
}
// Now we send something back if:
}
// Now we send something back if:
- // - we advanced rcv.nxt (ie, we got some data that needs to be ACKed)
+ // - we received data, so we have to send back an ACK
// -> sendatleastone = true
// - or we got an ack, so we should maybe send a bit more data
// -> sendatleastone = false
if(is_reliable(c) || hdr.ctl & SYN || hdr.ctl & FIN) {
// -> sendatleastone = true
// - or we got an ack, so we should maybe send a bit more data
// -> sendatleastone = false
if(is_reliable(c) || hdr.ctl & SYN || hdr.ctl & FIN) {
- ack(c, len || prevrcvnxt != c->rcv.nxt);