Documentation‎ > ‎Developer Resources‎ > ‎Connecting‎ > ‎

Cobalt Protocol

This document describes how a Cobalt client connects to an already existing Cobalt island somewhere on the network

To connect to an island, a client needs information about how to find
that island. This information is contained in an instance of TPostcard.
TPostcards are typically created out of XML joinme strings or data
returned from an LDAP server.

Connecting consists of the following steps:
0. Have a TPostcard on hand
1. Resolve the TPostcard into a TContact
2. Connect to a Cobalt dispatcher running at some address and port
   (given by the TContact instance)
3. Connect to a specific router running on the dispatcher
4. Connect to a specific island running on the router.

0. Have a TPostcard on hand
A client begins connecting by calling the method CroquetHarness >>
openConnectionTo: with its TPostcard instance.

1. Resolve the TPostcard into a TContect
A TPostcard is a high-level description of where to find a router, but a
TContact actually specifies where on the network it may be. The harness
resolves the TPostcard into a TContact by calling TPathNameResolver >>
rosolveContactByPostcard:ifAbsent: (from within CroquetHarness >>
openConnectionTo:ifUnavailable:). I won't go into how that works, as
it's outside the scope of this document.

2. Connect to a Cobalt dispatcher

Once it has a TContact to work with, the harness creates a
CobaltController to manage the high-level connection with the island
[TContact >> setupContactHarness, CobaltHarness >>
connectTo:port:sessionID]. The controller, in turn allocates a
CobaltControllerConnection to handle the low-level communication with
the router.  The first step is simple: the connection opens a TCP socket
to the IP address and port specified in the TContact [TMessageRelay >>
connect].

3. Connect to a Cobalt message router

A dispatcher does nothing but connect clients to routers, and also may
create routers, depending on configuration. To connect to a router, the
client sends a 128-bit session
identifier on the newly-opened TCP connection with the dispatcher [TMessageRelay >>
connectTo:port:sessionID:]. If the router is unknown to the dispatcher,
it may create one with that ID, depending on configuration [TSessionDispatcher >>
dispatchConnection:sessionID:]. The router then allocates a
CobaltMessageRouterClient to handle the low-level communication with the client
[TMessageRouter >> acceptConnectionFrom:].

=== Router protocol ===

The client is now connected to the router thru a TCP socket. An instance
of CobaltControllerConnection handles the protocol details on the client
end, and an instance of CobaltMessageRouterClient handles the details on
the router side. From this point forward, the protocol is symmetric;
CobaltControllerConnection and CobaltMessageRouterClient share a common
subclass: TMessageRelay.

The TMessageRelay protocol is an ordered datagram protocol. The client
and router exchange datagrams one after the other, with nothing in
between, over the TCP socket the client and dispatcher established.
The structure of the datagram is this [TMessageRelay >>
runReaderProcess, TMessageRelay >> sendDatagram:]:

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |            Size (32-bit big-endian unsigned integer)          |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    4 |       CRC Checksum (32-bit big-endian unsigned integer)       |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    8 |                                                               |
      +                                                               +
   16 |                                                               |
      +                   Facet ID (128-bit UUID)                     +
   24 |                                                               |
      +                                                               +
   32 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   48 |                                                               |
      .                                                               .
      .                   Payload (<Size> bytes)                      .
      .                                                               .
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The Facet ID and Payload may be encrypted by an ARC4 cipher. The Size
and Checksum never are

Size: the size of the payload, in bytes.
Checksum: CRC checksum of the (decrypted) Facet ID and Payload fields.
Facet ID: an identifier for a payload interpreter
Payload: Uninterpreted raw data of <Size> bytes.

A facet is a method that accepts two arguments: [TMessageRelay >>
invokeFacet:with:]
1. The payload from the datagram <ByteArray>
2. The relay it was delivered to <TMessageRelay>

message format. If <Facet ID> identifies a facet the
receiver understands, the facet will interpret the payload

Each facet has a name and an identifier. The name is a simple string, and the
identifier is a 128-bit UUID.

A Cobalt router understands the following facets:

