+static void ack(struct utcp_connection *c, bool sendatleastone) {
+ uint32_t left = seqdiff(c->snd.last, c->snd.nxt);
+ int32_t cwndleft = c->snd.cwnd - seqdiff(c->snd.nxt, c->snd.una);
+ char *data = c->sndbuf + seqdiff(c->snd.nxt, c->snd.una);
+
+ if(cwndleft <= 0)
+ cwndleft = 0;
+
+ if(cwndleft < left)
+ left = cwndleft;
+
+ if(!left && !sendatleastone)
+ return;
+
+ struct {
+ struct hdr hdr;
+ char data[c->utcp->mtu];
+ } pkt;
+
+ pkt.hdr.src = c->src;
+ pkt.hdr.dst = c->dst;
+ pkt.hdr.ack = c->rcv.nxt;
+ pkt.hdr.wnd = c->snd.wnd;
+ pkt.hdr.ctl = ACK;
+
+ do {
+ uint32_t seglen = left > c->utcp->mtu ? c->utcp->mtu : left;
+ pkt.hdr.seq = c->snd.nxt;
+
+ memcpy(pkt.data, data, seglen);
+
+ c->snd.nxt += seglen;
+ data += seglen;
+ left -= seglen;
+
+ print_packet(c->utcp, "send", &pkt, sizeof pkt.hdr + seglen);
+ c->utcp->send(c->utcp, &pkt, sizeof pkt.hdr + seglen);
+ } while(left);
+}
+