	HAProxy's peers v2.0 protocol 08/18/2016

Author: Emeric Brun ebrun@haproxy.com


I) Encoded Integer and Bitfield.


       0  <= X < 240        : 1 byte  (7.875 bits)  [ XXXX XXXX ]
      240 <= X < 2288       : 2 bytes (11 bits)     [ 1111 XXXX ] [ 0XXX XXXX ]
     2288 <= X < 264432     : 3 bytes (18 bits)     [ 1111 XXXX ] [ 1XXX XXXX ]   [ 0XXX XXXX ]
   264432 <= X < 33818864   : 4 bytes (25 bits)     [ 1111 XXXX ] [ 1XXX XXXX ]*2 [ 0XXX XXXX ]
 33818864 <= X < 4328786160 : 5 bytes (32 bits)     [ 1111 XXXX ] [ 1XXX XXXX ]*3 [ 0XXX XXXX ]




I) Handshake

Each peer try to connect to each others, and each peer is listening
for a connect from other peers.


Client                             Server
	    Hello Message
         ------------------------>

	    Status Message
         <------------------------

1) Hello Message

Hello message is composed of 3 lines:

<protocol> <version>
<remotepeerid>
<localpeerid> <processpid> <relativepid>

protocol: current value is "HAProxyS"
version: current value is "2.0"
remotepeerid: is the name of the target peer as defined in the configuration peers section.
localpeerid: is the name of the local peer as defined on cmdline or using hostname.
processid: is the system process id of the local process.
relativepid: is the haproxy's relative pid (0 if nbproc == 1)

2) Status Message

Status message is a code followed by a LF.

200: Handshake succeeded
300: Try again later
501: Protocol error
502: Bad version
503: Local peer name mismatch
504: Remote peer name mismatch


IV) Messages

Messages:

0 - - - - - - - 8 - - - - - - - 16
  Message Class| Message Type

if Message Type >= 128

0 - - - - - - - 8 - - - - - - - 16 .....
  Message Class|  Message Type  | encoded data length | data

Message Classes:
0:   control
1:   error
10:  related to stick table updates
255: reserved


1) Control Messages Class

Available message Types for class control:
0: resync request
1: resync finished
2: resync partial
3: resync confirm


a) Resync Request Message

This message is used to request a full resync from a peer

b) Resync Finished Message

This message is used to signal remote peer that locally known updates have been pushed, and local peer was considered up to date.

c) Resync Partial Message

This message is used to signal remote peer that locally known updates have been pushed, and but the local peer is not considered up to date.

d) Resync Confirm Message

This message is an ack for Resync Partial or Finished Messages.

It's allow the remote peer to go back to "on the fly" update process.


2) Messages Class

Available message Types for this class are:
0: protocol error
1: size limit reached

a) Protocol Message

To signal that a protocol error occurred. Connection will be shutdown just after sending this message.

b) Size Limit Error Message

To signal that a message is outsized and can not be correctly handled. Connection will be broken.



3) Stick Table Updates Messages Class

Available message Types for this class are:
0: Entry update
1: Incremental entry update
2: table definition
3: table switch
4: updates ack message.


a) Update Message

0 - - - - - - - 8 - - - - - - - 16 .....
 Message class  | Message Type  | encoded data length | data


data is composed like this

0 - - - - - - - 32 .............................
Local Update ID |  Key value | data values ....

Update ID in a 32bits identifier of the local update.

Key value format depends of the table key type:

- for keytype string

0 .................................
encoded string length | string value

- for keytype integer
0 - - - - - - - - - - 32
encoded integer value |

- for other key type

The value length is announced in table definition message
0 ....................
value


b) Incremental Update Message

Same format than update message  except the Update ID is not present, the receiver should
consider that the update ID is an increment of 1 of the previous considered update message (partial or not)


c) Table Definition Message

This message is used by the receiver to identify the stick table concerned by next update messages and
to know which data is pushed in these updates.

0 - - - - - - - 8 - - - - - - - 16 .....
 Message class  | Message Type  | encoded data length | data


data is composed like this

0 ...................................................................
Encoded Sender Table Id | Encoded Local Table Name Length | Table Name | Encoded Table Type | Encoded Table Keylen | Encoded Table Data Types Bitfield


Encoded Sender Table ID present a the id numerical ID affected to that table by the sender
It will be used by "Updates Aknowlegement Messages" and "Table Switch Messages".

Encoded Local Table Name Length present the length to read the table name.

"Table Name" is the shared identifier of the table (name of the current table in the configuration)
It permits the receiver to identify the concerned table. The receiver should keep in memory the matching
between the "Sender Table ID" to identify it directly in case of "Table Switch Message".

Table Type present the numeric type of key used to store stick table entries:
integer
 2: signed integer
 4: IPv4 address
 5: IPv6 address
 6: string
 7: binary

Table Keylen present the key length or max length in case of strings or binary (padded with 0).

Data Types Bitfield present the types of data linearly pushed in next updates message (they will be linearly pushed in the update message)
Known types are
bit
  0: server id
  1: gpt0
  2: gpc0
  3: gpc0 rate
  4: connections counter
  5: connection rate
  6: number of current connections
  7: sessions counter
  8: session rate
  9: http requests counter
 10: http requests rate
 11: errors counter
 12: errors rate
 13: bytes in counter
 14: bytes in rate
 15: bytes out rate
 16: bytes out rate
 17: gpc1
 18: gpc1 rate

d) Table Switch Message

After a Table Message Define, this message can be used by the receiver to identify the stick table concerned by next update messages.

0 - - - - - - - 8 - - - - - - - 16 .....
 Message class  | Message Type  | encoded data length | data


data is composed like this


0 .....................
encoded Sender Table Id

c) Update Ack Message

0 - - - - - - - 8 - - - - - - - 16 .....
 Message class  | Message Type  | encoded data length | data

data is composed like this

0 ....................... - - - - - - - - 32
Encoded Remote Table Id | Update Id


Remote Table Id is the numeric identifier of the table on the remote side.
Update Id is the id of the last update locally committed.

If a re-connection occurred, the sender should know they will have to restart the push of updates from this point.

III) Initial full resync process.


a) Resync from local old process

An old soft-stopped process will close all established sessions with remote peers and will try to connect to a new
local process to push all known ending with a Resync Finished Message or a Resync Partial Message (if it it does not consider itself as full updated).

A new process will wait for a an incoming connection from a local process during 5 seconds. It will learn the updates from this
process until it receives a Resync Finished Message or a Resync Partial Message. If it receive a  Resync Finished Message it will consider itself
as fully updated and stops to ask for resync. If it receive a Resync Partial Message it will wait once again for 5 seconds for an other incoming connection from a local process.
Same thing if the session was broken before receiving any "Resync Partial Message" or "Resync Finished Message".

If one of these 5 seconds timeout expire, the process will try to request resync from a remote connected peer (see b). The process will wait until 5seconds
if no available remote peers are found.

If the timeout expire, the process will consider itself ass fully updated

b) Resync from remote peers

The process will randomly choose a remote connected peer and ask for a full resync using a Resync Request Message. The process will wait until 5seconds
if no available remote peers are found.

The chosen remote peer will push its all known data ending with a Resync Finished Message or a Resync Partial Message (if it it does not consider itself as full updated).

If it receives a Resync Finished Message it will consider itself as fully updated and stops to ask for resync.

If it receives a Resync Partial Message, the current peer will be flagged to anymore be requested and any other connected peer will be randomly chosen for a resync request (5s).

If the session is broken before receiving any of these messages any other connected peer will be randomly chosen for a resync request (5s).

If the timeout expire, the process will consider itself as fully updated


