@item Client sends @code{VoRS v3} to the socket. Just a magic number.
-@item All next messages are prepended with 16-bit big-endian length.
+@item All next messages are @url{http://cr.yp.to/proto/netstrings.txt,
+Netstring} encoded strings. Most of them contain netstring encoded
+sequence of netstrings if multiple values are expected:
-@item Client sends initial Noise handshake message with his username as
-a payload.
+@example
+NS(NS(arg0) || NS(arg1) || ...)
+@end example
+
+@item Client sends initial Noise handshake message with his username,
+room name and optional BLAKE2s-256 hash of the room's password (or an
+empty string) as a payload: @code{"USERNAME", "ROOM", BLAKE2s(PASSWORD)}.
-@item Server answers with final noise handshake message with the payload
-of @code{OK HEX(COOKIE)}, or any other failure message. It may reject a
-client if there are too many peers or its name is already taken.
+@item Server answers with final noise handshake message with the
+@code{"COOKIE", COOKIE}, or @code{"ERR", MSG} failure message.
+It may reject a client if there are too many peers, its name is
+already taken or it provided an invalid room's password.
@item The 128-bit cookie is sent by client over UDP to the server every
second. If UDP packets are lost, then no connection is possible and
may differ from known to client one)
@end itemize
-@item Server replies with @code{SID XXX}, where XXX is ASCII decimal
+@item Server replies with @code{"SID", X}, where X is single byte
stream number client must use.
-@item @code{PING} and @code{PONG} messages are then sent every ten
+@item @code{"PING"} and @code{"PONG"} messages are then sent every ten
seconds as a heartbeat.
@end itemize
@example
-S <- C : e, es, "username"
-S -> C : e, ee, "OK COOKIE"
+S <- C : e, es, NS(NS("USERNAME") || NS("ROOM") || NS("PASSWORD"))
+S -> C : e, ee, NS(NS("COOKIE") || NS(COOKIE))
S <- C : UDP(COOKIE)
-S -> C : "SID XXX"
+S -> C : NS(NS("SID") || NS(X))
-S <- C : "PING"
-S -> C : "PONG"
+S <- C : NS(NS("PING"))
+S -> C : NS(NS("PONG"))
S <> C : ...
-S -> C : "ADD SID USERNAME HEX(KEY)"
+S -> C : NS(NS("ADD") || NS(SID) || NS(USERNAME) || NS(KEY))
S -> C : ...
-S -> C : "DEL SID"
+S -> C : NS(NS("DEL") || NS(SID))
S -> C : ...
@end example