---
title: Framing Layer
description: Developer documentation of the lowest layer of the Quassel Protocol
---

This describes the lowest layer of the protocol, on which the [Message Layer]
rests.

This layer is named the "framing" layer, because its only purpose is to frame messages of higher layers and negotiate
basic features for this use case.

## State Machine

The framing layer has two possible states: `HANDSHAKE` and `CONNECTED`. It starts off in `HANDSHAKE` state.

## Handshake State

First, the client sends `0x42b33f00` with certain flags set depending on available features:

| Flag   | Meaning     |
|--------|-------------|
| `0x01` | TLS         |
| `0x02` | Compression |

Afterwards, the client sends a list of all protocols it supports:

| Version      | Protocol                                           |
|--------------|----------------------------------------------------|
| `0x00000001` | Old legacy protocol, which won’t be described here |
| `0x00000002` | Datastream protocol, as described in this document |

To mark the end of the list, the client sets the flag `0x80000000` on the last protocol in the list.

The server responds with the following data:

| Type    | Field   | Description                                         |
|---------|---------|-----------------------------------------------------|
| `UChar` | flags   | As described above                                  |
| `Short` | extra   | Extra data, depends on the protocol, so far ignored |
| `Char`  | version | Protocol Version                                    |

Afterwards, the server expects the client to first enable TLS (if supported) and afterwards compression (if supported).

Compression is handled as Deflate applied to the socket.

This negotiation ends with the protocol advancing into the `CONNECTED` state.

## Connected State

### Receiving

The client reads an uint32_t of the size of the following message frame in bytes, followed by that message frame.

### Sending

The client sends an uint32_t of the size of the message frame in bytes, followed by that message frame. Afterwards, if
compression is enabled, the compressor is flushed.

[Message Layer]: message.md
