NOM-1 grammar and notes

pieterhpieterh wrote on 15 Jun 2011 13:57


Time to get formal. Even the simplest contracts have to be robust against our charming but ineradicable stupidity. Perhaps the simplest formal language for an unprotocol is ABNF. So here is a first draft grammar for NOM-1, with notes. This page will morph into a real unprotocol draft spec.

First the whole thing:

NOM-1           = open-peering *use-peering

open-peering    = C:OHAI ( S:OHAI-OK / S:ROTFL )

use-peering     = C:OHAI ( S:OHAI-OK / S:ROTFL )
                / C:HUGZ S:HUGZ-OK
                / S:HUGZ C:HUGZ-OK
                / C:ICANHAZ ( S:ICANHAZ-OK / S:ROTFL )
                / S:ICANHAZ ( C:ICANHAZ-OK / C:ROTFL )
                / C:NOM
                / S:NOM

ROTFL           = version reserved %b0000 %b0000 reason-text
version         = %b0001
reserved        = %b0000
reason-text     = *VCHAR

OHAI            = version reserved %b0001 %b0000 address
address         = ( broadcast / hostname / hostnumber ) ":" port
broadcast       = "*"
hostname        = label *( "." label )
label           = 1*( %x61-7A / DIGIT / "-" )
hostnumber      = 1*DIGIT "." 1*DIGIT "." 1*DIGIT "." 1*DIGIT
port            = 1*DIGIT

OHAI-OK         = version reserved %b0010 %b0000 address

HUGZ            = version reserved %b0011 %b0000
HUGZ-OK         = version reserved %b0100 %b0000

ICANHAZ         = version reserved %b0101 sequence zmq-payload
ICANHAZ-OK      = version reserved %b0110 sequence zmq-payload
sequence        = 4BIT          ; Incrementing for each ICANHAZ
zmq-payload     = 1*zmq-frame
zmq-frame       = frame-size frame-body
frame-size      = 2OCTET        ; In network byte order
frame-body      = *OCTET        ; frame-size octets

NOM             = version reserved %b0111 %b0000 zmq-payload

and now the notes:

  • A client opens a peering to a server. A server binds to and receives from some port. "Client" and "server" means exactly which node opens the peering, and which node accepts the peering. Nothing more. A peering has some state. We'll come to that.
  • A client may start a peering-open dialog before the server is ready. In this case the client will send OHAIs repeatedly, at short intervals, until a server responds with OHAI-OK.
  • The OHAI commands specifies an address, which the OHAI-OK command echoes. This lets a client broadcast OHAI to any listening server, and connect to the one that responds. We call this a broadcast peering.
  • Once a peering is established, either peer can send unsolicited HUGZ, ICANHAZ, or NOM commands. A client can also send OHAI more than once to the same server, which may be needed since UDP can lose messages, e.g. the returning OHAI-OK.
  • The ICANHAZ/ICANHAZ-OK commands are for the synchronous request-reply pattern (specifically for 0MQ REQ/REP sockets). NOM-1 does not use address envelopes, it is designed for single-hop request-reply.
  • Since UDP will randomly drop messages, ICANHAZ implements a minimal resend capability. Each ICANHAZ command has an incrementing sequence number. The sender resends the ICANHAZ at short intervals at least as long as the peering is alive, until it receives a matching ICANHAZ-OK. The recipient will resend its last ICANHAZ-OK if it receives a duplicate request.
  • Heartbeating consists of a ping-pong HUGZ/HUGZ-OK dialog. One peer sends HUGZ to the other, which replies with HUGZ-OK. Neither command has any payload. HUGZ and HUGZ-OK are not correlated. A peer should send HUGZ at regular intervals.
  • Silence means a peer has died. A server should handle this by destroying all resources associated with that peering. A client should handle this by restarting the peering-open dialog.


Add a New Comment
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License