quiche icon indicating copy to clipboard operation
quiche copied to clipboard

I have a question about ack block

Open xs-411 opened this issue 2 years ago • 1 comments

I would like to ask a question regarding the "ack frame block." I would appreciate it if you could provide an answer. Thank you.

As the receiver, I have received a sequence of packets from 1 to 5. Suddenly, I received a packet with the number 8. Is the following ACK reply correct?

{
Frame Type: ACK (0x0000000000000003)
Largest Acknowledged: 8
ACK Range Count: 1
First ACK Range: 5
{
gap: 2 (6-7)
length: 5 (1-5)
}
}

Afterward, if I receive a packet with the number 9, is the following approach correct? Should I save the previous ACK Range block and continue with the reply?

{
Frame Type: ACK (0x0000000000000003)
Largest Acknowledged: 9
ACK Range Count: 1
First ACK Range: 1 (8)
{
gap: 2 (6-7)
length: 5 (1-5)
}
}

Largest Acknowledged: 9 May I ask if my ack reply is correct? When should I remove the ack block? Next, I received package 13. Is my ack range correct?

{
Frame Type: ACK (0x0000000000000003)
Largest Acknowledged: 13
ACK Range Count: 2
First ACK Range: 0
{
gap:3 (10-12)
length:1 (9)
}
{
gap: 2 (6-7)
length: 5 (1-5)
}
}

xs-411 avatar Jun 29 '23 13:06 xs-411


class AckFrame:
    def __init__(self):
        self.ack_ranges = []  # List of (range_start, range_end)

    def insert_packet(self, packet_num):
        # Check if packet fits into an existing range or creates a new one
        for i, (start, end) in enumerate(self.ack_ranges):
            if start <= packet_num <= end:
                return  # Already acknowledged

            if packet_num == end + 1:
                # Extend existing range
                self.ack_ranges[i] = (start, packet_num)
                return
            elif packet_num == start - 1:
                # Extend existing range in the other direction
                self.ack_ranges[i] = (packet_num, end)
                return

        # Create a new range for out-of-order packet
        self.ack_ranges.append((packet_num, packet_num))
        self.ack_ranges.sort(reverse=True)  # Ensure the largest first

    def remove_acked_packets(self, received_packets):
        # Remove gaps when missing packets are received
        for packet_num in received_packets:
            for i, (start, end) in enumerate(self.ack_ranges):
                if start <= packet_num <= end:
                    if start == end:  # Single packet range
                        self.ack_ranges.pop(i)
                    elif packet_num == start:
                        self.ack_ranges[i] = (start + 1, end)
                    elif packet_num == end:
                        self.ack_ranges[i] = (start, end - 1)
                    else:
                        # Split the range
                        self.ack_ranges[i] = (start, packet_num - 1)
                        self.ack_ranges.insert(i + 1, (packet_num + 1, end))
                    break

    def generate_ack_frame(self):
        largest_ack = self.ack_ranges[0][1]  # Largest acknowledged
        ack_frame = {
            "Frame Type": "ACK (0x03)",
            "Largest Acknowledged": largest_ack,
            "ACK Range Count": len(self.ack_ranges) - 1,
            "First ACK Range": self.ack_ranges[0][1] - self.ack_ranges[0][0],
            "ACK Ranges": []
        }
        
        # Generate the gap and length details for each range
        prev_end = largest_ack
        for start, end in self.ack_ranges[1:]:
            gap = prev_end - end - 1
            length = end - start
            ack_frame["ACK Ranges"].append({"gap": gap, "length": length})
            prev_end = start

        return ack_frame

ljluestc avatar Oct 18 '24 05:10 ljluestc