Reciever (Router)                               Reciever Name (Router)                              ID
Sender   (Client)                               Sender   Name (Client)                              Creator
------------------------------------------------------------------------------------------------------------------------------------------------
CobaltMessageRouter >> requestRouterInfo:from:  CobaltController class >> requestAuthServicesFacet  a554dfd6b22eb0708bbf938da499be82
CobaltController >> requestRouterInfo           CobaltController class >> requestAuthServicesFacet  CobaltMessageRouter >> initializeFacets

CobaltMessageRouter >> login:from:              CobaltAuthService class >> loginFacet               bbd9dab1b2cb31cf9837d3b463cfe931
CobaltAuthService >> login:password:controller: CobaltAuthService class >> loginFacet               CobaltMessageRouter >> initializeWithConfig:

CobaltMessageRouter >> identify:from:           CobaltMessageRouterClient ivar identifyFacet        <random per connection>
CoPublicKeyAuthService >> challenge:from:controller:    temporary identifyFacet                     CoPublicKeyAuthService >> login:from:router:

CobaltMessageRouter >> listFacets:from:         TMessageRouterClient ivar listFacet                 <random per connection>
CobaltAuthService >> challenge:from:controller: temporary listFacet                                 CobaltAuthService >> login:from:router:

TMessageRouter >> join:from:                    facet joinFacet                                     <random per router>
TRemoteController >> join                       facet join                                          TMessageRouter >> initializeFacets

TMessageRouter >> leave:from:                   facet leaveFacet                                    <random per router>
TRemoteController >> leave                      facet leave                                         TMessageRouter >> initializeFacets

TMessageRouter >> sync:from:                    facet syncFacet                                     <random per router>
TRemoteController >> sync:                      facet sync                                          TMessageRouter >> initializeFacets

TMessageRouterClient >> syncReply:from:         <none>                                              <random per request>
TRemoteController >> serve:from:                temporary facet                                     TMessageRouter >> sync:from:

TMessageRouter >> heartbeat:from:               facet heartbeatFacet                                <random per router>
TRemoteController >> heartbeat:                 facet heartbeat                                     TMessageRouter >> initializeFacets

TMessageRouter >> beServer:from:                facet beServerFacet                                 <random per router>
TRemoteController >> beServer                   facet beServer                                      TMessageRouter >> initializeFacets

TMessageRouter >> send:from:                    facet sendFacet                                     <random per router>
TRemoteController >> sendMessage:               facet send                                          TMessageRouter >> initializeFacets

TMessageRouter >> timeStamp:from:               facet timeStampFacet                                <random per router>
TRemoteController >> routerStamp:               facet timeStamp                                     TMessageRouter >> initializeFacets
------------------------------------------------------------------------------------------------------------------------------------------------


A Cobalt client understands the following facets:

Reciever (Client)                               Reciever Name (Client)                              ID
Sender   (Router)                               Sender   Name (Router)                              Creator
------------------------------------------------------------------------------------------------------------------------------------------------
CobaltController >> routerInfo:from:            facet routerInfo                                    <random per request>
CobaltMessageRouter >> requestRouterInfo:from:  temporary routerInfoFacet                           CobaltController >> requestRouterInfo

CobaltController >> challenge:from:             facet challenge                                     <random per request>
CobaltAuthService >> login:from:router:         temporary challengeFacet                            CobaltAuthService >> login:password:controller:

CobaltController >> recvFacets:from:            facet recvFacets                                    <random per request>
CobaltAuthService >> listFacetsTo:from:router:  temporary responseFacet                             CobaltAuthService >> challenge:from:controller:

TRemoteController >> joinComplete:from:         facet joinComplete                                  <random per request>
TMessageRouter >> join:from:                    temporary respFacet                                 TRemoteController >> join

TRemoteController >> sync:from:                 facet syncFrom                                      <random per request>
TMessageRouter >> syncReply:from:               TMessageRouterClient ivar syncFacet                 TRemoteController >> sync:

TRemoteController >> serve:from:                facet serve                                         <random per client>
TMessageRouter >> sync:from:                    TMessageRouterClient ivar serveFacet                TRemoteController >> beServer

