.. index::
   double: subsystem; MESSENGER

.. _MESSENGER-Subsystem:

MESSENGER — Room-based end-to-end messaging 
===========================================

The MESSENGER subsystem is responsible for secure end-to-end
communication in groups of nodes in the GNUnet overlay network.
MESSENGER builds on the CADET subsystem which provides a reliable and
secure end-to-end communication between the nodes inside of these
groups.

Additionally to the CADET security benefits, MESSENGER provides
following properties designed for application level usage:

-  MESSENGER provides integrity by signing the messages with the users
   provided ego

-  MESSENGER adds (optional) forward secrecy by replacing the key pair
   of the used ego and signing the propagation of the new one with old
   one (chaining egos)

-  MESSENGER provides verification of a original sender by checking
   against all used egos from a member which are currently in active use
   (active use depends on the state of a member session)

-  MESSENGER offsers (optional) decentralized message forwarding between
   all nodes in a group to improve availability and prevent MITM-attacks

-  MESSENGER handles new connections and disconnections from nodes in
   the group by reconnecting them preserving an efficient structure for
   message distribution (ensuring availability and accountablity)

-  MESSENGER provides replay protection (messages can be uniquely
   identified via SHA-512, include a timestamp and the hash of the last
   message)

-  MESSENGER allows detection for dropped messages by chaining them
   (messages refer to the last message by their hash) improving
   accountability

-  MESSENGER allows requesting messages from other peers explicitly to
   ensure availability

-  MESSENGER provides confidentiality by padding messages to few
   different sizes (512 bytes, 4096 bytes, 32768 bytes and maximal
   message size from CADET)

-  MESSENGER adds (optional) confidentiality with ECDHE to exchange and
   use symmetric encryption, encrypting with both AES-256 and Twofish
   but allowing only selected members to decrypt (using the receivers
   ego for ECDHE)

Also MESSENGER provides multiple features with privacy in mind:

-  MESSENGER allows deleting messages from all peers in the group by the
   original sender (uses the MESSENGER provided verification)

-  MESSENGER allows using the publicly known anonymous ego instead of
   any unique identifying ego

-  MESSENGER allows your node to decide between acting as host of the
   used messaging room (sharing your peer's identity with all nodes in
   the group) or acting as guest (sharing your peer's identity only with
   the nodes you explicitly open a connection to)

-  MESSENGER handles members independently of the peer's identity making
   forwarded messages indistinguishable from directly received ones (
   complicating the tracking of messages and identifying its origin)

-  MESSENGER allows names of members being not unique (also names are
   optional)

-  MESSENGER does not include information about the selected receiver of
   an explicitly encrypted message in its header, complicating it for
   other members to draw conclusions from communication partners


:index:`libgnunetmessenger <single: libgnunet; messenger>`
----------------------------------------------------------

