Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Prototype Pseudocode #79

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions include/psuedocode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
The follow outlines some psuedocode for how to implement the logic for a prototype QEO solution.

```csharp
struct offload_info {
uint operation;
uint direction;
ulong next_packet_number;
addr ip_address;
byte cid[];
key_info key;
}

offload_info[] rx_offload_table;
offload_info[] tx_offload_table;

int rx_cid_length = -1;
int tx_cid_length = -1;

void update_offload(offload_info offloads[]) {
foreach (auto offload in offloads) {
if (offload.operation == "add") {
if (offload.direction == "tx") {
if (tx_cid_length == -1) tx_cid_length = offload.cid.length;
tx_offload_table.add(offload); // eventually will support update too, but simplifying things for now
} else {
if (rx_cid_length == -1) rx_cid_length = offload.cid.length;
rx_offload_table.add(offload); // eventually will support update too, but simplifying things for now
}
} else {
if (offload.direction == "tx") {
tx_offload_table.remove(offload);
} else {
rx_offload_table.remove(offload);
}
}
}
}

// Based on https://github.com/microsoft/msquic/blob/main/src/core/packet.h#L372
void decompress_packet_number(ulong expected_packet_number, uint compressed_packet_number) {
ulong Mask = 0xFFFFFFFF00000000;
ulong PacketNumberInc = (~Mask) + 1;
ulong PacketNumber = (Mask & expected_packet_number) | compressed_packet_number;
if (PacketNumber < expected_packet_number) {
ulong High = expected_packet_number - PacketNumber;
ulong Low = PacketNumberInc - High;
if (Low < High) {
PacketNumber += PacketNumberInc;
}

} else {
ulong Low = PacketNumber - expected_packet_number;
ulong High = PacketNumberInc - Low;
if (High <= Low && PacketNumber >= PacketNumberInc) {
PacketNumber -= PacketNumberInc;
}
}
return PacketNumber;
}

void encrypt_quic_packet(packet packet, offload_info offload) {
// Decompress the full packet number
ulong packet_number =
decompress_packet_number(
offload.next_packet_number,
packet.udp_payload[tx_cid_length+1 .. tx_cid_length+4]); // 4 bytes after the CID

// Update the next full packet number for the next TX/encrypt call
offload.next_packet_number = packet_number + 1;

// TODO - Encrypt the packet payload
// TODO - Encrypt the packet header
}

void on_packet_tx(packet packet) {
if (packet.udp_payload[0] == "long header") return;

// Find the offload info based on the destination IP:port and CID.
offload_info offload =
rx_offload_table.find(
packet.dest_ip_address,
packet.udp_payload[1 .. tx_cid_length]); // tx_cid_length bytes after the first byte

encrypt_quic_packet(packet, offload);
}

void decrypt_quic_packet(packet packet, offload_info offload) {
// TODO - Decrypt packet header

// Decompress the full packet number
ulong packet_number =
decompress_packet_number(
offload.next_packet_number,
packet.udp_payload[rx_cid_length+1 .. rx_cid_length+4]); // 4 bytes after the CID

// Update the next full packet number for the next RX/decrypt call
if (packet_number >= offload.next_packet_number) {
offload.next_packet_number = packet_number + 1;
}

// TODO - Decrypt packet payload
}

void on_packet_rx(packet packet) {
if (packet.udp_payload[0] == "long header") return;

// Find the offload info based on the destination IP:port and CID.
offload_info offload =
rx_offload_table.find(
packet.dest_ip_address,
packet.udp_payload[1 .. rx_cid_length]); // rx_cid_length bytes after the first byte

decrypt_quic_packet(packet, offload);
}
```