Sending Data
DocsImplementation GuideSending Data

Sending Data

Building and sending KSP StreamData frames

Transmitting data in KSP requires constructing a compliant binary frame. High-performance implementations utilize zero-copy serialization buffers.

Frame Construction Flow

To prepare a packet for the network, the sending endpoint executes the following workflow:

  1. Fragmentation: Check if payload size exceeds maximum single-packet limit (typically 16KB to prevent excessive buffer allocation). Fragment if needed.
  2. Compression: If negotiated and enabled, compress the payload using Zstandard. Set the COMPRESSED flag (bit 0) in the header.
  3. Nonce Generation: Increment the local sequence number, build the nonce by XORing the sequence number with the base write IV.
  4. Encryption: Encrypt the payload using the session keys. Use the 48-byte header as AAD.
  5. Tag Appending: Capture the 16-byte authentication tag produced by the AEAD cipher and append it to the end of the packet payload.

Serialization Example (Rust)

use byteorder::{BigEndian, WriteBytesExt};

fn serialize_header(header: &KspHeader, buffer: &mut [u8]) -> Result<(), std::io::Error> {
    let mut writer = &mut buffer[..];
    writer.write_u8(header.version)?;
    writer.write_u8(header.packet_type)?;
    writer.write_u16::<BigEndian>(header.flags)?;
    writer.write_u32::<BigEndian>(header.payload_len)?;
    writer.write_all(&header.session_id)?;
    writer.write_u32::<BigEndian>(header.stream_id)?;
    writer.write_u64::<BigEndian>(header.sequence_number)?;
    writer.write_all(&header.nonce)?;
    Ok(())
}