The MESSENGER API (defined in ``gnunet_messenger_service.h``) allows P2P
applications built using GNUnet to communicate with specified kinds of
messages in a group. It provides applications the ability to send and
receive encrypted messages to any group of peers participating in GNUnet
in a decentralized way ( without even knowing all peers's identities).

MESSENGER delivers messages to other peers in \"rooms\". A room uses a
variable amount of CADET \"channels\" which will all be used for message
distribution. Each channel can represent an outgoing connection opened
by entering a room with ``GNUNET_MESSENGER_enter_room`` or an incoming
connection if the room was opened before via
``GNUNET_MESSENGER_open_room``.

|messenger_room|

To enter a room you have to specify the \"door\" (peer's identity of a
peer which has opened the room) and the key of the room (which is
identical to a CADET \"port\"). To open a room you have to specify only
the key to use. When opening a room you automatically distribute a
PEER-message sharing your peer's identity in the room.

Entering or opening a room can also be combined in any order. In any
case you will automatically get a unique member ID and send a
JOIN-message notifying others about your entry and your public key from
your selected ego.

The ego can be selected by name with the initial
``GNUNET_MESSENGER_connect`` besides setting a (identity-)callback for
each change/confirmation of the used ego and a (message-)callback which
gets called every time a message gets sent or received in the room. Once
the identity-callback got called you can check your used ego with
``GNUNET_MESSENGER_get_key`` providing only its public key. The function
returns NULL if the anonymous ego is used. If the ego should be replaced
with a newly generated one, you can use ``GNUNET_MESSENGER_update`` to
ensure proper chaining of used egos.

Also once the identity-callback got called you can check your used name
with ``GNUNET_MESSENGER_get_name`` and potentially change or set a name
via ``GNUNET_MESSENGER_set_name``. A name is for example required to
create a new ego with ``GNUNET_MESSENGER_update``. Also any change in
ego or name will automatically be distributed in the room with a NAME-
or KEY-message respectively.

To send a message a message inside of a room you can use
``GNUNET_MESSENGER_send_message``. If you specify a selected contact as
receiver, the message gets encrypted automatically and will be sent as
PRIVATE- message instead.

To request a potentially missed message or to get a specific message
after its original call of the message-callback, you can use
``GNUNET_MESSENGER_get_message``. Additionally once a message was
distributed to application level and the message-callback got called,
you can get the contact respresenting a message's sender respectively
with ``GNUNET_MESSENGER_get_sender``. This allows getting name and the
public key of any sender currently in use with
``GNUNET_MESSENGER_contact_get_name`` and
``GNUNET_MESSENGER_contact_get_key``. It is also possible to iterate
through all current members of a room with
``GNUNET_MESSENGER_iterate_members`` using a callback.

To leave a room you can use ``GNUNET_MESSENGER_close_room`` which will
also close the rooms connections once all applications on the same peer
have left the room. Leaving a room will also send a LEAVE-message
closing a member session on all connected peers before any connection
will be closed. Leaving a room is however not required for any
application to keep your member session open between multiple sessions
of the actual application.

Finally, when an application no longer wants to use CADET, it should
call ``GNUNET_MESSENGER_disconnect``. You don't have to explicitly close
the used rooms or leave them.

Here is a little summary to the kinds of messages you can send manually:

.. _MERGE_002dmessage:

MERGE-message
^^^^^^^^^^^^^

MERGE-messages will generally be sent automatically to reduce the amount
of parallel chained messages. This is necessary to close a member
session for example. You can also send MERGE-messages manually if
required to merge two chains of messages.

.. _INVITE_002dmessage:

INVITE-message
^^^^^^^^^^^^^^

INVITE-messages can be used to invite other members in a room to a
different room, sharing one potential door and the required key to enter
the room. This kind of message is typically sent as encrypted
PRIVATE-message to selected members because it doesn't make much sense
to invite all members from one room to another considering a rooms key
doesn't specify its usage.

.. _TEXT_002dmessage:

TEXT-message
^^^^^^^^^^^^

TEXT-messages can be used to send simple text-based messages and should
be considered as being in readable form without complex decoding. The
text has to end with a NULL-terminator character and should be in UTF-8
encoding for most compatibility.

.. _FILE_002dmessage:

FILE-message
^^^^^^^^^^^^

FILE-messages can be used to share files inside of a room. They do not
contain the actual file being shared but its original hash, filename,
URI to download the file and a symmetric key to decrypt the downloaded
file.

It is recommended to use the FS subsystem and the FILE-messages in
combination.

.. _DELETE_002dmessage:

DELETE-message
^^^^^^^^^^^^^^

DELETE-messages can be used to delete messages selected with its hash.
You can also select any custom delay relative to the time of sending the
DELETE-message. Deletion will only be processed on each peer in a room
if the sender is authorized.

The only information of a deleted message which being kept will be the
chained hashes connecting the message graph for potential traversion.
For example the check for completion of a member session requires this
information.

.. _Member-sessions:

Member sessions
---------------

A member session is a triple of the room key, the member ID and the
public key of the member's ego. Member sessions allow that a member can
change their ID or their ego once at a time without losing the ability
to delete old messages or identifying the original sender of a message.
On every change of ID or EGO a session will be marked as closed. So
every session chain will only contain one open session with the current
ID and public key.

If a session is marked as closed the MESSENGER service will check from
the first message opening a session to its last one closing the session
for completion. If a the service can confirm that there is no message
still missing which was sent from the closed member session, it will be
marked as completed.

A completed member session is not able to verify any incoming message to
ensure forward secrecy preventing others from using old stolen egos.

.. |messenger_room| image:: /_static/images/messenger_room.png
