if(c->state == SYN_SENT)
acceptable = true;
-
- // TODO: handle packets overlapping c->rcv.nxt.
-#if 1
- // Only use this when accepting out-of-order packets.
else if(len == 0)
acceptable = seqdiff(hdr.seq, c->rcv.nxt) >= 0;
- else
+ else {
+ int32_t rcv_offset = seqdiff(hdr.seq, c->rcv.nxt);
+
+ // cut already accepted front overlapping
+ if(rcv_offset < 0) {
+ acceptable = rcv_offset + len >= 0;
+ if(acceptable) {
+ data -= rcv_offset;
+ len += rcv_offset;
+ }
+ }
+
acceptable = seqdiff(hdr.seq, c->rcv.nxt) >= 0 && seqdiff(hdr.seq, c->rcv.nxt) + len <= c->rcvbuf.maxsize;
-#else
- if(c->state != SYN_SENT)
- acceptable = hdr.seq == c->rcv.nxt;
-#endif
+ }
if(!acceptable) {
debug("Packet not acceptable, %u <= %u + %zu < %u\n", c->rcv.nxt, hdr.seq, len, c->rcv.nxt + c->rcvbuf.maxsize);
// ackno should not roll back, and it should also not be bigger than what we ever could have sent
// (= snd.una + c->sndbuf.used).
- if(hdr.ctl & ACK &&
- ((seqdiff(hdr.ack, c->snd.una + c->sndbuf.used) > 0 &&
- seqdiff(hdr.ack, c->snd.nxt) > 0) // TODO: simplify this if
- || seqdiff(hdr.ack, c->snd.una) < 0)) {
+ if(hdr.ctl & ACK && (seqdiff(hdr.ack, c->snd.last) > 0 || seqdiff(hdr.ack, c->snd.una) < 0)) {
debug("Packet ack seqno out of range, %u <= %u < %u\n", c->snd.una, hdr.ack, c->snd.una + c->sndbuf.used);
// Ignore unacceptable RST packets.
if(hdr.ctl & RST)
//Reset the congestion window so we wait for ACKs.
c->snd.nxt = c->snd.una;
c->snd.cwnd = utcp->mtu;
+ start_retransmit_timer(c);
}
}
}
// - or we got an ack, so we should maybe send a bit more data
// -> sendatleastone = false
-ack:
- ack(c, prevrcvnxt != c->rcv.nxt);
+ ack(c, len || prevrcvnxt != c->rcv.nxt);
return 0;
reset:
if(!c)
continue;
+ // delete connections that have been utcp_close()d.
if(c->state == CLOSED) {
if(c->reapable) {
debug("Reaping %p\n", c);
}
if(timerisset(&c->rtrx_timeout) && timercmp(&c->rtrx_timeout, &now, <)) {
+ debug("retransmit()\n");
retransmit(c);
}