TRemoteController >> recv:from:                 facet recv                                          <random per request>
TMessageRouter >> dispatchMessage:              TMessageRouterClient ivar recvFacet                 TRemoteController >> join

TRemoteController >> tick:from:                 facet tick                                          <random per request>
TMessageRouterClient >> sendTick                TMessageRouterClient ivar tickFacet                 TRemoteController >> heartbeat:

TRemoteController >> stampComplete:from:        facet stampComplete                                 <random per request>
TMessageRouterClient >> sendTick                TMessageRouterClient ivar tickFacet                 TRemoteController >> routerStamp:

------------------------------------------------------------------------------------------------------------------------------------------------


4. Authenticate to the router

All of the client-side steps to connect to an island are in
CobaltHarness >> connectToIslandAt:port:sessionId:

- Router installs core facets for the connection, but doesn't tell
  the client about them [...]

Note: I think the router uses the same facet ID's for the core facets of
every connection (join, send, sync, etc...). This is a security hole, as
it could allow a logged-in client to give other clients access to facets
the router hasn't authorized them to use. Check how
CobaltMessageRouterClient is created in the router.

- Client sends router a requestRouterInfo datagram [CobaltController >>
  requestRouterInfo]
- Router sends client a routerInfo datagram [CobaltMessageRouter >>
  requestRouterInfo:from:]
- This causes the promise p in CobaltHarness >>
  connectTo:port:sessionID: to resolve
- Client sends router a login datagram [CobaltController >>
  loginWithCredential:]
- If authentication fails, the router closes the TCP socket
  [TMessageRouterClient >> destroy]
- Router installs list facet [CobaltAuthService >> login:from:router:]
- Router sends client a challenge datagram [CobaltMessageRouterClient >>
  loginData:]
- Router begins sending and only accepting encrypted traffic
  [CobaltAuthService >> login:from:router:]
- Client decodes the challenge datagram and installs the encryption keys
  [CobaltAuthService >> challenge:from:controller:]
- Client sends router a list datagram (or identify if using public key
  authentication). The client has to successfully decode the encryption
  keys and the facet ID from the challenge datagram in order to do this.
  [CobaltAuthService >> challenge:from:controller:]
- Router authenticates the user if an identity datagram was sent, and
  closes the socket if auth failed [CoPublicKeyAuthService >>
  identity:from:router:]
- Router collects a list of facets the user is allowed to send to
  [CobaltAuthService >> facetsForUser:authServices:]. Current demo
  implementations require this to send all facets regardless of user,
  namely: join, send, sync, heartbeat, beServer, leave, and timeStamp
  [CobaltAuthService >> allFacets, CobaltController >> recvFacets:from:]
- Router packs the facets into a recvFacets datagram and sends it to the
  client [CobaltAuthService >> challenge:from:controller:]
- Client installs the facets and resolves the login promise
  CobaltHarness >> connectToIslandAt:port:sessionID: is waiting on
  [CobaltController >> recvFacets:from:]

5. Connect to the island

We're still in CobaltHarness >> connectToIslandAt:port:sessionID:

- Client sends router a join datagram [CobaltController >> join]
- Router sends client a joinComplete datagram [TMessageRouter >>
  join:from:]
- Client begins receiving a stream of update messages from the router
  and buffering them [TRemoteController >> recv:from:]
- Client sends router a sync datagram [CobaltController >> sync]
- Router forwards the sync datagram to a server in the form of a serve
  datagram [TMessageRouter >> sync:from:]
- Server sends the router a snapshot of the island in a SyncReply
  datagram [TRemoteController >> serve:from:]
- Router forwards the sync reply datagram to the client in the form of a
  syncFrom datagram [TMessageRouterClient >> syncReply:from:]
- Client leads the snapshot and discards all messages that are older
  than the snapshot, and waits for a newer one to arrive
  [TRemoteController >> install:]
- The server that provided the snapshot sends a no-op message thru the
  router (Object >> yourself), which will be later than the snapshot
  [TRemoteController >> serve:from:]
