The MuWire protocol operates over a TCP-like streaming layer offered by the I2P streaming library, except for "Result" type messages which are delivered of I2P datagrams.
## Handshake
A connection begins with the word "MuWire" followed by a space and either the word "leaf" or "peer", depending on whether Alice is in a leaf or an ultrapeer role. This allows Bob to immediately drop the connection without allocating any more resources if it is a leaf or if it does not have any more connection slots.
## Compression
All traffic after the handshake is compressed using the same compression algorithm in Gnutella.
## Messages
After the handhsake follows a stream of messages. Messages can arrive in any order. Each message consists of 3 bytes - the most significant bit of the first message indicates if the payload is binary or JSON. The remaining 23 bits indicate the length of the message.
The JSON payload has two mandatory top-level fields - type and version:
Binary messages can be two types: full bloom filter or a patch message to be applied to a previously sent bloom filter. Binary messages travel only between ultrapeers. There is a single byte after the payload indicating the type of the binary message. That byte is counted in the total payload length.
This message starts with a single byte which indicates the size of the bloom filter in bits in power of 2, maximum being 22 -> 512kb. The rest of the payload is the bloom filter itself.
#### Patch
This message starts with two unsigned bytes indicating the number of patches included in the message. Each patch consists of 3 bytes, where the most significant bit indicates whether the corresponding bit should be set or cleared and the remaining 23 contain the position within the Bloom filter that is to be patched.