This repository has been archived by the owner on Jun 13, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMTL.txt
412 lines (275 loc) · 16.8 KB
/
MTL.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
This document proposes a Message Transport Layer (MTL), a connection-oriented protocol that supports broker-based messaging. MTL connects a set of clients with a central message broker, allowing clients to issue commands to the broker, send messages to the broker, and receive messages back from the broker.
* Name: rfc.zeromq.org/spec:11/MTL
* Editor: Pieter Hintjens <[email protected]>
++ License
Copyright (c) 2011 the Authors.
This Specification is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
This Specification is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses>.
++ Change Process
This Specification is a free and open standard[((bibcite fandos))] and is governed by the Digital Standards Organization's Consensus-Oriented Specification System (COSS)[((bibcite coss))].
++ Language
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119[((bibcite rfc2119))].
Note that in this document we do not use the term "message" formally since the term is overloaded at several levels. The name of this specification needs to be reviewed.
++ Goals
MTL is a connection-oriented protocol that supports broker-based messaging. It connects a set of clients with a broker, allowing clients to issue commands to the broker, send content to the broker, and receive content back from the broker.
The main goals of MTL are:
* To support arbitrary messaging semantics based on extensible //profiles//.
* To provide a simple synchronous flow for commands from the client to the server.
* To provide a fast asynchronous flow for data from the client to or from the server.
* To provide authentication of clients using SASL[((bibcite sasl))].
* To provide safe forwards and backwards compatibility.
* To provide detection of errors such as dead or blocked peers.
* To provide robust error handling.
++ General Operation
MTL separates all client-server activity into two distinct flows:
* A synchronous low-volume //control flow//. The control flow is strictly request-response, where one request by the client always results in one response from the server. The server never sends a response without a request from the client. The client detects a dead or absent server using a timeout on its request socket.
* An asynchronous high-volume //data flow//. The data flow is bidirectional and asynchronous, where either client or server may send various types of frame at any time. Either client or server may use heart-beating to detect a dead peer.
The control flow carries JSON[((bibcite json))] commands. The intention is to make control content trivial to parse, extend, and debug.
The data flow carries binary-encoded commands and content. The intention is to make data content fast to decode and encode, and compact on the wire.
++ Control Flow
Control commands go over a request-reply flow from client to server. The server opens a 0MQ ROUTER socket, and binds to its well-known endpoint. The client opens a REQ socket and connects to this endpoint. The client then issues a request, and the server a response. The connection lasts forever, or until the client closes its socket, or until the server unbinds from its endpoint.
Every request from a client to the server follows this format:
* Frame 0: command name (string)
* Frame 1: request body (JSON string)
Every reply from the server to a client follows this format:
* Frame 0: status code (three digits, 2xx-5xx)
* Frame 1: reply body (JSON string)
Commands are broken into //classes//, where each class provides a set of //methods//. Each method consists of a client request and a server reply, serialized as JSON. Server replies are categorized by status code.
Command names are case-insensitive.
+++ Client Authentication
On a new connection, the client MUST first send a Connection.Open command. This requests access to a specific //virtual host// on the server:
[[code]]
Connection.Open
------------------------------------------------------------
{
"protocol": {
"name": "MTL",
"version": 1
},
"virtual-host": "test-env"
}
[[/code]]
Clients are authenticated using the SASL challenge-response model. A server MAY accept to work with unauthenticated clients. It will then reply 201 Ready:
[[code]]
201
------------------------------------------------------------
{
"status": "Ready",
"profiles": [ "profile name", "profile name",... ]
}
[[/code]]
To challenge a client, the server responds with 401 Unauthorized and specifies a list of SASL mechanisms that it accepts:
[[code]]
401
------------------------------------------------------------
{
"status": "Unauthorized",
"mechanisms": [ "mechanism name", "mechanism name",... ]
}
[[/code]]
The server MAY issue a 401 response at any time, e.g. if a client's authentication information changed, or expired. The client MUST be able to re-authenticate at any time.
To authenticate, a client sends Connection.Authorize:
[[code]]
Connection.Authorize
------------------------------------------------------------
{
"mechanism" : "mechanism name",
"response" : "BASE64-encoded blob"
}
[[/code]]
If the SASL challenge/response cycle finished, the server replies with 201 Ready. Otherwise the server responds with 402 Challenged, after which the client MUST re-send a new Connection.Authorize with new response data:
[[code]]
402
------------------------------------------------------------
{
"status": "Challenged",
"mechanism": "mechanism name",
"challenge" : "BASE64-encoded blob"
}
[[/code]]
The SASL challenge-response cycle can repeat multiple times.
+++ Selecting a Profile
To start working with a specific profile, the client issues a Connection.Profile command:
[[code]]
Connection.Profile
------------------------------------------------------------
{
"profile" : "profile name"
}
[[/code]]
The profile name must be one of the profiles specified by the server when it issued 201 Ready.
If the profile was valid, the server responds with 200 OK. If not, the server responds with 400 Bad Request.
[[code]]
200
------------------------------------------------------------
{
"status": "OK"
}
[[/code]]
Profile names are case-insensitive.
Each profile defines a set of classes that the client can use to work with server-side resources. A "test" profile is defined later in this document.
+++ Requesting a Data Lease
A data flow can either read from a set of resources, or write to a set of resources. To open a data flow, the client requests a "lease", using either the Connection.Reader or Connection.Writer command:
[[code]]
Connection.Reader
------------------------------------------------------------
{
"resources": [ "resource name", "resource name", ...],
"confirm": "none | full"
}
[[/code]]
[[code]]
Connection.Writer
------------------------------------------------------------
{
"resources": [ "resource name", "resource name", ...],
"confirm": "none | full"
}
[[/code]]
The client MUST have already selected a profile before making a Connection.Reader or Connection.Writer request.
The resources list specifies which resources the request applies to. An empty list means "any and all resources on the server".
The "confirm" field specifies whether messages are confirmed or not. If the server accepts the Connection.Reader or Connection.Writer request it responds with a 202 Data Lease:
[[code]]
202
------------------------------------------------------------
{
"status": "Data Lease",
"port": port number
"lease" : "data lease"
}
[[/code]]
If the profile does not support the requested confirmation model, the server MUST respond with a 501 Not Implemented:
[[code]]
501
------------------------------------------------------------
{
"status": "Not implemented"
}
[[/code]]
+++ Control Flow Error Handling
The server SHOULD silently drop ill-formed requests, that is, requests with the wrong number of frames, or with content that is not valid JSON. The server MUST respond to well-formed requests that are invalid for any reason with a suitable error reply.
++ Data Flow
Data commands go over an asynchronous bidirectional flow between client to server. The server opens a 0MQ ROUTER socket and binds it to a port, which it communicates to the client in a 202 reply. The client opens a DEALER socket and connects to the server endpoint, using this port. The client and server can then issue data commands. The connection lasts forever, or until the client closes its socket, or until the server unbinds from its endpoint.
The server MAY handle data flows on the same socket as control flows, or it MAY open separate sockets for data flows.
+++ Data Command Encoding
Every data command follows this format:
* Frame 0: header (binary encoded)
* Frame 1: body (binary content)
The header frame is encoded thus:
* 1-byte command type
* Optional fields
Depending on the command type, the command type is followed by zero or more optional fields, whose encoding and meaning are specified per command type.
+++ Initializing a Data Flow
When a client has opened a data connection it must send a Lease command as follows:
* Type = 0x01, Lease
* Field 1: command sequence (integer)
* Field 2: data lease provided by server 202 response (short string)
* Body: unused
The server MUST reply with a Response command that echoes the command sequence used by the client, as follows:
* Type = 0x02, Response
* Field 1: command sequence (integer)
* Body: three-digit response code
Where the response code can be:
* "200" - the lease was successful
* "403" - the lease was forbidden
The purpose of the command sequence in this and other commands is to allow the client to pipeline commands, i.e. to send multiple commands without waiting for the response to each. The server MAY return Response commands in any order.
+++ Summoning a Resource
To start receiving content from a resource, the client sends a Summon command as follows:
* Type = 0x03, Summon
* Field 1: command sequence (integer)
* Field 2: resource name (short string)
* Body: unused
Where the resource name MUST be one of the resources specified by the Connection.Reader request for this data lease. The client MAY NOT summon the same resource twice without an intervening dismiss.
The server MUST reply with a Response command, where the response code can be:
* "200" - the Summon command was successful
* "400" - the resource cannot be summoned.
Following a successful Summon command, the server-side resource MAY send Content commands to the client.
+++ Dismissing a Resource
To stop receiving content from a resource, the client sends a Dismiss command as follows:
* Type = 0x04, Dismiss
* Field 1: command sequence (integer)
* Field 2: resource name (short string)
* Body: unused
Where the resource name MUST be one of the resources specified by the Connection.Reader request for this data lease. The client MAY NOT dismiss the same resource twice without an intervening summon.
The server MUST reply with a Response command, where the response code can be:
* "200" - the Consume command was successful
* "400" - the resource cannot be dismissed.
Following a successful Dismiss command, the server-side resource MUST NOT send further Contents to the client.
+++ Sending Content to a Resource
To send content to a resource, the client sends a Content command as follows:
* Type = 0x05, Content
* Field 1: content sequence (integer)
* Field 2: resource name (short string), may be empty
* Field 3: properties (field table)
* Body: opaque binary content
If the Connection.Writer request specified more than one resource, then the resource name is required.
+++ Receiving Content from a Resource
When a resource has content to send to a client, the server sends a Content command as follows:
* Type = 0x05, Content
* Field 1: content sequence (integer)
* Field 2: resource name (short string), may be empty
* Field 3: properties (field table)
* Body: opaque binary content
The server MUST send the Response to a Summon command before any Content from that resource, and the server MUST NOT send any Content from a resource after a successful Response to a Dismiss command. If the Connection.Reader request specified more than one resource, then the resource name is required.
+++ Content Confirmation
All Content commands in one direction on a data flow are either confirmed, or not confirmed, depending on the "confirm" value specified in the corresponding Connection.Reader or Connection.Writer:
* "none" - Content commands are not confirmed.
* "full" - Content commands are confirmed.
The confirmation works as follows:
* One peer sends one or more Content commands.
* The recipient confirms safe receipt of one or more Content commands with a Confirm command.
* The recipient rejects one or more Content commands with a Reject command.
The Confirm command has this format:
* Type = 0x06, Confirm
* Field 1: content sequence (integer)
* Field 2: multiple (Boolean)
* Body: unused
If the 'multiple' field is TRUE, the Confirm command covers all Contents up to and including the specified content sequence. If the 'multiple' field is FALSE, the Confirm covers exactly one Content.
There is no response to a Confirm command. Invalid Confirm commands are ignored silently.
The Reject command has this format:
* Type = 0x07, Reject
* Field 1: content sequence (integer)
* Field 2: multiple (Boolean)
* Field 3: recycle (Boolean)
* Body: unused
If the 'multiple' field is TRUE, the Reject command covers all Contents up to and including the specified content sequence. If the 'multiple' field is FALSE, the Reject covers exactly one Content.
if the 'recycle' field is TRUE, the Content will be resent using a heuristic that depends on the profile.
There is no response to a Reject command. Invalid Reject commands are ignored silently.
+++ Heartbeating
The client or server may heartbeat an otherwise silent data connection by sending Ping commands:
* Type = 0x08, Ping
* Body: unused
The recipient of a Ping command should respond with a Pong command:
* Type = 0x09, Pong
* Body: unused
A client or server SHOULD send Ping commands when it is not otherwise sending commands. The frequency of Ping commands should be configurable.
A client or server SHOULD consider its peer "disconnected" if no Pong arrives within some specific time period.
+++ Field Encodings
These are the possible field encodings:
* Short string: a single byte followed by 0 to 255 bytes of printable characters.
* Integer: an eight-byte (64-bit) unsigned value represented in network byte order.
* Shortint: a two-byte (16-bit) unsigned value represented in network byte order.
* Boolean: a single byte with the possible values 0 (FALSE) or 1 (TRUE).
* Field table: to be defined.
+++ Data Flow Error Handling
The server SHOULD silently drop ill-formed requests, that is, requests with the wrong number of frames, or with content that is not valid. The server MUST respond to well-formed requests that are invalid for any reason with a suitable error reply.
++ Request and Reply Routing
Servers MUST use ROUTER sockets. From the ØMQ Reference Manual[((bibcite zmqsocket))]:
> When receiving messages a ROUTER socket shall prepend a message part containing the identity of the originating peer to the message before passing it to the application. When sending messages a ROUTER socket shall remove the first part of the message and use it to determine the identity of the peer the message shall be routed to.
This extra frame is ignored in this discussion.
++ The Test Profile
The "test" profile defines the following routing and queuing semantics for content:
* The server provides exactly one resource, called "resource".
* Content commands are never confirmed.
* Content is fanned-out (duplicated) from all writers to all readers.
The server and the client MAY implement the test profile.
++ References
[[bibliography]]
: rfc2119 : "Key words for use in RFCs to Indicate Requirement Levels" - [http://tools.ietf.org/html/rfc2119 ietf.org]
: fandos : "Definition of a Free and Open Standard" - [http://www.digistan.org/open-standard:definition digistan.org]
: coss : "Consensus Oriented Specification System" - [http://www.digistan.org/spec:1/COSS digistan.org]
: sasl : "RFC 2222 - Simple Authentication and Security Layer (SASL)" - [http://www.faqs.org/rfcs/rfc2222.html faqs.org]
: json : "The application/json Media Type for JavaScript Object Notation (JSON)" [http://tools.ietf.org/html/rfc4627 ietf.org]
: zmqsocket : "zmq_socket(3)" [http://api.zeromq.org/master:zmq-socket zeromq.org]
[[/bibliography]]