- Client recieves a message later than the snapshot (which is probably,
  but not necessarily, the one the server just sent. There may be other
  traffic on the island). The client executes the message and is done
  installing the snapshot. [TRemoteController >> install:]
- Client sends a heartbeat datagram to the router requesting tick
  messages be sent every 20 milliseconds [TRemoteController >>
  heartbeat:]

6: tell the harness about the island
- addController: and addIsland:postcard: at the end of CroquetHarness >>
  openConnectionTo:ifUnavailable

7: teleport or make a portal to the island
- TPostcard >> makePortalForAvatar:portalType:
- The avatar sends (or at least recieves) 3 messages during
  CroquetHarness >> gotoSnapshot:


=== Facet Details ===

requestRouterInfo

Payload

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |                                                               |
      +                                                               +
    4 |                                                               |
      +                  Reply Facet ID (128-bit UUID)                +
    8 |                                                               |
      +                                                               +
   12 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

requestRouterInfo reply

Revocation: on send

Payload

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |                                                               |
      .                                                               .
      .              DataStream encoded reply (<Size> bytes)          .
      .                                                               .
  end |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The DataStream encodes an Array with the following
data [CobaltMessageRouter >> requestRouterInfo:from, CobaltController >>
unpackRouterInfo:]:

objOut <Array>
    1. dispatcher dispatcherInfo <Array>
        1. dispatcher uuid <UUID>
        2. dispatcher internalContactInfo <TContact>
        3. dispatcher externalContactInfo <TContact or nil>
    2. CobaltMessageRouter >> authServicesInfo <Array>
        1. authServices first listForController <Array>
            1. authService class name <Symbol>
            1. authService serviceName <String>
        2. authServices second listForController <Array>
        3. etc...

login

Payload

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |  Version ID (2 bytes: 0x0100) |    n = Service Name Length    |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    4 |                                                               |
      .                                                               .
      .     Authentication Service Name (UTF-8 string of n bytes)     .
      .                                                               .
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  4+n |                                                               |
      +                                                               +
  8+n |                                                               |
      +                  Response Facet ID (128 bits)                 +
 12+n |                                                               |
      +                                                               +
 16+n |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 20+n |                                                               |
      .                                                               .
      .             Authentication Payload (<Size>-n-20 bytes)        .
      .                                                               .
  end |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

length: 2-byte big-endian unsigned integer < 1024
Service name must be

