The purpose of this protocol is to provide a wire format for implementing a binary request/response communication interface, such as that of the Jini ERInet.jini.jeri.connection.ConnectionManager
net.jini.jeri.connection.ServerConnectionManager
net.jini.jeri.tcp.TcpEndpoint
net.jini.jeri.tcp.TcpServerEndpoint
net.jini.jeri.ssl.SslEndpoint
net.jini.jeri.ssl.SslServerEndpoint
net.jini.jeri.kerberos.KerberosEndpoint
net.jini.jeri.kerberos.KerberosServerEndpoint
OutboundRequest
and InboundRequest
interfaces, on top of a bi-directional byte stream connection.
The intended application of this protocol is to communicate Jini ERI
remote method invocations over TCP and similar connection-oriented
transport protocols, as well as over layered application-level
protocols that can provide a connection-oriented byte stream
interface.
OutboundRequest
and InboundRequest
interfaces
Items in the protocol are of the following simple types:
The client may use the connection to send requests to the server and receive responses in reply. The server may use the connection to receive requests and send responses in reply. (Note that the terms "client" and "server" in this page are only used as convenient labels to distinguish the two endpoints of the asymmetric connection over which this protocol operates; they do not necessarily correspond to higher-level application concepts of "client" and "server".)
How the connection is established is outside the scope of this protocol. A typical model, however, is for the server to passively listen on a network address for incoming connections and to publish that address to clients, and for the client to actively attempt to connect to the server at the published address; if the server accepts the connection, this protocol may then commence over the established connection.
A message comprises a four-byte header optionally followed by more data, depending on the type of the message. The first byte of the message header defines the type of the message. Message types fall into two general categories: messages that pertain to the connection as a whole, which begin with a byte in the range 0-0xF, and messages that pertain to a particular session, which begin with a byte in the range 0x10-0xFF.
The following table lists the allowed ranges of values for the first byte of a message header, and what message type each range corresponds to. The value ranges are listed as both bit patterns, in which x represents a bit that may be either 0 or 1 for the given message type, and in hexadecimal, in which two hyphen-separated values indicate an inclusive range. Some of the hexadecimal ranges include more values than are legally allowed for the given message type, but the bit pattern range specifies the allowed values exactly.
It is a protocol violation to send a message with a first byte that does not match one of the above bit patterns.
bit pattern hexadecimal range message type 00000000 00 NoOperation 00000010 02 Shutdown 00000100 04 Ping 00000110 06 PingAck 00001000 08 Error 0001xxx0 10-1F IncrementRation 001000x0 20-23 Abort 00110000 30 Close 01000000 40 Acknowledgment 100xxxx0 80-9F Data
A session may be either established or terminated with respect to either endpoint. A session established with respect to an endpoint may also be finished with respect to that endpoint, meaning that the endpoint is finished sending data for that session. These and other session state changes occur as a result of messages sent for the associated session identifier.
For any transmitted message that affects the state of a session, the state change is clearly known first to the sender of the message (when the message is sent), and later to the receiver (when the message is received). All restrictions on what messages may be sent relating to the current state of a session require that there is some interleaved order of messages received and messages sent by a given endpoint for which the restrictions are satisfied.
A session is established with respect to both endpoints when the client sends a Data message with the open flag set. The newly established session is associated with the session identifier contained in the message header. A session remains established with respect to a given endpoint until it becomes terminated with respect to that endpoint.
An established session is finished with respect to a given endpoint after the endpoint has sent a Data message with the eof flag set for the associated session identifier. A session finished with respect to a given endpoint still remains established with respect to that endpoint (and data still can be received) until it becomes terminated with respect to the endpoint. Note that a session can become both established and finished from a single Data message sent from the client, if both the open and the eof flags are set.
The client may re-use a session identifier for establishing a new session after the previous session associated with that session identifier is terminated with respect to the client and the server, or after it is terminated with respect to the server and the client has sent a Data message with the eof flag set with the session identifier (after which the previous session associated with the session identifier becomes implicitly terminated with respect to the client).
Each endpoint has two state values associated with each session:
When a session is first established, the client's inbound ration is the value that the client sent in the ClientConnectionHeader for the connection, and the client's outbound ration is the value that the server sent in the ServerConnectionHeader for the connection (although it will likely be immediately decremented by the length value of the Data message used to establish the session). Also, the server's outbound ration is the value that the client sent in the ClientConnectionHeader for the connection, and the server's inbound ration is the value that the server sent in the ServerConnectionHeader for the connection (although it will likely be immediately decremented by the length value of the Data message used to establish the session).
An endpoint's outbound ration for a session is incremented when it receives an IncrementRation message for that session with a non-zero increment, and it is decremented when it sends a Data message for that session with a non-zero length. An endpoint's inbound ration for a session is incremented when it sends an IncrementRation message for that session with a non-zero increment, and it is decremented when it receives a Data message for that session with a non-zero length. It is a protocol violation for an endpoint to send a Data message with a length value greater than its current outbound ration.
The sequence of messages sent by the server ends with a Shutdown message, an Error message, or closure of the connection's stream from the server. The sequence of messages sent by the client ends with an Error message or closure of the connection's stream from the client.
initialRation: 16-bit integerA ClientConnectionHeader message must and must only be sent by the client, as the first message of this protocol over the connection.
For all newly established sessions, the client's initial inbound ration and the server's initial outbound ration will be (initialRation * 256) if initialRation is non-zero, or infinity if initialRation is zero.
(If the server receives an invalid ClientConnectionHeader message, the server should respond with an Error message following the ServerConnectionHeader message.)
The structure of a ClientConnectionHeader message is 8 bytes as follows:
offset bit pattern content 0 to 3 01001010
01101101
01110101
01111000
magic number (ASCII "Jmux") 4 00000001
version 5 to 6 xxxxxxxx
xxxxxxxx
initialRation 7 00000000
reserved
initialRation: 16-bit integerA ServerConnectionHeader message must and must only be sent by the server, as the first message of this protocol over the connection.
For all newly established sessions, the server's initial inbound ration and the client's initial outbound ration will be (initialRation * 256) if initialRation is non-zero, or infinity if initialRation is zero.
The structure of a ServerConnectionHeader message is 8 bytes as follows:
offset bit pattern content 0 to 3 01001010
01101101
01110101
01111000
magic number (ASCII "Jmux") 4 00000001
version 5 to 6 xxxxxxxx
xxxxxxxx
initialRation 7 00000000
reserved
length: 16-bit integerA NoOperation message may be sent by the client or the server. A NoOperation message should be ignored by the receiver.
data: sequence of length bytes
The structure of a NoOperation message is (4+length) bytes as follows:
offset bit pattern content 0 00000000
NoOperation message type identifier 1 00000000
reserved 2 to 3 xxxxxxxx
xxxxxxxx
length 4 to (4+length-1) n/a data
A Shutdown message contains the following variable items:
length: 16-bit integerThe Shutdown message is used to indicate that the server is shutting down the connection in a graceful fashion.
detail: sequence of length bytes
A Shutdown message must only be sent by the server.
By definition, a Shutdown message is the last message of the protocol sent by the server over the connection; after sending a Shutdown message, the server will typically close the connection.
When the client receives a Shutdown message, it should discard the connection and consider all established sessions that were not finished with respect to the server as if they have been aborted (as with an Abort message) with no partial processing-- thus the client can safely retry such sessions on another connection without violating at most once execution semantics. Therefore, the server must only send a Shutdown message if it can guarantee that no currently established sessions have been processed with any possible side effects.
The server can use the detail item to provide the client with more information explaining the reason for the Shutdown message. The content of the detail item, if any, is a UTF-8 encoded string of unspecified content.
The structure of a Shutdown message is (4+length) bytes as follows:
offset bit pattern content 0 00000010
Shutdown message type identifier 1 00000000
reserved 2 to 3 xxxxxxxx
xxxxxxxx
length 4 to (4+length-1) n/a detail
A Ping message contains the following variable items:
cookie: 16-bit integerThe Ping message is used to test the liveness of the receiver.
A Ping message may be sent by the client or the server.
The sender may choose any arbitrary value for cookie. After sending a Ping message, the sender can expect the receiver to respond with exactly one corresponding PingAck message containing the same cookie value. The sender may expect the corresponding PingAck within a reasonable timeout, and if it is not received, the sender may consider the receiver to have gone down or become unreachable (such as due to a network partition), in which case it should discard the connection and consider all open sessions aborted (with partial processing, if the sender is the client).
The structure of a Ping message is 4 bytes as follows:
offset bit pattern content 0 00000100
Ping message type identifier 1 00000000
reserved 2 to 3 xxxxxxxx
xxxxxxxx
cookie
cookie: 16-bit integerThe PingAck message is used to respond to a Ping message.
A PingAck message may be sent by the client or the server, and must only be sent in response to exactly one previous Ping message received by the sender.
After receiving a Ping message with a given cookie value, an endpoint should immediately respond with a PingAck message with the same cookie value.
The structure of a PingAck message is 4 bytes as follows:
offset bit pattern content 0 00000110
PingAck message type identifier 1 00000000
reserved 2 to 3 xxxxxxxx
xxxxxxxx
cookie
length: 16-bit integerThe Error message is used to indicate that the sender has detected a protocol violation somewhere in the messages that it has received.
detail: sequence of length bytes
An Error message may be sent by the client or the server.
By definition, an Error message is the last message of the protocol sent by the sender over the connection; after sending an Error message, the sender will typically close the connection.
When the client receives an Error message, it should discard the connection and consider all established sessions that were not finished with respect to the server as if they have been aborted (as with an Abort message) with possible partial processing-- thus the client cannot safely retry such sessions on another connection without violating at most once execution semantics.
When the server receives an Error message, it should discard the connection and consider all established sessions as if they have been aborted.
The sender can use the detail item to provide the receiver with more information explaining the reason for the Error message. The content of the detail item, if any, is a UTF-8 encoded string of unspecified content.
The structure of an Error message is (4+length) bytes as follows:
offset bit pattern content 0 00001000
Error message type identifier 1 00000000
reserved 2 to 3 xxxxxxxx
xxxxxxxx
length 4 to (4+length-1) n/a detail
shift: 3-bit integerThe IncrementRation message is used to indicate that more data can be received by the sender for a given session.
sessionID: 7-bit integer
increment: 16-bit integer
An IncrementRation message may be sent by the client or the server. The sessionID must identify a session established with respect to the sender. (In other words, the client must not send an IncrementRation message after sending an Abort message for the given session, and the server must not send an IncrementMessage after sending a Close or an Abort message for the given session.)
An IncrementRation message indicates that the sender is prepared to receive (increment<<(shift*2)) more bytes for the session beyond its current inbound ration for the session identified by sessionID. After sending an IncrementRation message, the sender's inbound ration for the session is incremented by (increment<<(shift*2)), and after receiving an IncrementRation message, the receiver's outbound ration is incremented by (increment<<(shift*2)). It is a protocol violation for an IncrementRation message to cause the sender's inbound ration to exceed 0x7FFFFFFF. (Therefore, if the receiver's outbound ration is caused to exceed 0x7FFFFFFF, the receiver should respond with an Error message.)
If the session is finished (or terminated) with respect to the receiver, this message should be ignored.
For a given session, if an endpoint is expecting more data from the other endpoint but its inbound ration is zero, then it must send an IncrementRation message (with a non-zero increment) for that session.
The structure of an IncrementRation message is 4 bytes as follows:
offset bit pattern content 0 0001----
IncrementRation message type identifier 0 ----xxx-
shift 0 -------0
reserved 1 0-------
reserved 1 -xxxxxxx
sessionID 2 to 3 xxxxxxxx
xxxxxxxx
increment
partial: flagThe Abort message is used to terminate a session abruptly, usually before its expected exchange of data has completed.
sessionID: 7-bit integer
length: 16-bit integer
detail: sequence of length bytes
An Abort message may be sent by the client or the server. The partial flag must only be set when the sender is the server. The sessionID must identify a session established with respect to the sender.
An Abort message causes the session to be terminated with respect to the sender; the sender must not send any further messages for the session.
If the session is not yet terminated with respect to the receiver, then the receiver should cease sending messages for the session, except to respond in a timely fashion with an Abort message for the session so that it will be terminated with respect to the receiver.
If the client receives an Abort message with the partial flag set, then it must assume that any data sent over the session has been at least partially processed with any possible side effects-- thus the client cannot safely retry the session again without violating at most once execution semantics. If the client receives an Abort message with the partial flag not set, then it may assume that no data sent over the session has been even partially executed with any possible side effects-- thus the client can safely retry the session again without violating at most once execution semantics. Therefore, the server must only send an Abort message with the partial flag not set if it can guarantee that no amount of the data received for the session has been processed with any possible side effects.
The sender can use the detail item to provide the receiver with more information explaining the reason for the Abort message. The content of the detail item, if any, is a UTF-8 encoded string of unspecified content.
The structure of an Abort message is (4+length) bytes as follows:
offset bit pattern content 0 001000--
Abort message type identifier 0 ------x-
partial 0 -------0
reserved 1 0-------
reserved 1 -xxxxxxx
sessionID 2 to 3 xxxxxxxx
xxxxxxxx
length 4 to (4+length-1) n/a detail
sessionID: 7-bit integerThe Close message is used to indicate that the server is done with a particular session in the normal fashion.
A Close message must only be sent by the server. The sessionID must identify a session finished (but established) with respect to the server.
A Close message causes the session to be terminated with respect to the server; the server must not send any further messages for the session.
The server should send a Close message in a timely fashion after the session is finished with respect to the server and either finished with respect to the client or the server is not interested in the remainder of the request data, so that the client may reuse the session identifier. When possible, the server should use the abbreviated form of the Close message: the close flag of the Data message.
If the session is finished (or terminated) with respect to the client, then after receipt of a Close message for the session, the client may reuse the session identifier.
If the session is not yet terminated with respect to the client, then the client should cease sending messages for the session, except to respond in a timely fashion with an Abort message for the session so that it will be terminated with respect to the client as well, and then the client may reuse the session identifier. Note that in this case, the client must not consider the session to have failed; instead, it must provide the data received as the complete response, and it should consider that the server is not interested in the remainder of the request data, so it should be silently discarded.
The structure of a Close message is 4 bytes as follows:
offset bit pattern content 0 00110000
Close message type identifier 1 0-------
reserved 1 -xxxxxxx
sessionID 2 to 3 00000000
00000000
reserved
sessionID: 7-bit integerThe Acknowledgment message is used to indicate that the client is done processing the complete response data for a particular session.
An Acknowledgment message must only be sent by the client. The sessionID must identify a session established with respect to the client. An Acknowledgment must only be sent after the server has sent a Data message with the ackRequired flag set for the session, and it must only be sent once for the session.
Upon receipt of an Acknowledgment message, the server may consider that the client has finished processing the response.
The structure of an Acknowledgment message is 4 bytes as follows:
offset bit pattern content 0 01000000
Acknowledgment message type identifier 1 0-------
reserved 1 -xxxxxxx
sessionID 2 to 3 00000000
00000000
reserved
open: flagThe Data message is used by the client to establish a session, by the client or the server to transmit fragments of data for a session and to signal the end of data for a session, and by the server to terminate the session and to request an acknowledgment for complete processing of the data sent.
eof: flag
close: flag
ackRequired: flag
sessionID: 7-bit integer
length: 16-bit integer
data: sequence of length bytes
A Data message may be sent by the client or the server. The open flag must only be set when the sender is the client, and the close and ackRequired flags must only be set when the sender is the server. The close and the ackRequired flags must only be set if the eof flag is also set.
If the open flag is not set, then sessionID must identify a session established and not finished with respect to the sender. If the open flag is set, then sessionID must not identify an established session, and a new session is established associated with the session identifier sessionID.
The data of the message represents the next fragment of data that constitutes the request data (if sent by the client) or the response data (if sent by the server) of the session. It is a protocol violation for an endpoint to send a Data message with a length value greater than its current outbound ration for the session. (Therefore, if the receiver's inbound ration is less than length, the receiver should respond with an Error message.) After sending a Data message, the sender's outbound ration is decremented by length, and after receiving a Data message, the receiver's inbound ration is decremented by length.
The eof flag marks this message as containing the last fragment of data for the session, and thus the request or response data has been completely transmitted and the session is finished with respect to the sender.
The meaning of the close flag being set is equivalent to the meaning of the same Data message sent without the close flag being set immediately followed by a Close message with the same sessionID.
The ackRequired flag indicates that the server is interested in being notified with a positive acknowledgment when the client is done processing the response data for the session. Such a positive acknowledgment takes the form of an Acknowledgment message received from the client with the same sessionID. If instead the server receives an Abort message with the same sessionID, or the server receives a Data message with the open flag set and the same sessionID, or the connection is closed, then that constitutes a negative acknowledgment (as a positive acknowledgment could never be received).
After the client has received a Data message with the ackRequired flag set, it should send an Acknowledgment message with the same sessionID in a timely fashion after it is done processing the response data.
The structure of a Data message is (4+length) bytes as follows:
offset bit pattern content 0 100-----
Data message type identifier 0 ---x----
open 0 ----x---
close 0 -----x--
eof 0 ------x-
ackRequired 0 -------0
reserved 1 0-------
reserved 1 -xxxxxxx
sessionID 2 to 3 xxxxxxxx
xxxxxxxx
length 4 to (4+length-1) n/a data