networking · advanced · ~15 min

Sliding Window Packet ACK Tracker

Implement sliding window transport flow control and monotonic window advancement.

Challenge

Reliable transport protocols (TCP) maintain sliding send and receive windows to track unacknowledged packets and advance the window sequence monotonically.

Your Task

Given the sliding window tracker structure:

typedef struct {
    uint32_t base_seq;       // lowest unACKed sequence
    uint32_t next_seq;       // next sequence to transmit
    uint32_t window_size;    // maximum in-flight packets
    uint8_t acked_bitmap[32];// bitmask for packets in [base_seq, base_seq + window_size - 1]
} SlidingWindow;

Implement:

void window_init(SlidingWindow *w, uint32_t initial_seq, uint32_t win_size);
int window_can_send(const SlidingWindow *w);
int window_send_packet(SlidingWindow *w, uint32_t *assigned_seq);
int window_receive_ack(SlidingWindow *w, uint32_t ack_seq);

Rules

  1. window_init: set base_seq = initial_seq, next_seq = initial_seq, window_size = min(win_size, 256), zero acked_bitmap.
  2. window_can_send: return 1 if next_seq - base_seq < window_size, otherwise 0.
  3. window_send_packet: if window_can_send(w) == 0, return -1. Write *assigned_seq = next_seq, increment next_seq++, return 0.
  4. window_receive_ack: if ack_seq < base_seq or ack_seq >= next_seq, return -1. Mark bit ack_seq - base_seq in acked_bitmap. While the bit corresponding to base_seq is ACKed: advance base_seq++, and shift acked_bitmap left by 1 bit. Return 0.

Example

SlidingWindow w; window_init(&w, 100, 4);
uint32_t seq;
window_send_packet(&w, &seq); // seq == 100
window_send_packet(&w, &seq); // seq == 101
window_receive_ack(&w, 100); // base_seq advances to 101

Input format

w: SlidingWindow pointer; sequence numbers: uint32_t.

Output format

Returns 0 on success, -1 on window full/stale ACK.

Constraints

Zero heap allocations. Cumulative and selective ACK sliding logic.

Starter code

#include <stddef.h>
#include <stdint.h>

typedef struct {
    uint32_t base_seq;
    uint32_t next_seq;
    uint32_t window_size;
    uint8_t acked_bitmap[32];
} SlidingWindow;

void window_init(SlidingWindow *w, uint32_t initial_seq, uint32_t win_size) {
    (void)w; (void)initial_seq; (void)win_size;
}
int window_can_send(const SlidingWindow *w) { (void)w; return 0; }
int window_send_packet(SlidingWindow *w, uint32_t *assigned_seq) { (void)w; (void)assigned_seq; return -1; }
int window_receive_ack(SlidingWindow *w, uint32_t ack_seq) { (void)w; (void)ack_seq; return -1; }

Common mistakes

Shifting bitmap improperly across byte boundaries; allowing send when window is full.

Edge cases to handle

Out-of-order ACK marks bitmap without advancing base; in-order ACK cascades base advancement.

Background lessons

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.