LocalSecret Auth Payload
[CobaltLocalSecretTestAuthService >> login:pass:controller:,

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |                                                               |
      .                                                               .
      .         Username (UTF-8 encoded string of <Size> bytes)       .
      .                                                               .
  end |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Challenge (Router -> Client)

Revocation: on receive

Payload is ARC4 encrypted with the user's password or public key

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |                                                               |
      +                                                               +
    4 |                                                               |
      +                    Send Session Key (128 bits)                +
    8 |                                                               |
      +                                                               +
   12 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   16 |                                                               |
      +                                                               +
   20 |                                                               |
      +                  Receive Session Key (128 bits)               +
   24 |                                                               |
      +                                                               +
   28 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   32 |                                                               |
      +                                                               +
   36 |                                                               |
      +                     Next Facet ID (128-bit UUID)              +
   40 |                                                               |
      +                                                               +
   44 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Next facet is either list (for most authentication services), or identify
(for public key authentication)

List (Client -> Router)

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |                                                               |
      +                                                               +
    4 |                                                               |
      +               Receive Facets Facet ID (128-bit UUID)          +
    8 |                                                               |
      +                                                               +
   12 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


Identify (Client -> Router)

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |                                                               |
      +                                                               +
    4 |                                                               |
      +               Receive Facets Facet ID (128-bit UUID)          +
    8 |                                                               |
      +                                                               +
   12 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   16 |      n = Username Length      |                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
   20 |                                                               |
      .                                                               .
      .              Username (UTF-8 string of n bytes)               .
      .                                                               .
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 18+n |      m = Password Length      |                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
 22+n |                                                               |
      .                                                               .
      .              Password (UTF-8 string of m bytes)               .
      .                                                               .
  end |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

m, n < 1024 [String >> asLVRouterData]

recvFacets (Router -> Client)

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |                                                               |
      +                                                               +
    4 |                                                               |
      +                      Join Facet ID (128 bits)                 +
    8 |                                                               |
      +                                                               +
   12 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   16 |                                                               |
      +                                                               +
   20 |                                                               |
      +                      Send Facet ID (128 bits)                 +
   24 |                                                               |
      +                                                               +
   28 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   32 |                                                               |
      +                                                               +
   36 |                                                               |
      +                      Sync Facet ID (128 bits)                 +
   40 |                                                               |
      +                                                               +
   44 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   48 |                                                               |
      +                                                               +
   52 |                                                               |
      +                    Heartbeat Facet ID (128 bits)              +
   56 |                                                               |
      +                                                               +
   60 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   64 |                                                               |
      +                                                               +
   68 |                                                               |
      +                    BeServer Facet ID (128 bits)               +
   72 |                                                               |
      +                                                               +
   76 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   80 |                                                               |
      +                                                               +
   84 |                                                               |
      +                     Leave Facet ID (128 bits)                 +
   88 |                                                               |
      +                                                               +
   92 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   96 |                                                               |
      +                                                               +
  100 |                                                               |
      +                   TimeStamp Facet ID (128 bits)               +
  104 |                                                               |
      +                                                               +
  108 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Join (Client -> Router)

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |                                                               |
      +                                                               +
    4 |                                                               |
      +                      Recv Facet ID (128 bits)                 +
    8 |                                                               |
      +                                                               +
   12 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   16 |                                                               |
      +                                                               +
   20 |                                                               |
      +                    Response Facet ID (128 bits)               +
   24 |                                                               |
      +                                                               +
   28 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

JoinComplete (router -> client)

no payload


Sync (Client -> Router)

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |                                                               |
      +                                                               +
    4 |                                                               |
      +            Response Facet ID (on client) (128 bits)           +
    8 |                                                               |
      +                                                               +
   12 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   16 |                                                               |
      +                                                               +
   20 |             Session ID (for sync requests) (128 bits)         |
      +                            - or -                             +
   24 |           Resource ID (for resource requests) (128 bits)      |
      +                                                               +
   28 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


Serve (Router -> Server)

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |                                                               |
      +                                                               +
    4 |                                                               |
      +            Response Facet ID (on router) (128 bits)           +
    8 |                                                               |
      +                                                               +
   12 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   16 |                                                               |
      +                                                               +
   20 |             Session ID (for sync requests) (128 bits)         |
      +                            - or -                             +
   24 |           Resource ID (for resource requests) (128 bits)      |
      +                                                               +
   28 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

SyncReply (Server -> Router)

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |                                                               |
      .  TSnapshotWriter-encoded island snapshot (for sync requests)  .
      .                            - or -                             .
      .                 ??? (for resource requests)                   .
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


SyncFrom (Router -> Client)

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |                                                               |
      .  TSnapshotWriter-encoded island snapshot (for sync requests)  .
      .                            - or -                             .
      .                 ??? (for resource requests)                   .
      |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Heartbeat (Client -> Router)

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |                                                               |
      +                                                               +
    4 |                                                               |
      +                    Response Facet ID (128 bits)               +
    8 |                                                               |
      +                                                               +
   12 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   16 | tickPeriod (milliseconds) (32-bit big-endian unsigned integer)|
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Tick (Router -> Client)

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |                                                               |
      +  timeStamp (IEEE 754 double-precision floating point number)  +
    4 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


Leave (Client -> Router)

no payload

also causes the router to close the tcp connection

timeStamp (Client -> Router)

bits   0               8              16              24            31
bytes  0               1               2               3
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    0 |                                                               |
      +                                                               +
    4 |                                                               |
      +                    Response Facet ID (128 bits)               +
    8 |                                                               |
      +                                                               +
   12 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   16 |                                                               |
      +  timeStamp (IEEE 754 double-precision floating point number)  +
   20 |                                                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

stampComplete (Router -> Client)

no payload

Comments