| 574 | // grouped acks, first int - packet_id, second int - bit mask for 32 packets preceding packet_id |
| 575 | const int SIZEOF_ACK = 8; |
| 576 | static int WriteAck(TUdpInTransfer* p, int* dst, int maxAcks) { |
| 577 | int ackCount = 0; |
| 578 | if (p->NewPacketsToAck.size() > 1) |
| 579 | Sort(p->NewPacketsToAck.begin(), p->NewPacketsToAck.end()); |
| 580 | int lastAcked = 0; |
| 581 | for (size_t idx = 0; idx < p->NewPacketsToAck.size(); ++idx) { |
| 582 | int pkt = p->NewPacketsToAck[idx]; |
| 583 | if (idx == p->NewPacketsToAck.size() - 1 || pkt > lastAcked + 30) { |
| 584 | *dst++ = pkt; |
| 585 | int bitMask = 0; |
| 586 | int backPackets = Min(pkt, 32); |
| 587 | for (int k = 0; k < backPackets; ++k) { |
| 588 | if (p->GetPacket(pkt - k - 1)) |
| 589 | bitMask |= 1 << k; |
| 590 | } |
| 591 | *dst++ = bitMask; |
| 592 | if (++ackCount >= maxAcks) |
| 593 | break; |
| 594 | lastAcked = pkt; |
| 595 | //printf("sending ack %d (mask %x)\n", pkt, bitMask); |
| 596 | } |
| 597 | } |
| 598 | p->NewPacketsToAck.clear(); |
| 599 | return ackCount; |
| 600 | } |
| 601 | |
| 602 | static void AckPacket(TUdpOutTransfer* p, int pkt, float deltaT, bool updateRTT) { |
| 603 | if (pkt < 0 || pkt >= p->PacketCount) { |