Technical Whitepaper by Clipcode.com
IETF BEEP (RFC 3080) – A Framework for Next Generation Application Protocols
BEEP – The Blocks Extensible Exchange Protocol – is a new specification that provides a common set of services to help designers of application protocols. In the past, when designers were faced with the need for a new application protocol, they had to either face the daunting task of designing a complete new protocol - which is a lot of work, or somehow piggyback on top of an existing protocol (usually HTTP) - and live with all the advantages and disadvantages of the existing protocol.
BEEP is a new approach that recognizes that many application protocols are trying to solve the same set of issues again and again. "How do I set up a connection?" "What message exchange styles should be supported (e.g. one-way, request/response, request/N-response)?" "What about security?" "Who can initiate a message exchange – the client, the server, or both?" "Is asynchronous messaging to be supported (sending multiple messages at the same time)?" The reusability theory that object-oriented professionals have been preaching since the '80s can easily be applied to the design of application protocols - and that is exactly what BEEP does. BEEP tackles those issues that are common to many application protocols once, and leaves the design of the remaining 10% to 20% of issues that are unique to each application protocol to the designers of that application protocol. An interesting paper called "On the design of application protocols" (RFC 3117) describes in detail the rationale behind BEEP.
BEEP is an IETF (www.ietf.org) specification. As the IETF is responsible for standardizing much of the Internet (including HTTP), in it is likely that BEEP will gain more widespread support compared to company-specific solutions.
Example uses of BEEP include distributed application-to-application communication, distributed user interfaces, web services and peer-to-peer services.
Rather than targeting every possible application protocol type, BEEP is aimed at a specific subset with a well-defined list of attributes. BEEP is connection-oriented – which means that a connection is established and maintained – and then messages flow over this, and sometime later the connection is closed. BEEP supports asynchronous interactions, which mean either party to the connection can initiate a message exchange. BEEP defines the concept of discrete messages that belong to well-defined message exchange patterns. The result of this is that BEEP is suitable for some application protocols, such as peer-to-peer communications, and not suitable for others – a classic example would be multimedia streaming –IETF RTP would be more suited for that.
Some application protocols have achieved very widespread success for particular functionality – and it is expected that these will continue to be used. BEEP is not going to replace HTTP for hypertext transfer or SMTP for email. A number of protocols have been layered above HTTP, and in many cases BEEP would be a more suitable foundation for them. One example would be SOAP – the SOAP binding for BEEP specification is already available and a .NET implementation will be provided by clipcode.com shortly.
BEEP is a peer-to-peer application protocol. It describes a direct connection from one endpoint to one other endpoint. It is possible, indeed expected, that multiples of these pairs be established as needed, to form multi-hop connections (e.g. based on the TUNNEL proposal or similar) or to form meshes of relays and end-points (e.g. the APEX proposal).
BEEP travels over a configurable transport service. How it interacts with a particular transport service is specified in a transport mapping document that is defined for each transport service and is separate from the BEEP Core specification. Most current BEEP deployments work over a single TCP connection. In this case, a single BEEP session maps onto a single TCP connection. The purpose of a transport mapping is to describe how BEEP frames travel over an underlying transport service. Typically the transport service is a single TCP connection, but in future others may be supported.
A BEEP session is divided into a number of logical channels. A profile describes what messages may flow over a channel. A profile is identified by a URI and is documented by listing the syntax and semantics of permissible messages. BEEP defines some profiles (for channel management, TLS and authentication). And it is expected that others will define custom profiles for their particular needs.
When a session is established channel 0 is automatically in existence and the BEEP Channel Management profile describes messages may be sent on it to create and close other channels, and to close the entire session. A new channel is created by sending a <start> request on channel 0. It contains one or more profiles that the peer sending the request is prepared to use on the channel. If we imagine Clipcode.com designed a profile describing how a distributed game of chess could be played, a peer could try to establish a channel based on this profile using:
<profile uri='http://clipcode.com/beep/chessprofile' />
The peer that receives such a message can decide to refuse the request, by sending an error, or to accept the channel creation request, by sending the profile message:
<profile uri='http://clipcode.com/beep/chessprofile' />
Once the channel has been established, messages as defined in the profile may flow between the two peers. Some time later either peer can request the channel be closed by sending a close message:
<close number='1' code='200' />
To which the other peer responds with an OK confirmation message.
BEEP supports great flexibility in message handling. Messages in BEEP may be textual or binary. MIME headers are used to describe the message content. Messages may be of any length. XML is often used to describe messages. The default for the MIME "Content-Type" is "application/octet-stream".
All the profiles that the BEEP core defines are based on XML and use the MIME content type of "application/beep+xml". A full message on channel 0 would look like this (it requests that channel 1 be closed with a success code of 200):
<close number='1' code='200' />
Note there is an extra CRLF separating the MIME headers from the body of the message. Also note that the headers are MIME headers – in contrast, HTTP mixes up MIME headers with non-MIME headers and calls them all “HTTP headers”. With BEEP, only MIME headers are permitted in the header section of the message – any other information to be transferred must be part of the message body.
BEEP combines individual messages into message exchanges. A MSG message initiates a message exchange. It can be replied to via a single RPY reply message, an ERR error message or multiple ANS responses followed by a single NUL message. The peer that sends the MSG message is termed the client. The peer that replies is termed the server. A peer can be a client for one message exchange and a server for a different message exchange, even for multiple message exchanges on the same channel at the same time.
Framing is explaining how the start and end of discrete messages are defined. If a message is of fixed size then it is easy to decide when one message completes and the next begins. The size of a BEEP message is not predetermined, so an octet count is provided with each message. Another issue is that we could have a single transport service data flow (e.g. a single TCP connection) and wish to have many channels running over it. What happens if multiple channels wish to send (large) messages concurrently? The goal of BEEP is to allow multiple channels work independently, and so it is not acceptable for one channel to monopolize the connection (e.g. imagine one channel wishes to send a 20MB video file and another wishes to send 20 octets of XML). The BEEP solution is to subdivide messages into small frames – and interleave frames from different channels on the same connection. Thus one gets fair distribution of bandwidth among the competing channels if many are active, yet when only one is active it gets access to the entire bandwidth of the connection.
A frame consists of a frame header, a frame payload and a frame trailer. The frame header consists of the frame type (MSG, RPY, ERR, ANS or NUL), the channel identifier (an integer, that differentiates frames on different channels), a message exchange identifier (that specifies which message exchange a message belongs to), a continuation indicator ('*' means this is not the last frame of a message; '.' means it is), a sequence number (used to verify correct ordering) and a payload size (used to know when the frame is finished). The frame payload contains the octets from the message to be transported. If the message is small, it will fit completely inside a single frame – if it is large, it will be divided into multiple frames. What "small" and "large" mean in actual octet terms depends on the transport service in use (for TCP, a frame should fits comfortably inside less than two thirds of a packet). The frame trailer is "END" followed by CRLF. Here is a sample frame:
MSG 0 1 . 52 128
<profile uri='http://asptoday.com/beep/chessprofile' />
Note that MIME headers apply per message, not per frame – so a message that is divided into two frames will have its MIME headers at the beginning of the payload for the first frame but not in the second frame.
As different application protocols can be built based on BEEP, there is no such thing as a standard BEEP port number (unlike HTTP, with port 80). BEEP might not even be traveling over TCP (though it usually is).
Security and authentication are handled by BEEP profiles for transport security and IETF SASL. BEEP defines one transport security profile – for TLS – and it is used to encrypt the communications and to authenticate the server, and optionally to authenticate the client. BEEP defines a profile for SASL, which is a range of authentication and other services that are defined separate from any particular application protocol. SASL could be based on Kerberos, GSSAPI, one-time passwords or other configurable techniques.
One of the first questions people ask when they hear about BEEP is "why not use HTTP instead?" No one argues that HTTP is not an excellent protocol for the task it was originally designed for – to transmit hypertext and related documents. HTTP also has some capabilities to act as a substrate for other protocols – and if it matches the needs of the higher-level protocol, then it is quite acceptable to use it. It is when you stray too far from the original goals of HTTP that you begin to see issues. One clear example is asynchronous client notification – how does the server send a message to the client? HTTP was designed to have the client initiate each message exchange – so it is quite difficult, indeed awkward, to let the server initiate an exchange. (A technical whitepaper describing the possibilities is available). Another issue with HTTP is what happens if you need to send multiple messages in parallel – without having to serialize each message transmission. Or how about having multiple responses (not just HTTP's single response) to a single request. It is for these more complex, but quite necessary, message exchange patterns that BEEP shows significant advantages.
There are a number of BEEP libraries available. See Beepcore.org for descriptions of implementations for JAVA, Linux and TCL. Clipcode.com has created a product called Clipcode.Peer that offers a BEEP programmatic object model in the Microsoft .NET environment (it requires .NET beta 2). Here is a small snippet of C# code showing how it can be used to create a BEEP listener session, using an imaginary profile for a game of chess. Application developers or third party vendors could create such profiles and these can easily be integrated with BEEP applications.
. . .
BeepApplication myBeepApplication = new BeepApplication();
ChessProfileHandlerFactory chessProfileHandlerFactory =
new ChessProfileHandlerFactory ();
TcpTransportSession myTcpSession(null, 7000);
It is that simple. As remote initiator peers establish connections with this peer on port 7000, the application will respond by sending out a greeting with a list of profiles (in this case it only contains the chess profile) and remote peers to create a channel based on that profile. Additional functionality is available to enable the application to be the initiator when setting up BEEP sessions, to create channels and to send requests.
We have seen how BEEP supports many rich and flexible message exchange styles. A number of evolving IETF standards are based on BEEP. It is likely to provide the foundation for successful peer-to-peer architectures. It is an excellent protocol to carry SOAP traffic. Many custom application protocols are leveraging it. As BEEP profiles for several specialist needs are developed, you are likely to see more and more uses for BEEP.
 The homepage of the IETF BEEP Working Group:
 RFC 3080 – The BEEP Core Specification
 RFC 3081 – Mapping the BEEP Core onto TCP
 SOAP Binding to BEEP
 "On the design of application protocols" explains the rationale behind BEEP
 Beepcore.org is a community portal for those interested in BEEP issues
 The BEEP mailing list is at:
 The Clipcode.Peer product provides an implementation of BEEP on the Microsoft .NET platform.