MUTE is a word which means at least two things:
Q-MUTE is an alternative protocol, thought to be useable in the very same MUTE Network through double-stack nodes. This document describes the protocol.
The MUTE Network, up to day, is quite small, for various reasons. Adding a new incompatible protocol would thus have split even more this network, so the double-protocol feature seem to be quite essential.
This aim is achieved quite simply: the first byte of the normal MUTE Protocol is a “P” (from the word “PublicKey” - remember that normal MUTE protocol is quite ASCII-based), or byte 0x50. This protocol, as a successor, starts with the next byte: “Q” (or byte 0x51). This is the reason why the protocol is named Q-MUTE.
    This method has at least a pair of advantages: first of all, we need to
    read only one byte to decide about compatibility. Second, most programming
    environment provide an ungetc-like function or method, which
    allows you to put back at least one byte just read. This allows
    double-stack nodes to read a byte, know what stack to use, then put back
    the byte and pass the control to the right protocol stack.
    
Q-MUTE is a protocol stack which needs an underlying communication environment, over which it makes some assumptions. That is, a node running the Q-MUTE Protocol Stack requires that he's able to communicate with at least another node through a channel which is full-duplex and that support an 8-bit-clean full-duplex stream abstraction (that is, it's possible to send a stream of data composed of arbitrary 8-bit bytes, on both directions without limitations). Such abstraction is usually satisfied by the common socket abstraction (but can also be implemented over HTTP or other such methods - for example to avoid firewalls).
Here it is a summary of the structure of the Q-MUTE Protocol Stack:
Note that the parallelism with current MUTE protocol makes able a double stack node to integrate even more the two stacks, making them communicate at each layer.
This specifications are quite formal: everything is defined in terms of layering of protocols, data structures, and functions each layer exports to higher levels. Each layer declares some data structures and functions, whose semantic is defined through the description of the network operations which must be accomplished. Their format is kept quite similar to that of RFCs.
Q-MUTE makes assumptions on the Stream Layer, but do not define it. A single Q-MUTE stack can use more Stream Layers at the same time. Currently, no Stream Layer for Q-MUTE is defined, even if such a definition for TCP/IP is trivial. Every Stream Layer has an associated code. The following data types must be defined for every given Stream Layer:
HostAddress. It represents all data needed to identify a
      potential connection between this host and another one. E.g., for TCP/IP
      this would be a couple host/port.HostConnection. It represents a connection.It must also implement those operations, with given semantics:
connect(HostAddress ha): HostConnection.
      This function establish a connection between two nodes. If no host
      correspond to the given HostAddress, this
      function fails. Can also fail for other, unspecified reasons.send(HostConnection hc, byte[] data): void.
      This function sends a chunk of data of any size to given connection.  If
      hc has been disconnect()ed, send
      fails. Can also fail for other, unspecified reasons.receive(HostConnection hc, int length):
      byte[length]. This function receives a chunk of data of any size
      from given connection. If hc has been
      disconnect()ed, receive fails. Can also fail
      for other, unspecified reasons.disconnect(HostConnection hc): void. This
      function removes an established connection. If no connection has been
      established with given host, this function fails. It can fail for no
      other reasons.serialize(HostAddress ha): byte[]. This function takes
      an host address, and serializes it in a sequence of bytes, the first of
      which must be the code of the corresponding Stream Layer.deserialize(byte[] ser): HostAddress. Do the reverse of
      serialize()What about listen()-like method? The QNP layer needs it
The QLP protocol works with an associated Stream Layer, which provides
    its connect, send, receive and
    disconnect functions.
We use here three more data types:
RSAPublicKey.
      RSAPrivateKey.
      QlpConnection.
      The QLP protocol defines the following operations:
qlp_init(RSAPublicKey public, RSAPrivateKey
      private): void. This function simply sets this node's public and
      private key.
      qlp_connect(HostAddress ha, int AES_key_length):
      QlpConnection. This function initializes a secure connection
      between the two endpoints. AES_key_length specifies the
      length of the random generated AES key.
      qlp_send(QlpConnection conn, byte[] data): void. Sends
      some data over the secure connection.qlp_receive(QlpConnection conn, int length):
      byte[length]. Receives some data from the secure connection.qlp_disconnect(QlpConnection conn): void. Closes the
      connection.Here the various operations are explained more in depths, telling what each function is exactly supposed to do.
qlp_init(RSAPublicKey public, RSAPrivateKey
      private): void. Nothing more than what has already been stated.
      qlp_connect(HostAddress ha, int AES_key_length):
      QlpConnection. Connection presumes an exchange of keys. once this
      function is called, a fresh, random AES Key is generated (we will call
      it “our AES key”), whereas public and private keys are the
      same given to qlp_init(). Connection is initiated by
      initiating a connection (through connect()) and sending
      the following data (through send()):
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Protocol Ver. | Public Key Buffer Length..................... | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ............. | Public Key................................... | +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ | ............................................................. | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | AES Key Buffer Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | AES Key...................................................... | +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ | ............................................................. | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Follows an explanation of the various fields:
qlp_send(QlpConnection conn, byte[] data): void.
      Encrypts data through other node's AES key, and send it
      through send().qlp_receive(QlpConnection conn, int length):
      byte[length]. Receives length bytes through
      receive(), and decrypts them using our AES key.qlp_disconnect(QlpConnection conn): void. Simply calls
      disconnect(). Usually, we don't need to
      gracefully inform the partner about our desire to close the connection,
      since underlying protocol will do it for us - so, this means it's OK this
      way?
    The QNP Protocol works with an associated QLP layer, which
    provides its qlp_init, qlp_connect,
    qlp_send, qlp_receive and
    qlp_disconnect.
    
We use here one more data types:
QNPConnection.The QNP protocol defines the following operations:
qnp_init(RSAPublicKey public, RSAPrivateKey private):
      void. This function initializes the QLP and QNP layers.qnp_connect(HostAddress ha): QNPConnection. This
      function connects to given host, and includes it in the routing
      tables.qnp_known_hosts(): HostAddress[]. This function given
      the list of all addresses for known Q-MUTE nodes Perhaps is better to tell “MUTE and Q-MUTE
      nodes”? learned thanks to the informations other nodes gave
      us.qnp_route(QNPMessage m): void. This function routes a
      single packet of data (message) through the hosts we've already
      qnp_connect()ed to.qnp_get(): QNPMessage. This function reads a packet of
      data (Message) which has arrived, if present.Here the various operations are explained more in depths, telling what each function is exactly supposed to do.
qnp_init(RSAPublicKey public, RSAPrivateKey private):
      void. Calls qlp_init(public, private); initialize
      an internal list of HostAddress (which we will call
      “Host Address List”) to an empty list; initialize an internal
      counter (which we will call “Internal Timestamp”) to a random
      value.
      qnp_connect(HostAddress ha): QNPConnection.
      Connection to given host address happens through the following steps:
      qlp_connect(ha).0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Unique Name Length | Unique Name.................. | +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ | ............................................................. | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Timestamp | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Host Count | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Host Addresses............................................... | +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ | ............................................................. | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Accepted | +-+-+-+-+-+-+-+-+Follows an explanation of the various fields:
serialize() function.deserialize() of elements of Host Addresses
        field to the Host Address List.qnp_route(QNPMessage m): void.qnp_get(): QNPMessage.