\subsection*{About}

libchat6 is a complete library that handles an I\+Pv6 only, peer-\/to-\/peer, end-\/to-\/end encrypted, decentralised, chat client.

\subsection*{Ideas}


\begin{DoxyItemize}
\item Transport is I\+Pv6, but some fallback mechanism to help I\+Pv4 client may be implemented.
\item all clients are identical and no server is needed (some clients might run to act as bootstrap servers but all clients do that as well.)
\item clients have a built-\/in bootstrap list of I\+Pv6 addresses. This list gets updated when the client connects to the network. This allows the client to always have a recent list of bootstraping I\+Ps.
\item There\textquotesingle{}s no central registration site, therefor users just choose a nickname and have a private/public key pair (generated by the client). Clients are identified by their public key.
\item Friends can be searched by their nickname or public key. If a client changes the nickname without changing the key pair, the friend can still be found using the public key. This process is completely handled by the library and is transparent to the user. Is a friend changes the key pair, a new friend request will have to be sent.
\item The interconnection of clients is handled over other clients. The network builds up and paths between clients are calculated similar as a routing protocol for routes. The network is anarchic and no rules, except the protocol, leads it.
\item A client may connect to multiple clients, the network of clients will adjust the routing paths according to a metric and select the best path. The metric is the delay in miliseconds on each connection. A regular keepalive is used to measure the delay and the routing information is adjusted accordingly.
\item To avoid dead paths, a relatively short keepalive timeout is used.
\item The network does not allow store-\/and-\/forward of messages. If the friend is offline, messages cannot be send and the client has to store the message until the friend is available. For mobile clients, notifications might be integrated to wakup the client (no clue how? anyone?)
\item The network allows users to find other users by nickname. Nickname collisions are possible.
\item Chat groups require to send the message to all the clients.
\item Each client will randomly add a certain amount of time to its own metric to avoid disclosing its identifiy to any incoming connection.
\item ... ?
\end{DoxyItemize}

\subsection*{Bootstrapping}

To bootstrap a node, a node will have a list of hardcoded nodes and a list of the last known nodes. The hardcoded list is a list of nodes that are put in place by the initiators of this library. Anyone willing to run a permanent node is welcome to contact us to add a node to the hardcoded list.

\subsection*{Protocol}

\subsubsection*{Principles}

A client is the user. A person or a bot using the network to exchange messages. A node is the entity transporting messages for clients. Both are within the same library but use different identities (keypairs). Nodes sending messages to its peer node(s) will use a temporary keypair generated on startup. This keypair changes at every startup and is not stored. A client, on the other side, will generate a keypair once and will use it to generate a temporary keypair for each chat partner to ensure forward secrecy. The temporary keypair is never stored.

\subsubsection*{Messages format}


\begin{DoxyCode}
<MSGSIGNATURE> <MSGHASH> <TIMESTAMP> <MSGTYPE> [<name>=<value>] ...
\end{DoxyCode}



\begin{DoxyItemize}
\item M\+S\+G\+S\+I\+G\+N\+A\+T\+U\+RE\+: An authenticated M\+S\+G\+H\+A\+SH to prove the origin of the msg. This is signed by the client for client-\/to-\/client messages and by the node key for node-\/to-\/node messages. The first H\+E\+L\+LO message has the signature set to all zeroes.
\item M\+S\+G\+H\+A\+SH\+: A hash of the complete message starting at the timestamp. If the name=value pairs contain a \textquotesingle{}metric\textquotesingle{} option, the hash must be calculated with the metric set to 0.
\item T\+I\+M\+E\+S\+T\+A\+MP\+: The timestamp at the creation of the message, formatted \char`\"{}\+Y\+Y\+Y\+Y-\/mm-\/dd H\+H\+:\+M\+M\+:\+S\+S.\+sss\char`\"{}. The timestamp is always in U\+TC.
\item M\+S\+G\+T\+Y\+PE\+: The msgtime is the type of message that is sent. See below.
\item name=value\+: name=value pairs transport all the message informations and vary depending on the msgtype. See description of msgtypes below.
\end{DoxyItemize}

\subsubsection*{name=value pairs}

N\+O\+TE\+: All \textquotesingle{}value\textquotesingle{} transporting binary or U\+T\+F-\/8 data is represented as base64.


