BLIP/BLIP Overview.txt
author Jens Alfke <jens@mooseyard.com>
Sat May 24 21:26:09 2008 -0700 (2008-05-24)
changeset 3 76f302097a75
child 4 2bd9d60a2c46
permissions -rw-r--r--
Added a BLIP port of Apple's "CocoaEcho" sample code.
jens@0
     1
BLIP OVERVIEW
jens@0
     2
Jens Alfke <jens@mooseyard.com>
jens@0
     3
Preliminary Draft 1 -- 21 May 2008
jens@0
     4
jens@0
     5
jens@0
     6
BLIP is a generic application-layer network protocol that runs atop TCP. It was inspired by BEEP (in fact BLIP stands for "BEEP-LIke Protocol") but is deliberately simpler and somewhat more limited.
jens@0
     7
jens@0
     8
DATA MODEL
jens@0
     9
jens@0
    10
BLIP lets the two peers on either end of a TCP socket send requests and responses to each other.
jens@0
    11
Each message and response is very much like a MIME body, as in email or HTTP: it consists of a blob of data of arbitrary length, plus a set of key/value pairs called "properties". The properties are mostly ignored by BLIP itself, but clients can use them for metadata about the body, and for delivery information (i.e. something like BEEP's "profiles".)
jens@0
    12
jens@0
    13
Either peer can send a message at any time; there's no notion of "client" and "server" roles. Multiple messages can be transmitted simultaneously over the same connection, so a very long message does not block any other messages from being delivered. This means that message ordering is a bit looser than in BEEP or HTTP 1.1: the receiver will see the beginnings of messages in the same order in which the sender posted them, but they might not end in that same order. (For example, a long message will take longer to be delivered, so it may finish after messages that were begun after it.)
jens@0
    14
jens@0
    15
The sender can indicate whether a message needs to be replied to; the response is tagged with the identity of the original message, to make it easy for the sender to recognize. This makes it straighforward to implement RPC-style (or REST-style) request/response interactions. (Replies cannot be replied to again, however.)
jens@0
    16
jens@0
    17
A message can be flagged as "urgent". Urgent messages are pushed ahead in the outgoing queue and get a higher fraction of the available bandwidth.
jens@0
    18
jens@0
    19
A message can be flagged as "compressed". This runs its body through the gzip algorithm, ideally making it faster to transmit. (Common markup-based data formats like XML and JSON compress extremely well, at ratios up to 10::1.) The message is decompressed on the receiving end, invisibly to client code.
jens@0
    20
jens@0
    21
WIRE FORMAT
jens@0
    22
jens@0
    23
All multi-byte numbers are encoded in network byte-order (big-endian).
jens@0
    24
jens@0
    25
Each message is packed into a series of bytes consisting of the properties followed by the body. The properties are encoded as a 16-bit byte-count followed by a series of NUL-terminated C strings alternating keys and values.
jens@0
    26
jens@0
    27
The message is then broken up into "frames", usually 4k to 12k bytes. Each frame is prefixed with a 12-byte header containing its length in bytes, message number, and some flags.
jens@0
    28
jens@0
    29
Each of the two unidirectional TCP streams carries a sequence of these frames, and nothing else. If multiple messages are queued up at the sender, their frames will be interleaved, so that one message doesn't block the rest. The ordering is primarily round-robin, except that urgent messages are scheduled more often than regular ones; the scheduler tries to alternate urgent and regular frames, and lets the urgent frames be larger. It's rather like a thread scheduler, really.
jens@0
    30
jens@0
    31
When one peer wants to close the connection, it finishes sending all pending frames and then closes its outgoing (write) stream. The other peer detects this and goes into closing mode as well, sending its pending frames and then closing the other stream, which closes the socket. On the other hand, if a peer's writing stream is closed unexpectedly, or its reading stream closes in mid-frame, this indicates a broken connection.
jens@0
    32
jens@0
    33
  Frame header:
jens@0
    34
    UInt32           magic;         // magic number (kBLIPFrameHeaderMagicNumber)
jens@0
    35
    UInt32           number;        // serial number of MSG (starts at 1)
jens@0
    36
    BLIPMessageFlags flags;         // encodes frame type, "more" flag, and other delivery options
jens@0
    37
    UInt16           size;          // total size of frame, _including_ this header
jens@0
    38
jens@0
    39
  Flags:
jens@0
    40
    kBLIP_TypeMask  = 0x000F,       // bits reserved for storing message type
jens@0
    41
    kBLIP_Compressed= 0x0010,       // data is gzipped
jens@0
    42
    kBLIP_Urgent    = 0x0020,       // please send sooner/faster
jens@0
    43
    kBLIP_NoReply   = 0x0040,       // no RPY needed
jens@0
    44
    kBLIP_MoreComing= 0x0080,       // More frames of this message coming
jens@0
    45
    // all other bits reserved
jens@0
    46
jens@0
    47
  Message types:
jens@0
    48
    kBLIP_MSG = 0,                  // initiating message
jens@0
    49
    kBLIP_RPY = 1,                  // response to a MSG
jens@0
    50
    kBLIP_ERR = 2                   // error response to a MSG
jens@0
    51
    // values 3-15 reserved
jens@0
    52
jens@0
    53
jens@0
    54
LIMITATIONS
jens@0
    55
jens@0
    56
Compared to BEEP, the BLIP protocol has:
jens@0
    57
* No channels. (It's as though every message/response were sent on a separate channel.)
jens@0
    58
* No ANS style responses (multiple answers)
jens@0
    59
* No proocol for "tuning" the session by negotiating encryption (SSL) or authentication (SASL, etc.)
jens@0
    60
* No negotiation of closing the connection (a peer can't veto a close)
jens@0
    61
jens@0
    62
Some currently missing features that will likely be added are:
jens@0
    63
* Flow control (i.e. "windows" to throttle the sender so the listener can keep up)
jens@0
    64
* Ability to enforce one-at-a-time ordering of a set of requests and responses, so a message isn't sent until the previous message is complete (as in a BEEP channel)
jens@0
    65
* A more stream-like API for requests and responses, so their bodies can be sent and received incrementally. (The protocol and implementation already support this.)
jens@0
    66
* Ability to stop an incoming message partway through (e.g. to interrupt a file transfer)