Skip to content

[QUIC] Implement Connection ID storage and rotation management #399

Description

@kcenon

Summary

Implement proper Connection ID storage and rotation management for QUIC connections as required by RFC 9000 Section 5.1.

Current State

The connection.cpp:655 has a TODO indicating new Connection IDs from peer are not stored:

// TODO: Store new connection IDs from peer

Current implementation:

  • Connection IDs can be generated (add_local_cid)
  • Retirement is stubbed (retire_cid)
  • No storage of peer-provided Connection IDs via NEW_CONNECTION_ID frames

RFC 9000 Requirements

Per Section 5.1 (Connection ID):

  • Endpoints must store connection IDs provided by peer
  • Must track sequence numbers and retire_prior_to values
  • Must support Connection ID rotation for path migration
  • Must honor retire_prior_to in NEW_CONNECTION_ID frames

Proposed Implementation

Data Structure

struct connection_id_entry {
    connection_id cid;
    uint64_t sequence_number;
    std::vector<uint8_t> stateless_reset_token;  // 16 bytes
    bool retired{false};
};

class connection_id_manager {
public:
    auto add_peer_cid(const connection_id& cid, 
                      uint64_t sequence,
                      uint64_t retire_prior_to,
                      std::span<const uint8_t, 16> reset_token) -> VoidResult;
    
    auto get_active_peer_cid() const -> const connection_id&;
    auto rotate_peer_cid() -> VoidResult;
    auto retire_cids_prior_to(uint64_t sequence) -> void;
    
private:
    std::vector<connection_id_entry> peer_cids_;
    size_t active_index_{0};
};

Frame Handling

auto connection::handle_new_connection_id_frame(const new_connection_id_frame& frame) 
    -> VoidResult 
{
    // 1. Validate frame
    if (frame.sequence < frame.retire_prior_to) {
        return error_void(connection_error::protocol_violation);
    }
    
    // 2. Store new CID
    cid_manager_.add_peer_cid(
        frame.connection_id,
        frame.sequence,
        frame.retire_prior_to,
        frame.stateless_reset_token);
    
    // 3. Retire old CIDs
    cid_manager_.retire_cids_prior_to(frame.retire_prior_to);
    
    // 4. Send RETIRE_CONNECTION_ID frames for retired CIDs
    queue_retire_connection_id_frames();
    
    return common::ok();
}

Tasks

  • Create connection_id_manager class
  • Implement CID storage with sequence tracking
  • Handle NEW_CONNECTION_ID frames
  • Implement RETIRE_CONNECTION_ID frame generation
  • Implement CID rotation API
  • Add stateless reset token validation
  • Unit tests for CID management
  • Integration tests for CID rotation

Acceptance Criteria

  • NEW_CONNECTION_ID frames are properly processed
  • Peer CIDs are stored with sequence numbers
  • retire_prior_to is honored
  • RETIRE_CONNECTION_ID frames are sent when needed
  • CID rotation works for path migration
  • All unit tests pass

Files to Modify

  • New: include/kcenon/network/protocols/quic/connection_id_manager.h
  • New: src/protocols/quic/connection_id_manager.cpp
  • src/protocols/quic/connection.cpp
  • include/kcenon/network/protocols/quic/connection.h
  • tests/test_quic_connection.cpp

Related

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions