Project

General

Profile

Doc quassel protocols » History » Version 4

« Previous - Version 4/20 (diff) - Next » - Current version
Sputnick, 02/27/2013 01:36 AM


The Quassel Protocol

Overview

When we talk about the "Quassel protocol", we mean the format of data sent between a Quassel core and connected Quassel clients. At the moment (i.e., as of version 0.8), only one protocol - the "legacy protocol" - is in use. It has evolved from Quassel's early days and hasn't really changed all that much over the years. However, back then we didn't really expect Quassel to ever become popular, much less other developers writing alternate clients such as QuasselDroid or iQuassel. Accordingly, instead of designing (and documenting) a well-defined and easy-to-use format, we chose a rather pragmatic approach for sending data over the wire: Because Qt already had a facility to (de)serialize arbitrary data types over a binary stream - using QDataStream - we simply went with that.

While being both straightforward and easy to implement in Quassel, this choice turned out to be rather unlucky in retrospect:

  • QDataStream's serialization format is not the most efficient one. In particular, strings are serialized as UTF-16, which means that almost half of the data exchanged between client and core is nullbytes. However, this is partially compensated by Quassel using compression if possible.
  • Speaking of which, we don't use streaming compression, which means that lots of potential for benefitting from recurring strings is not used. And since many of the objects we send are key/value maps which tend to have the same set of keys every time, this does matter in practice.
  • And to add insult to injury, we waste even more space all over the place because we simply didn't think about optimizing the protocol. Mobile use of Quassel was just not on our radar in 2005.
  • The serialization format is nowhere documented in a concise and complete way. Yes, there's documentation somewhere in Qt for built-in types; for Quassel's own types however, one would have to hunt through the source. And without reading (and understanding) some rather icky parts of Quassel code, it's close to impossible to understand what's going on even if one manages to deserialize the binary data into proper objects. Bad news for people wanting to write alternate clients. Amazingly, some smart people still managed to reverse-engineer the protocol...

To fix these and more issues, we're now planning to replace the legacy protocol by something more sensible. As the first (and most complicated) step, work is now underway to implement a protocol abstraction that will then allow us to much more easily support alternative formats. As a neat side effect, the resulting refactoring also will make some core parts of the code (e.g. SignalProxy) much nicer to understand.

Protocol Abstraction - The Master Plan

Requirements for new protocols

Keeping compatibility

TBD: for how long?

Abstract View

Handshake

Probing

Init and Authentication

Sigproxy Mode

On-Wire Format

Legacy Protocol