\begin{DoxyItemize}
\item chatid\+: a uuid defining the chat group.
\item clientkey\+: the public key of the sending client.
\item icon\+: base64 encoded png.
\item message\+: a base64 encoded message, encrypted with the target\textquotesingle{}s session key.
\item metric\+: a 32 bits unsigned integer representing the sum of all latencies between the client and the announcing client. An originating client will set a random value between 1000 and 2000 to avoid localisation.
\item msgid\+: a uuid defining a message unique to a chatid.
\item mtype\+: A closed supported list of media types \{text, png, jpeg, gif, webm, vcard, ??\} (text is always U\+T\+F-\/8)
\item neighbour\+: ipv6,port\mbox{[},ipv4\mbox{]} (I\+Pv4 can be optionally disclosed)
\item nickname\+: the nickname chosen by the client (U\+T\+F-\/8 string).
\item nodekey\+: the public key of the sending node.
\item nonce\+: random bytes, also known as initialisation vector. Must be new for every message.
\item sessionkey\+: a session temporary public key.
\item target\+\_\+hash\+: a hash of the target public key. Mainly used for routing.
\item version\+: currenlty has the value of 1.
\end{DoxyItemize}

\subsubsection*{begin and end of session (node-\/to-\/node)}

This is the very first message both nodes will send after connecting. The connecting node will send it\textquotesingle{}s H\+E\+L\+LO first. If the connected node agrees it will reply with its own H\+E\+L\+LO. If it doesn\textquotesingle{}t it will reply with a B\+YE msg and close the connection. Both nodes may send a B\+YE message at any time to terminate the connection.


\begin{DoxyCode}
HELLO \{version,nodekey\}
BYE
\end{DoxyCode}


\subsubsection*{path anouncement and withdrawal}

Clients can announce, withdraw or update their presence. A node will keep all client information and inform any new node of the state of all known clients. The metric must be updated when a O\+N\+L\+I\+NE or U\+P\+D\+A\+TE msg is received.


\begin{DoxyCode}
CLIENT\_ONLINE \{clientkey, nickname, icon, metric\}
CLIENT\_UPDATE \{nonce, nickname, icon, metric\}
CLIENT\_OFFLINE
\end{DoxyCode}


\subsubsection*{K\+E\+E\+P\+A\+L\+I\+VE}

Keepalive and node-\/to-\/node only and are originated by both nodes on a connection. The interval is 15s and if a node doesn\textquotesingle{}t receive a timeout for 30s, it must shutdown the connection. The interval betweeen the request and the response is used to calculate the metric. The metric is caculcated as an average value of the last 10 messages.


\begin{DoxyCode}
KEEPALIVE\_REQUEST
KEEPALIVE\_RESPONSE
\end{DoxyCode}


\subsubsection*{F\+R\+I\+E\+N\+DS \& M\+E\+S\+S\+A\+G\+ES}

The friend request message has two purposes. First, for a new friend, is will ask the friend to confirm to actually be friends. Secondly, it will exchange temporary session keys. This means that everytime a client comes online and wants to initiate a chat with an existing friend, it will have to send a friend request and get a friend confirm message back in order to exchange new temporary keys. If a friend request from an existing friend comes in, the confim message will automatically be sent back without user confirmation. If the friend is unknown, a user confirmation is required.


\begin{DoxyCode}
FRIEND\_REQUEST \{target\_hash, sessionkey\}
FRIEND\_CONFIRM \{target\_hash, sessionkey\}
\end{DoxyCode}


client-\/to-\/client messages are exchanged using those three message types. Message received and read are only confirmations. A UI may implement a visual aid to show those. Message send, sends a message using the name=value pair \textquotesingle{}message\textquotesingle{}. The message is encrypted using the temporary session key of the friend. Messages must be confirmed received, if they don\textquotesingle{}t, the client will retry sending it after a timeout of 30s until a recv is received or a C\+L\+I\+E\+N\+T\+\_\+\+O\+F\+F\+L\+I\+NE message is received. Messages can only be sent to online friends. If a friend is offline, the client will have to store the message until the friend is online.


\begin{DoxyCode}
MESSAGE\_SEND \{target\_hash, chatid, msgid, mtype, message\}
MESSAGE\_RECV \{target\_hash, chatid, msgid\}
MESSAGE\_READ \{target\_hash, chatid, msgid\}
\end{DoxyCode}


\subsubsection*{N\+E\+I\+G\+H\+B\+O\+U\+RS}

In order to discover other nodes, a node may request the directly connected nodes of a neighbor node. The list will be sent back to the requesting node with one or multiple name=value pairs of \textquotesingle{}neighbor\textquotesingle{}. The value is composed of the IP of the node and the T\+CP port separated by a comma. A neighbor will only be disclosed to another neighbor if it is relaying messages for others (showed more than one C\+L\+I\+E\+N\+T\+\_\+\+O\+N\+L\+I\+NE msg).


\begin{DoxyCode}
NEIGHBORS\_REQUEST # request the neighbours of your neighbour
NEIGHBORS\_RESPONSE \{neighbour,..\} # neighbours list, multiple time the same key
\end{DoxyCode}
 