ITMP

Part 0: Overview

0.1 Introduction

The Internet of Thinks Messaging Protocol is open Internet protocol for inter thinks messaging. ITMP consist of three important components: discovering, remote procedure calling, messaging (pub-sub), in comparing with competitors ITMP is compact, simple, extensible, robust protocol.

0.1.1 Terminology

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this specification are to be interpreted as described in IETF
RFC2119.

0.2 Conformance

ITMP defines a wire level protocol. ITMP does not define a wire-level distinction between "clients" and "servers", the protocol is symmetric. It is expected and encouraged that implementations of ITMP will have different capabilities.

A conformant implementation MAY perform protocol negotiation, and then parse, process, and produce frames in accordance with the format and semantics.

Conformant implementations MUST NOT require the use of any extensions defined outside this document in order to interoperate with any other conformant implementation.

Part 1 of this document defines the type system and type encodings that every conformant implementation MUST implement.

Part 2 defines the peer-to-peer transport protocol which operates over TCP and UDP or Serial Line. Every conformant implementation of TMP over TCP MUST implement Part 2. Part 2 admits behaviors that might not be appropriate for every implementation. For example a “client library” might not allow for its communication partner to spontaneously attempt to initiate a connection and request messages. Where an implementation does not allow for a behavior the implementation MUST respond according to the rules defined within Part 2 of the specification.

Part 3 of this document defines the ITMP Messaging Layer. Every conformant implementation which processes messages MUST implement this part of the specification. Some implementations might not process messages (for example, an implementation acting as a “router” which looks only at the routing information carried by the ITMP Transport layer). Such implementations do not actively implement Part 3, but MUST NOT act in ways which violate the rules of this part of the specification. The Messaging layer admits behaviors that might not be appropriate for all implementations (and within an implementation all behaviors might not be available for all configurations). Where a behavior is not admitted, the implementation MUST respond according to the rules defined within this specification.

Part 4 defines the requirements for transactional messaging. Transactional messaging defines two roles, that of the transactional resource and that of the transaction controller. A conformant implementation SHOULD be capable of operating in one of these roles but MAY be unable to operate in either (for instance a simplistic client library might have no ability to act as a transaction controller and would not be expected to act as a transactional resource).

It is RECOMMENDED that implementations designed to act as messaging intermediaries support the ability to act as a transactional resource. It is RECOMMENDED that implementations or re-usable libraries provide Application Programming Interfaces to enable them to act as transactional controllers. Where a behavior is not admitted, the rules defined in part 4 regarding responses to non-admitted behaviors MUST be followed.

Part 5 defines Security Layers to provide an authenticated and/or encrypted transport. Implementations SHOULD allow the configuration of appropriate levels of security for the domain in which they are to be deployed. Conformant implementations acting in the TCP server role are strongly RECOMMENDED to implement Part 5: section 5.2 (or Part 5: 5.2.1 Alternative Establishment). Implementations acting in the TCP server role are strongly RECOMMENDED to implement Part 5: section 5.3 and to support commonly used SASL mechanisms. In particular such implementations SHOULD support the PLAIN [RFC4616] and SCRAM-SHA1 [RFC5802] mechanisms.  Conformant implementations acting in the TCP client role SHOULD be capable of being configured to connect to an implementation in the TCP server role that is following the recommendations above.

Part 1: Types

1.1 Type System

The ITMP based mostly on JSON format and CBOR encoding and type system followed by those definition for interoperable data representation. ITMP values can be annotated with CBOR extension.

1.1.1 Primitive Types

The ITMP type system defines a standard set of primitive types for representing both common scalar values and common collections. The scalar types include booleans, integer numbers, floating point numbers, strings and binary data. The collection types include arrays(polymorphic), and maps.

1.2 Type Encodings

An ITMP uses JSON strings or CBOR binary encoded messages.

Part 2: Transport

2.1 Transport

2.1.1 Conceptual Model

An ITMP network consists of nodes connected via links. Nodes act as agents and can realize one or more roles. Actor is a node that implements RPC functions. Publisher is a node that produces events. Subscriber is a node that can receive events messages and react for its in some manner. Broker is a node that act as Subscriber for all Connected Publishers act as Publisher for Subscribers and connect one another.

2.1.2 Protocol Frames

The protocol consists of messages of frames all of them has same structure.

[<message type>,<id>,<name>,<parameters>,<options>]

where <message type> - integer number from 0 - 23 described int table 2.1

<id> - integer number initially chosen randomly and then increments any time new message sending. It prevent of messages doubles and allow correlate answer to question.

<name> - string denotes procedure to call or event name to emit or subscribe

<parameters> - array of function or event parameters or map of named values instead of position dependent values stored in array, can be committed if empty

<options> - map of named values extend parameters of calling method, can be committed if empty

 

  

Connection
0 [CONNECT,0,"ITMP10"] opened connection and make version negotiation
1 [CONNECTED,0,"ITMP10"] confirm connection and start communication
2 [ABORT,0,"",[503,"time out"]] terminate connection
3 [DISCONNECT,0,"",[503,"time out"]]  
Description
4 [GETDESCR,id,"name"] 6 - get description
5 [DESCR,id,"name",["name&int"]] 7 - description response
6 [DESCRERR,id,"name",[404,"not found"]] 8 - get - description error
     
RPC
8 [CALL,id,"name",[1,2]] 9 - call
9 [CALLCANCEL,id,"name"] 10 call cancel
10 [CALLRESP,id,"name",["ok","result"]] 11 - call response
     
12 [PROGRESS,id,"name",[2,"almost done"]] 12 call in progress
13 [CALLERR,id,"name",[503,"time out"]] 13 - call error
14    
15    
publish
16 [EVENT,id,"alarm",[32,"12:33"]] 14 - event
17 [EVENT_WITH_ACK,id,"alarm",[32,"12:33"]] 15 - event with acknowledge awaiting
18 [EVENTACK,id,"alarm"] 15 - event acknowledged
19 [EVENTNAK,id,"alarm",[500,"server busy"]] 16 - event not acknowledged
subscribe
20 [SUBSCRIBE,id,"alarm"] 17 - subscribe
21 [UNSUBSCRIB,id,"alarm"] 20 - unsibscribe
22 [CONFIRMED,id,"alarm",[503,"no memory"]] 18 - subscription confirmed19 - subscription not confirmed
23 [NOT CONFIRMED,id,"*",[503,"no memory"]]  
 
23 [KEEP_ALIVE,id,""] 23 - keep alive
     
     
     
     
     
     
     

 

2.2 Version Negotiation

Prior to sending any frames on a connection, each peer MAY start by sending a protocol header that indicates the protocol version used on the connection. In total this is an CONNECT message:

JSON: [CONNECT, 0, "ITMP10"]

CBOR: 83  00  00  66 49 54 4d 50 31 30 // 10 bytes

Any data appearing beyond the protocol header MUST match the version indicated by the protocol header. If the incoming and outgoing protocol headers do not match, both peers MUST close their outgoing stream and SHOULD read the incoming stream until it is terminated.

The ITMP peer which acted in the role of the TCP client (i.e. the peer that actively opened the connection) MUST immediately send its outgoing protocol header on establishment of the TCP connection. The ITMP peer which acted in the role of the TCP server MAY elect to wait until receiving the incoming protocol header before sending its own outgoing protocol header. This permits a multi protocol server implementation to choose the correct protocol version to fit each client.

Two ITMP peers agree on a protocol version as follows (where the words “client” and “server” refer to the roles being played by the peers at the TCP connection level):

 When the client opens a new socket connection to a server, it MUST send a protocol header with the client’s preferred protocol version.
 If the requested protocol version is supported, the server MUST send its own protocol header with the requested version to the socket, and then proceed according to the protocol definition.
 If the requested protocol version is not supported, the server MUST send a protocol header with a supported protocol version and then close the socket.
 When choosing a protocol version to respond with, the server SHOULD choose the highest supported version that is less than or equal to the requested version. If no such version exists, the server SHOULD
respond with the highest supported version.

PART 3. Messaging

3.1 Connect

3.1.1.  CONNECT

Sent by a Client to initiate opening of a ITMP session to a Router attaching to a Realm.

       [CONNECT, Realm|uri, Options|dict]

3.1.2.  CONNECTED

   Sent by a Server to accept a Client.  The ITMP session is now open.

       [CONNECTED, Session|id, Options|dict]

3.1.3.  ABORT

   Sent by a Peer*to abort the opening of a ITMP session.  No response is expected.

       [ABORT, Reason|uri, Options|dict]

3.1.4.  DISCONNECT

   Sent by a Peer to close a previously opened ITMP session.  Must be echo'ed by the receiving Peer.

       [DISCONNECT, Reason|uri, Options|dict]

 

 

6.4.1.5.  ERROR

   Error reply sent by a Peer as an error response to different kinds of
   requests.

       [ERROR, REQUEST.Type|int, REQUEST.Request|id, Details|dict,
           Error|uri]

       [ERROR, REQUEST.Type|int, REQUEST.Request|id, Details|dict,
           Error|uri, Arguments|list]

       [ERROR, REQUEST.Type|int, REQUEST.Request|id, Details|dict,
           Error|uri, Arguments|list, ArgumentsKw|dict]

If the server cannot parse the protocol header, the server MUST send a valid protocol header with a supported protocol version and then close the socket.
Note that if the server only supports a single protocol version, it is consistent with the above rules for the server to send its protocol header prior to receiving anything from the client and to subsequently close the socket if the client’s protocol header does not match the server’s.

Based on this behavior a client can discover which protocol versions a server supports by attempting to connect with its highest supported version and reconnecting with a version less than or equal to the version received back from the server.

 

3.2 Description

3.2.1.  GETDESCR

Sent by a Client to get information about method, event or whole node.

       [GETDESCR, id|int, name|uri, Options|dict]

3.2.2.  DESCR

   Sent by a Node to inform about event or function.

       [DESCR, id|int, name|uri, [description|string] Options|dict]


<field description> ::= <name><description><signature>
<name> ::= string
<signature> ::= <interface> | <func> | <event> | <container>
<interface> ::= ’:’ [ <interface name> [ , <interface name> ] ]
<interface name> ::= string
<container> ::= ’*’ [ <interface name> [ , <interface name> ] ]
<func> ::= ’&’ <return type list> [ ‘(‘ <argument type list> ’)’ ]
<event> ::= ’!’ <type list>
<return type list> ::= <type list>
<argument type list> ::= <type list>
<type list> ::= [ <type> [ , <type> ] ]
<type> ::= <simple type> | '['<type list>']' | '{' <prop name> [ '?' ] : <type> [ , <prop name> : <type> ] '}'
<simple type> ::= <type char> [<description>]
<description>::='’' [<name>] [<version>] [<UniqueId>] [<units>] [<variants>] [<manufacturer>] '’'
<version>::=’%’ string
<UniqueId>::=’#’ string
<units> ::= '$' string
<variants> ::= '<' <value> [ , <value> ] '>'
<manufacturer> ::= '@' string
<type char> ::= i | s | b | f | B | N | Q | I | U | X | T | F | D | S

simple type JSON and CBOR encoded

i integer
s  UTF-8 string
b boolean
f  floating point number

fixed types JSON BASE64 string or CBOR byte array encoded as sequence (for small controllers without complex encoders)

B  8-bit unsigned integer (byte)
N  16-bit signed integer
Q  16-bit unsigned integer
I  32-bit signed integer
U  32-bit unsigned integer
X  64-bit signed integer
T  64-bit unsigned integer
F  single-precision floating point (IEEE 754)
D  double-precision floating point (IEEE 754)
S  UTF-8 string with length prefix

any sequence of primitive typed values encoded as byte array or base64 encoded string for json

3.3 Call

 

 

3.4 Subscribe

 

 

3.4 Publish

 

 

3.5 Keep alive

 

 

 

 

TCP Client TCP Server
======================================================
AMQP%d0.1.0.0 ------------->
<------------- AMQP%d0.1.0.0 (1)
... *proceed*
AMQP%d0.1.1.0 ------------->
<------------- AMQP%d0.1.0.0 (2)
*TCP CLOSE*
HTTP ------------->
<------------- AMQP%d0.1.0.0 (3)
*TCP CLOSE*
------------------------------------------------------
(1) Server accepts connection for: AMQP, protocol=0,
major=1, minor=0, revision=0
(2) Server rejects connection for: AMQP, protocol=0,
major=1, minor=1, revision=0, Server responds
that it supports: AMQP, protocol=0, major=1,
minor=0, revision=0
(3) Server rejects connection for: HTTP. Server
responds it supports: AMQP, protocol=0, major=1,
minor=0, revision=0
Figure 2.12: Version Negotiation Examples
Please note that the above examples use the literal notation defined in RFC 2234 [RFC2234] for non alphanumeric
values.
The protocol id is not a part of the protocol version and thus the rule above regarding the highest supported
version does not apply. A client might request use of a protocol id that is unacceptable to a server - for example,
it might request a raw AMQP connection when the server is configured to require a TLS or SASL security layer
(See Part 5: section 5.1). In this case, the server MUST send a protocol header with an acceptable protocol id
(and version) and then close the socket. It MAY choose any protocol id.
TCP Client TCP Server
======================================================
AMQP%d0.1.0.0 ------------->
<------------- AMQP%d3.1.0.0
*TCP CLOSE*
------------------------------------------------------
Server rejects connection for: AMQP, protocol=0,
major=1, minor=0, revision=0, Server responds
that it requires: SASL security layer, protocol=3,
major=1, minor=0, revision=0
Figure 2.13: Protocol ID Rejection Example
2.3 Framing
Frames are divided into three distinct areas: a fixed width frame header, a variable width extended header, and a
variable width frame body.
amqp-core-complete-v1.0-os
Standards Track Work Product Copyright
c OASIS Open 2012. All Rights Reserved.
29 October 2012
Page 36 of 124
PART 2. TRANSPORT 2.3 Framing
REQUIRED OPTIONAL OPTIONAL
+--------------+-----------------+------------+
| frame header | extended header | frame body |
+--------------+-----------------+------------+
8 bytes *variable* *variable*
Figure 2.14: Frame Layout
frame header The frame header is a fixed size (8 byte) structure that precedes each frame. The frame
header includes mandatory information necessary to parse the rest of the frame including
size and type information.
extended header The extended header is a variable width area preceding the frame body. This is an extension
point defined for future expansion. The treatment of this area depends on the frame type.
frame body The frame body is a variable width sequence of bytes the format of which depends on the
frame type.
2.3.1 Frame Layout
The diagram below shows the details of the general frame layout for all frame types.
+0 +1 +2 +3
+-----------------------------------+ -.
0 | SIZE | |
+-----------------------------------+ |---> Frame Header

 

 

 

Основная функция протокола обмен сообщениями для реализации передачи уведомлений, а также удаленного вызова функций.

Небольшие накладные расходы на передачу сообщений позволяют реализовать протокол на небольших контроллерах

1.1     Формат сообщения

Сообщение представляет собой пакет состоящий из заголовка, опций, адреса и данных

[message_type,id,name,data,options]

message type one of

   CHALLENGE: 4,
   AUTHENTICATE: 5,
0 - connect

1 - connected

2 - not connected

3 abort

4 - disconnect

5 - disconnected

6 - get description

7 - description response

8 - get - description error

9 - call

10 call cancel

11 - call response

12 call in progress

13 - call error

14 - event

15 - event acknowledged

16 - event not acknowledged

17 - subscribe

18 - subscription confirmed

19 - subscription not confirmed

20 - unsibscribe

21 - unsubscripted

22 - not unsubscripted

23 - keep alive

 

 id is number (unsigned id) it should start from any value (random) and should increment every time (it can be used to control double sending and lost packets)

 

 

name is string name (could be integer value for simplest implementations) of calling function emitted event and so on

 

data is array or map of arguments for calling function return value for returning and so on, data can be omitted if there is no options in message

 

options is map of additional values specific for that method, options can be omitted if there is empty map

 

 

 

 

message encoding:

JSON encoding, then transport is string based it is variant

CBOR encoding, then transport is binary based

 

Hello world message encoding

 

[7,14756,"","Hello world"]

JSON

CBOR

message "hello world" even without topic

[7,14756,"","Hello world"]

26 bytes

84 - array of 4 items
07 - integer value - 7
19 39 a4 integer value 14756
60 - empty string
6B 48 65 6c 6c 6f 20 77 6f 72 6c 64 - string "Hello world"

18 bytes

call the method relay.on without parameters

[4,4365,"relay.on"]

19 bytes

83 - array of 3 items
04 - integer value - 4
19 11 0d integer value 4365
68 72 65 6c 61 79 2e 6f 6e -  string "relay.on"

14 bytes

   

 

call e method

 

[4,4365,"relay.on"]

return

[5,4365,"relay.on"] or even [5,4365] // if function relay.on has no return value (void in c language)

[5,4365,"relay.on",true] or even [5,4365,null,true] // if function relay.on has boolean return value type

[6,4365,"relay.on",[4,"arguments omitted"]] or even [6,4365,null,[4,"arguments omitted"]] // if function relay.on can not be called because arguments should be passed

 

 

 

 

Заголовок

идентификатор сообщения

адрес(url)

данные

 

Заголовок занимает один байт

bit

octet

0

1

2

3

4

5

6

7

0

MTH

T

A

ML

MTH - Method

00 = LCP  (link control protocol)

01 = desc (announce when NON) empty url-get dev desc

10 = call (inform when NON)

11 = publ (NON or CON publication)

 

T

0 = NON non confirmable message

1 = CON confirmable request

2 = ACK normal response

3 = ERR error response

 

A

00 – no address present (point to point)

01 – Master to slave (slave address presented)

10 – slave to Master (slave address presented)

11 – desination and source address presented

 

ML

0 = no message id or in options

1 = message id is 1 bytes length

2 = message id is 2 bytes length

3 = message id is 4 bytes length

Метод определяет сообщение и смысл следующих бит.

LCP – сообщение относится к протоколу управления соединением (смотри соответствующий раздел).

Call – (аналог GET в REST идеологии) сообщение ITMP обеспечивающее удаленный вызов процедуры подписку на событие или список членов для индексатора или объекта

Desc – сообщение ITMP обеспечивающее получение информации об указанном URL

Publ – сообщение ITMP обеспечивающее возможность сообщить об асинхронном событии (от клиента к получателю, указывается урл события)

 

тип сообщения

NON – сообщение не требует подтверждения принимающей стороной

CON – сообщение требует подтверждения (или ответа с соответствующими данными)

ACK – сообщение ответ на CON сообщение - успех

ERR – сообщение ответ на CON сообщение - неуспех

длина идентификатора сообщения указана в заголовке

 

длина url может быть от 0 до 127 байт и указывается в одном байте

 

Данные в сообщении зависят от url для которого выполняется запрос и продолжаются до конца пакета.


 

 

1.2     Сообщения

1.2.1     Сообщение Call

В сообщении указывается URL требуемого действия, в payload параметры, для контроля повторной отправки и сопоставления запроса и ответа каждое сообщение помечается MessageID который увеличивается после отправки каждого сообщения.

Если при запросе биты T установлены в NON не предполагает ответ, если в запросе биты T установлены в CON – запрос подразумевает получение ответа (ACK или ERR) с тем- же url и MessageID что и в запросе

при ответе устанавливаются биты T равными ACK или ERR в зависимости от успешности выполнения запрашиваемого действия

1.2.2     Сообщение Desc (Description)

В сообщении указывается URL для которого требуется получить описание, payload должен быть пустым, для контроля повторной отправки и сопоставления запроса и ответа каждое сообщение помечается MessageID который увеличивается после отправки каждого сообщения.

Биты T установлены в CON – запрос подразумевает получение ответа (ACK или ERR) с тем- же url и MessageID что и в запросе

при ответе устанавливаются биты T равными ACK или ERR в зависимости от успешности выполнения запрашиваемого действия

1.2.3     Сообщение Publ (Publish)

В сообщении указывается URL возникновения события, payload содержит информацию о событии, для контроля повторной отправки и сопоставления запроса и ответа каждое сообщение помечается MessageID который увеличивается после отправки каждого сообщения.

Если необходимо получить подтверждение сообщения T устанавливается в CON иначе NON. при необходимости получить подверждение ожидается ответ  (ACK или ERR) с тем- же url и MessageID что и в запросе. оба ответа говорят о корректном получении сообщения и повторные отправки прекращаются.

1.2.4     Сообщения об ошибках

сообщение об ошибке содержит первым байтом код ошибки далее необязательное текстовое описание ошибки

Коды ошибок

+------+------------------------------+---------+

| Code | Description                  | encoded |

+------+------------------------------+---------+

| 1.02 | Processing                   |    12   |

| 4.00 | Bad Request                  |    40   |

| 4.01 | Unauthorized                 |    41   |

| 4.02 | Bad Option                   |    42   |

| 4.03 | Forbidden                    |    43   |

| 4.04 | Not Found                    |    44   |

| 4.05 | Method Not Allowed           |    45   |

| 4.06 | Not Acceptable               |    46   |

| 4.12 | Precondition Failed          |    4B   |

| 4.13 | Request Entity Too Large     |    4C   |

| 4.15 | Unsupported Content-Format   |    4F   |

| 5.00 | Internal Server Error        |    50   |

| 5.01 | Not Implemented              |    51   |

| 5.02 | Bad Gateway                  |    52   |

| 5.03 | Service Unavailable          |    53   |

| 5.04 | Gateway Timeout              |    54   |

| 5.05 | Proxying Not Supported       |    55   |

| 5.06 | call exception               |    56   |

+------+------------------------------+---------+

Задержка ответа

Если сервер не может немедленно ответить на запрос клиента (особенно в ситуации когда мастер-клиент управляет порядком запросов по шине к нескольким серверам) он может ответить сообщением Processing (12), тогда клиент должен через указанную задержку послать повторный запрос с тем же ID и получить задержанный ответ сервера.

1.3     Схема описания данных

при выполнении запроса get возвращается описание поля без указания имени (имя есть в поле url), при запросе call для получения списка полей отдается массив (вначале указывается количество полей, а затем сами поля) строк с описанием полей объекта.

<field description>::=<name><description><signature>

<name>::=string

<signature>::=<interface>|<func>|<event>|<container>

<interface>::=’:’[<interface name>[,<interface name>]]

<container>::=’*’[<interface name>[,<interface name>]]

<func>::=’&’<ret type list>[‘(‘<argument type list>’)’]

<event>::=’!’<type list>

<interface name>::=string

<ret type list>::=<type list>

<argument type list>::=<type list>

<type list>::=[<type>[,<type>]]

<type>::=<simple type>|a<simple type>

<simple type>::=<type char>[<description>]

<description>::='{'[<name>][<version>][<UniqueId>] [<units>][<variants>][<manufacturer>]'}'

<name>::=string

<version>::=’%’string

<UniqueId>::=’#’string

<units>::='$'string

<variants>::='['<value>[,<value>]']'

<manufacturer>::='@'string

<type char>::=b|n|q|i|u|x|t|N|Q|I|U|X|T|f|d|s

primitive types

b  8-bit unsigned integer (byte)

n  16-bit signed integer

q  16-bit unsigned integer

i  32-bit signed integer

u  32-bit unsigned integer

x  64-bit signed integer

t  64-bit unsigned integer

N  16-bit packed signed integer

Q  16-bit packed unsigned integer

I  32-bit packed signed integer

U  32-bit packed unsigned integer

X  64-bit packed signed integer

T  64-bit packed unsigned integer

f  single-precision floating point (IEEE 754)

d  double-precision floating point (IEEE 754)

s  UTF-8 string with length prefix

Examples

NSC duino{#1.0}:motor

 

addr&b

setpwm&b{status}(n{value[0..1024]})

 

DESCR "" responce

F01.100:apollo,upd{#1.0}

 

CALL "" responce

upd&(b)

frd&(i)

pwr&(b)

stat&b{status byte}

dev*fgdev

 

DESCR "dev" response

dev{extrenal bus devices}*fgdev

 

CALL "dev" response

 

num&b{devs number}

add&(s{element name})

del&(s{element name})

list&as{array of item names}

*fgdev

 

CALL "dev/*" response

 

stat&b{status byte}

act{execute action}&b{status byte}(b{action to execute[0=none,1=reset]})

 

DESCR "dev/num" response

 

{number of external devices connected}&b{devices number}

 

DESCR "dev/5" response

 

stat&b{status byte}

act{execute action}&b{status byte}(b{action to execute[0=none,1=reset]})

 

Интерфейс содержит сигнатуры методов, свойств, событий

функция это необходимое действие со списком параметров и списков возвращаемых значений описывается как

Свойство это объединение двух методов – чтения и записи, причем типы для чтения и записи совпадают, если в запросе присутствует поле данных то это операция записи а затем чтения в противном случае это операция чтения (когда поле данных в запросе пустое), при необходимости реализовать свойство, доступное только для записи, нужно определить функцию без возвращаемого параметра

Событие это извещение клиента об изменении состояния агента, событие сопровождается сопутствующими данными

Коллекция, именованный набор элементов имеющих общие интерфейсы

коллекция может поддерживать получение количества, списка элементов, а также операции по добавлению/удалению элементов. Эти операции должны быть сообщены по запросу Call для коллекции ели получение списка элементов в запросе CALL для коллекции не реализовано, последним элементом перечня методов должен быть метод * без имени подразумевающий что в коллекции есть элементы но их список недоступен (даже если на момент запроса количество элементов 0)

 

1.4     Примеры сообщений

Each device describing as object consist of variables, functions and events. Each variable, function and event has a type (for functions input and output, for events output), name, id, and tagged annotations

Get Device object Description

51                 get description

00                 message id=0

00                 get device description (no resource name)

encoded answer (32 bytes)

61                 descripttion answer

00                 message id=0

00                 description of device empty uri

 

1C                 description length

4d 4f 54 38 32 33  MOT823.112rack:mot{#1.0@NSC}

2e 31 31 32 72 61

63 6b 3a 6d 6f 74

7b 23 31 2e 30 40

4e 53 43 7d

Get field list

91                 call emty url command

01                 message id=1

00                 root with empty uri        

answer

A1                 answer

01                 message id=1

00                 root with empty uri

08 02 6c 57 01 57  url list = ["lW","W","3","4",

01 33 01 34 01 35  "5","6","7","info"]

01 36 01 37 04 69

6e 66 6f

Get field description

91                 get description command

02                 message id=2

02 6c 57           uri = "lW"                 

answer encoded

A1                 get description answer

02                 message id=2

02 6c 57           uri = "lW"

1c                 description length

26 62 7b 6c 65 76  “&b{level of Water$%[0..100]}”

65 6c 20 6f 66 20  function return one byte

57 61 74 65 72 24  that means water level in

25 5b 30 2e 2e 31  percents (from 0 to 100)

30 30 5d 7d

Get field description (4 bytes)

91                 get description command

03                 message id=3

01 57              uri = "W"                  

answer encoded (40 bytes)

A1                 get descripttion answer

03                 message id=3

01 57              uri = "W"                  

1d                 description length

7b 73 74 61 72 74  “{start watering}&

20 77 61 74 65 72  (b{time$ms})”

69 6e 67 7d 26 28

62 7b 74 69 6d 65

24 6d 73 7d 29

possible error answer encoded

B1                 get descripttion err answer

03                 message id=3

01 57              uri = "W"                  

44                 url not found

Publish Message

D2                 publish CON

00 00              message id=0 (two bytes)

08 31 32 2f 73 74

61 72 74           URL: "12/start"

 

46 7b              event data

Example answer

E2                 publish ACK

00 00              message id=0 (two bytes)

08 31 32 2f 73 74

61 72 74           URL: "12/start"

 

6LoWPAN

From Wikipedia, the free encyclopedia

6LoWPAN is an acronym of IPv6 over Low power Wireless Personal Area Networks.[1] 6LoWPAN is the name of a concluded working group in the Internet area of the IETF.[2]

The 6LoWPAN concept originated from the idea that "the Internet Protocol could and should be applied even to the smallest devices,"[3] and that low-power devices with limited processing capabilities should be able to participate in the Internet of Things.[4]

The 6LoWPAN group has defined encapsulation and header compression mechanisms that allow IPv6 packets to be sent and received over IEEE 802.15.4 based networks. IPv4 and IPv6 are the work horses for data delivery for local-area networks, metropolitan area networks, and wide-area networks such as the Internet. Likewise, IEEE 802.15.4 devices provide sensing communication-ability in the wireless domain. The inherent natures of the two networks though, are different.

The base specification developed by the 6LoWPAN IETF group is RFC 4944 (updated by RFC 6282 with header compression, and by RFC 6775 with neighbor discovery optimizations). The problem statement document is RFC 4919.

Contents

Application areas

The target for IP networking for low-power radio communication are applications that need wireless internet connectivity at lower data rates for devices with very limited form factor. An example is automation and entertainment applications in home, office and factory environments. The header compression mechanisms standardized in RFC6282 can be used to provide header compression of IPv6 packets over such networks.

IPv6 is also in use on the smart grid enabling smart meters and other devices to build a micro mesh network before sending the data back to the billing system using the IPv6 backbone. Some of these networks run over IEEE 802.15.4 radios, and therefore use the header compression and fragmentation as specified by RFC6282.

Thread

Thread is an effort of over 50 companies to standardize on a closed-documentation[5], royalty-free protocol running over 6LoWPAN to enable home automation. It is to be launched in the second half of 2015.[6] The protocol will most directly compete with Z-Wave and Zigbee IP.[7]

Functions

As with all link-layer mappings of IP, RFC4944 provides a number of functions. Beyond the usual differences between L2 and L3 networks, mapping from the IPv6 network to the IEEE 802.15.4 network poses additional design challenges (see RFC 4919 for an overview).

Adapting the packet sizes of the two networks
IPv6 requires the maximum transmission unit (MTU) to be at least 1280 Bytes. In contrast, IEEE 802.15.4's standard packet size is 127 octets. A maximum frame overhead of 25 octets spares 102 octets at the media access control layer. An optional but highly recommended security feature at the link layer poses an additional overhead. For example, 21 octets are consumed for AES-CCM-128 leaving only 81 octets for upper layers.
Address resolution
IPv6 nodes are assigned 128 bit IP addresses in a hierarchical manner, through an arbitrary length network prefix. IEEE 802.15.4 devices may use either of IEEE 64 bit extended addresses or, after an association event, 16 bit addresses that are unique within a PAN. There is also a PAN-ID for a group of physically collocated IEEE 802.15.4 devices.
Differing device designs
IEEE 802.15.4 devices are intentionally constrained in form factor to reduce costs (allowing for large-scale network of many devices), reduce power consumption (allowing battery powered devices) and allow flexibility of installation (e.g. small devices for body-worn networks). On the other hand, wired nodes in the IP domain are not constrained in this way; they can be larger and make use of mains power supplies.
Differing focus on parameter optimization
IPv6 nodes are geared towards attaining high speeds. Algorithms and protocols implemented at the higher layers such as TCP kernel of the TCP/IP are optimized to handle typical network problems such as congestion. In IEEE 802.15.4-compliant devices, energy conservation and code-size optimization remain at the top of the agenda.
Adaptation layer for interoperability and packet formats
An adaptation mechanism to allow interoperability between IPv6 domain and the IEEE 802.15.4 can best be viewed as a layer problem. Identifying the functionality of this layer and defining newer packet formats, if needed, is an enticing research area. RFC 4944 proposes an adaptation layer to allow the transmission of IPv6 datagrams over IEEE 802.15.4 networks.
Addressing management mechanisms
The management of addresses for devices that communicate across the two dissimilar domains of IPv6 and IEEE 802.15.4 is cumbersome, if not exhaustingly complex.
Routing considerations and protocols for mesh topologies in 6LoWPAN
Routing per se is a two phased problem that is being considered for low-power IP networking:
  • Mesh routing in the personal area network (PAN) space.
  • The routability of packets between the IPv6 domain and the PAN domain.

Several routing protocol have been proposed by the 6LoWPAN community such as LOAD,[8] DYMO-LOW,[9] HI-LOW.[10] However, only two routing protocols are currently legitimate for large-scale deployments: LOADng [11] standardized by the ITU [4] under the recommendation ITU-T G.9903 and RPL [12] standardized by the IETF ROLL working group.[13]

Device and service discovery
Since IP-enabled devices may require the formation of ad hoc networks, the current state of neighboring devices and the services hosted by such devices will need to be known. IPv6 neighbour discovery extensions is an internet draft proposed as a contribution in this area.
Security
IEEE 802.15.4 nodes can operate in either secure mode or non-secure mode. Two security modes are defined in the specification in order to achieve different security objectives: Access Control List (ACL) and Secure mode[14]

Further reading

See also

  • DASH7 active RFID standard
  • MyriaNed low power, biology inspired, wireless technology
  • Z-Wave designed to provide, reliable, low-latency transmission of small data packets at data rates up to 100kbit/s
  • ZigBee standards-based protocol based on IEEE 802.15.4.
  • LoRaWAN allows low bit rate communication from and to connected objects, thus participating to Internet of Things, machine-to-machine M2M, and smart city.
  • Thread (network protocol) standard suggested by Nest Labs based on IEEE 802.15.4 and 6LoWPAN.

References

 

External links

This document defines the Internet of Thinks Messageging Protocol (ITMP).


ITMP is a routable protocol that provides two messaging patterns: Publish & Subscribe and Remote Procedure Calls. It is intended to connect application components in distributed applications. ITMP uses WebSocket as its default transport, but can be transmitted via any other protocol that allows for ordered, reliable, bi-directional, and message-oriented communications.


1. Introduction

1.1. Background

The WebSocket protocol brings bi-directional real-time connections to the browser. It defines an API at the message level, requiring users who want to use WebSocket connections in their applications to define
their own semantics on top of it.

The Internet of Thinks Messaging Protocol (ITMP) is intended to provide application developers with the semantics they need to handle messaging between components in distributed applications.

ITMP is a route-able protocol, with all components can connect to a ITMP Router, where the ITMP Router performs message routing between the components.

ITMP provides two messaging patterns: Publish & Subscribe and Remote Procedure Calls.

Publish & Subscribe (PubSub) is an established messaging pattern where a component, the _Subscriber_, informs the router that it wants to receive information on a topic (i.e., it subscribes to a topic).
Another component, a _Publisher_, can then publish to this topic, and the router distributes events to all Subscribers.

Remote Procedure Calls (RPCs) rely on the same sort of decoupling that is used by the Publish & Subscribe pattern. A component, the _Callee_, announces to the router that it provides a certain procedure, identified by a procedure name. Other components, _Callers_, can then call the procedure, with the router invoking the procedure on the Callee, receiving the procedure's result, and then forwarding this result back to the Caller. Routed RPCs differ from traditional client-server RPCs in that the router serves as an intermediary between the Caller and the Callee.

The decoupling in routed RPCs arises from the fact that the Caller is no longer required to have knowledge of the Callee; it merely needs to know the identifier of the procedure it wants to call. There is
also no longer a need for a direct connection between the caller and the callee, since all traffic is routed. This enables the calling of procedures in components which are not reachable externally (e.g. on
a NATted connection) but which can establish an outgoing connection to the ITMP router.

Combining these two patterns into a single protocol allows it to be used for the entire messaging requirements of an application, thus reducing technology stack complexity, as well as networking overheads.

1.2. Protocol Overview

The PubSub messaging pattern defines three roles: _Subscribers_ and _Publishers_, which communicate via a _Broker_.

The RPC messaging pattern also defines three roles: _Callers_ and _Callees_, which communicate via a _Dealer_.

ITMP Connections are established by _Clients_ to a _Router_. Connections can use any transport that is message-based, ordered, reliable and bi-directional, with WebSocket as the default transport.

A Router is a component which implements one or both of the Broker and Dealer roles. A Client is a component which implements any or all of the Subscriber, Publisher, Caller, or Callee roles.

ITMP _Connections_ are established by Clients to a Router. Connections can use any transport which is message-oriented, ordered, reliable and bi-directional, with WebSocket as the default transport.

ITMP _Sessions_ are established over a ITMP Connection. A ITMP Session is joined to a _Realm_ on a Router. Routing occurs only between ITMP Sessions that have joined the same Realm.

The _ITMP Basic Profile_ defines the parts of the protocol that are required to establish a ITMP connection, as well as for basic interactions between the four client and two router roles. ITMP implementations are required to implement the Basic Profile, at minimum.

The _ITMP Advanced Profile_ defines additions to the Basic Profile which greatly extend the utility of ITMP in real-world applications. ITMP implementations may support any subset of the Advanced Profile features. They are required to announce those supported features during session establishment.

1.3. Design Philosophy

_This section is non-normative._

ITMP was designed to be performant, safe and easy to implement. Its entire design was driven by a implement, get feedback, adjust cycle.

1.3.1. Basic and Advanced Profiles

This document first describes a Basic Profile for ITMP in its entirety, before describing an Advanced Profile which extends the basic functionality of ITMP.

The separation into Basic and Advanced Profiles is intended to extend the reach of the protocol. It allows implementations to start out with a minimal, yet operable and useful set of features, and to expand that set from there. It also allows implementations that are tailored for resource-constrained environments, where larger feature sets would not be possible. Here implementers can weigh between resource constraints and functionality requirements, then implement an optimal feature set for the circumstances.

Advanced Profile features are announced during session establishment, so that different implementations can adjust their interactions to fit the commonly supported feature set.

1.3.2. Application Code

ITMP is designed for application code to run within Clients, i.e. _Peers_ having the roles Callee, Caller, Publisher, and Subscriber.

Routers, i.e. Peers of the roles Brokers and Dealers are responsible for *generic call and event routing* and do not run application code.

This allows the transparent exchange of Broker and Dealer implementations without affecting the application and to distribute and deploy application components flexibly.

Note that a *program* that implements, for instance, the Dealer role might at the same time implement, say, a built-in Callee. It is the Dealer and Broker that are generic, not the program.

1.3.3. Language Agnostic

ITMP is language agnostic, i.e. can be implemented in any programming language. At the level of arguments that may be part of a ITMP message, ITMP takes a 'superset of all' approach. ITMP
implementations may support features of the implementing language for use in arguments, e.g. keyword arguments.

1.3.4. Router Implementation Specifics

This specification only deals with the protcol level. Specific ITMP Broker and Dealer implementations may differ in aspects such as support for:

o router networks (clustering and federation),

o authentication and authorization schemes,

o message persistence, and,

o management and monitoring.

The definition and documentation of such Router features is outside the scope of this document.

1.4. Relationship to WebSocket

ITMP uses WebSocket as its default transport binding, and is a registered WebSocket subprotocol.

2. Conformance Requirements

All diagrams, examples, and notes in this specification are non-normative, as are all sections explicitly marked non-normative. Everything else in this specification is normative.

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 [RFC2119].

Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word
("MUST", "SHOULD", "MAY", etc.) used in introducing the algorithm.


Conformance requirements phrased as algorithms or specific steps MAY
be implemented in any manner, so long as the end result is
equivalent.

2.1. Terminology and Other Conventions

Key terms such as named algorithms or definitions are indicated like
_this_ when they first occur, and are capitalized throughout the
text.

3. Realms, Sessions and Transports

A Realm is a ITMP routing and administrative domain, optionally protected by authentication and authorization. ITMP messages are only routed within a Realm. Realm with empty name is default.

A Session is a transient conversation between two Peers attached to a Realm and running over a Transport.

A Transport connects two ITMP Peers and provides a channel over which ITMP messages for a ITMP Session can flow in both directions.

ITMP can run over any Transport which is message-based, bidirectional, reliable and ordered.

The default transport for ITMP is WebSocket [RFC6455], where ITMP is an officially registered [1] subprotocol.

4. Peers and Roles

A ITMP Session connects two Peers. Each ITMP Peer MUST implement one role, and MAY implement more roles.

A Client MAY implement any combination of the Roles:

o Callee

o Caller

o Publisher

o Subscriber

o Dealer

o Broker

This document describes ITMP as in client-to-router communication and direct client-to-client communication is supported by ITMP. Router-to-router communication MAY be defined same way.

4.1. Symmetric Messaging

It is important to note that though the establishment of a Transport might have a inherent asymmetry (like a TCP client establishing a WebSocket connection to a server), and Clients establish ITMP sessions by attaching to Realms on Routers, ITMP itself is designed to be fully symmetric for application components.

After the transport and a session have been established, any application component may act as Caller, Callee, Publisher and Subscriber at the same time. And Routers provide the fabric on top of which ITMP runs a symmetric application messaging service.

4.2. Remote Procedure Call Roles

The Remote Procedure Call messaging pattern involves peers of two different roles:

o Callee (Client)

o Caller (Client)

A Caller issues calls to remote procedures by providing the procedure URI and any arguments for the call. The Callee will execute the procedure using the supplied arguments to the call and return the result of the call to the Caller.

Callees register procedures they provide with Dealers. Callers initiate procedure calls first to Dealers. Dealers route calls incoming from Callers to Callees implementing the procedure called, and route call results back from Callees to Callers.

The Caller and Callee will usually run application code, while the Dealer works as a generic router for remote procedure calls decoupling Callers and Callees.

4.3. Publish & Subscribe Roles

The Publish & Subscribe messaging pattern involves peers of three different roles:

o Subscriber (Client)

o Publisher (Client)

A Publishers publishes events to topics by providing the topic URI and any payload for the event. Subscribers of the topic will receive the event together with the event payload.

Subscribers subscribe to topics they are interested in with Brokers. Publishers initiate publication first at Brokers. Brokers route events incoming from Publishers to Subscribers that are subscribed to
respective topics.

The Publisher and Subscriber will usually run application code, while the Broker works as a generic router for events decoupling Publishers from Subscribers.

4.4. Peers with multiple Roles

Note that Peers might implement more than one role: e.g. a Peer might act as Caller, Publisher and Subscriber at the same time. Another Peer might act as both a Broker and a Dealer.


5. Building Blocks

ITMP is defined with respect to the following building blocks

1. Identifiers

2. Serializations

3. Transports

For each building block, ITMP only assumes a defined set of requirements, which allows to run ITMP variants with different concrete bindings.

5.1. Identifiers

5.1.1. URIs

ITMP needs to identify the following persistent resources:

1. Topics

2. Procedures

3. Errors

These are identified in ITMP using Uniform Resource Identifiers (URIs) [RFC3986] that MUST be Unicode strings.

When using JSON as ITMP serialization format, URIs (as other strings) are transmitted in UTF-8 [RFC3629] encoding.

_Examples_

o "com.myapp.mytopic1"

o "com.myapp.myprocedure1"

o "com.myapp.myerror1"

The URIs are understood to form a single, global, hierarchical namespace for ITMP.

The namespace is unified for topics, procedures and errors - these different resource types do NOT have separate namespaces.

To avoid resource naming conflicts, the package naming convention from Java is used, where URIs SHOULD begin with (reversed) domain names owned by the organization defining the URI.

5.1.1.1. Relaxed/Loose URIs

URI components (the parts between two "."s, the head part up to the first ".", the tail part after the last ".") MUST NOT contain a ".", "#" or whitespace characters and MUST NOT be empty (zero-length strings).

The restriction not to allow "." in component strings is due to the fact that "." is used to separate components, and ITMP associates semantics with resource hierarchies, such as in pattern-based subscriptions that are part of the Advanced Profile. The restriction not to allow empty (zero-length) strings as components is due to the fact that this may be used to denote wildcard components with pattern-based subscriptions and registrations in the Advanced Profile. The character "#" is not allowed since this is reserved for internal use by Dealers and Brokers.

As an example, the following regular expression could be used in Python to check URIs according to the above rules:

<CODE BEGINS>
## loose URI check disallowing empty URI components
pattern = re.compile(r"^([^\s\.#]+\.)*([^\s\.#]+)$")
<CODE ENDS>

When empty URI components are allowed (which is the case for specific messages that are part of the Advanced Profile), this following regular expression can be used (shown used in Python):

<CODE BEGINS>
## loose URI check allowing empty URI components
pattern = re.compile(r"^(([^\s\.#]+\.)|\.)*([^\s\.#]+)?$")
<CODE ENDS>

5.1.1.2. Strict URIs

While the above rules MUST be followed, following a stricter URI rule is recommended: URI components SHOULD only contain lower-case letters, digits and "_".

As an example, the following regular expression could be used in Python to check URIs according to the above rules:

<CODE BEGINS>
## strict URI check disallowing empty URI components
pattern = re.compile(r"^([0-9a-z_]+\.)*([0-9a-z_]+)$")
<CODE ENDS>

When empty URI components are allowed (which is the case for specific messages that are part of the Advanced Profile), the following regular expression can be used (shown in Python):

<CODE BEGINS>
## strict URI check allowing empty URI components
pattern = re.compile(r"^(([0-9a-z_]+\.)|\.)*([0-9a-z_]+)?$")
<CODE ENDS>

Following the suggested regular expression will make URI components valid identifiers in most languages (modulo URIs starting with a digit and language keywords) and the use of lower-case only will make those identifiers unique in languages that have case-insensitive identifiers. Following this suggestion can allow implementations to map topics, procedures and errors to the language environment in a completely transparent way.

5.1.1.3. Reserved URIs

Further, application URIs MUST NOT use "wamp" as a first URI component, since this is reserved for URIs predefined with the ITMP protocol itself.

_Examples_

o "wamp.error.not_authorized"

o "wamp.error.procedure_already_exists"

5.1.2. IDs

ITMP needs to identify the following ephemeral entities each in the scope noted:

1. Sessions (_global scope_)

2. Publications (_global scope_)

3. Subscriptions (_router scope_)

4. Registrations (_router scope_)

5. Requests (_session scope_)

These are identified in ITMP using IDs that are integers between (inclusive) *0* and *2^53* (9007199254740992):

o IDs in the _global scope_ MUST be drawn _randomly_ from a _uniform distribution_ over the complete range [0, 2^53]

o IDs in the _router scope_ can be chosen freely by the specific router implementation

o IDs in the _session scope_ SHOULD be incremented by 1 beginning with 1 (for each direction - _Client-to-Router_ and _Router-to-Client_)

The reason to choose the specific upper bound is that 2^53 is the largest integer such that this integer and _all_ (positive) smaller integers can be represented exactly in IEEE-754 doubles. Some languages (e.g. JavaScript) use doubles as their sole number type. Most languages do have signed and unsigned 64-bit integer types that both can hold any value from the specified range.

The following is a complete list of usage of IDs in the three categories for all ITMP messages. For a full definition of these see Section 6.

5.1.2.1. Global Scope IDs

o "WELCOME.Session"

o "PUBLISHED.Publication"

o "EVENT.Publication"

5.1.2.2. Router Scope IDs

o "EVENT.Subscription"

o "SUBSCRIBED.Subscription"

o "REGISTERED.Registration"

o "UNSUBSCRIBE.Subscription"

o "UNREGISTER.Registration"

o "INVOCATION.Registration"


5.1.2.3. Session Scope IDs

o "ERROR.Request"

o "PUBLISH.Request"

o "PUBLISHED.Request"

o "SUBSCRIBE.Request"

o "SUBSCRIBED.Request"

o "UNSUBSCRIBE.Request"

o "UNSUBSCRIBED.Request"

o "CALL.Request"

o "CANCEL.Request"

o "RESULT.Request"

o "REGISTER.Request"

o "REGISTERED.Request"

o "UNREGISTER.Request"

o "UNREGISTERED.Request"

o "INVOCATION.Request"

o "INTERRUPT.Request"

o "YIELD.Request"

5.2. Serializations

ITMP is a message based protocol that requires serialization of messages to octet sequences to be sent out on the wire.

A message serialization format is assumed that (at least) provides the following types:

o "integer" (non-negative)

o "string" (UTF-8 encoded Unicode)

o "bool"

o "list"

o "dict" (with string keys)

ITMP _itself_ only uses the above types, e.g. it does not use the JSON data types "number" (non-integer) and "null". The _application payloads_ transmitted by ITMP (e.g. in call arguments or event payloads) may use other types a concrete serialization format supports.

There is no required serialization or set of serializations for ITMP implementations (but each implementation MUST, of course, implement at least one serialization format). Routers SHOULD implement more than one serialization format, enabling components using different kinds of serializations to connect to each other.

ITMP defines two bindings for message serialization:

1. JSON

2. CBOR

Other bindings for serialization may be defined in future ITMP versions.

5.2.1. JSON

With JSON serialization, each ITMP message is serialized according to the JSON specification as described in RFC4627.

Further, binary data follows a convention for conversion to JSON strings. For details see the Appendix.

5.2.2. CBOR

With CBOR serialization, each ITMP message is serialized according to the CBOR specification.

5.3. Transports

ITMP assumes a transport with the following characteristics:

1. message-based

2. reliable

3. ordered

4. bidirectional (full-duplex)

There is no required transport or set of transports for ITMP implementations (but each implementation MUST, of course, implement at least one transport). Routers SHOULD implement more than one transport, enabling components using different kinds of transports to connect in an application.

5.3.1. WebSocket Transport

The default transport binding for ITMP is WebSocket.

In the Basic Profile, ITMP messages are transmitted as WebSocket messages: each ITMP message is transmitted as a separate WebSocket message (not WebSocket frame). The Advanced Profile may define other
modes, e.g. a *batched mode* where multiple ITMP messages are transmitted via single WebSocket message.

The ITMP protocol MUST BE negotiated during the WebSocket opening handshake between Peers using the WebSocket subprotocol negotiation mechanism.

ITMP uses the following WebSocket subprotocol identifiers for unbatched modes:

o "itmp.json"

o "itmp.cbor"

With "itmp.json", _all_ WebSocket messages MUST BE of type *text* (UTF8 encoded payload) and use the JSON message serialization.

With "wamp.2.msgpack", _all_ WebSocket messages MUST BE of type *binary* and use the MsgPack message serialization.

To avoid incompatibilities merely due to naming conflicts with WebSocket subprotocol identifiers, implementers SHOULD register identifiers for additional serialization formats with the official WebSocket subprotocol registry.


5.3.2. Transport and Session Lifetime

ITMP implementations MAY choose to tie the lifetime of the underlying transport connection for a ITMP connection to that of a ITMP session, i.e. establish a new transport-layer connection as part of each new
session establishment. They MAY equally choose to allow re-use of a transport connection, allowing subsequent ITMP sessions to be established using the same transport connection.

The diagram below illustrates the full transport connection and session lifecycle for an implementation which uses WebSocket over TCP as the transport and allows the re-use of a transport connection.


,------. ,------.
| Peer | | Peer |
`--+---' `--+---'

TCP established
|<----------------------------------------->|
| |
| TLS established |
|+<--------------------------------------->+|
|+ +|
|+ WebSocket established +|
|+|<------------------------------------->|+|
|+| |+|
|+| ITMP established |+|
|+|+<----------------------------------->+|+|
|+|+ +|+|
|+|+ +|+|
|+|+ ITMP closed +|+|
|+|+<----------------------------------->+|+|
|+| |+|
|+| |+|
|+| ITMP established |+|
|+|+<----------------------------------->+|+|
|+|+ +|+|
|+|+ +|+|
|+|+ ITMP closed +|+|
|+|+<----------------------------------->+|+|
|+| |+|
|+| WebSocket closed |+|
|+|<------------------------------------->|+|
|+ +|
|+ TLS closed +|
|+<--------------------------------------->+|
| |
| TCP closed |
|<----------------------------------------->|

,--+---. ,--+---.
| Peer | | Peer |
`------' `------'

6. Messages

All ITMP messages are a "list" with a first element "MessageType" followed by one or more message type specific elements:

[MessageType|integer, ... one or more message type specific elements ...]


The notation "Element|type" denotes a message element named "Element" of type "type", where "type" is one of

o "uri": a string URI as defined in Section 5.1.1

o "id": an integer ID as defined in Section 5.1.2

o "integer": a non-negative integer

o "string": a Unicode string, including the empty string

o "bool": a boolean value ("true" or "false") - integers MUST NOT be
used instead of boolean value

o "dict": a dictionary (map) where keys MUST be strings, keys MUST
be unique and serialization order is undefined (left to the
serializer being used)

o "list": a list (array) where items can be again any of this
enumeration

_Example_

A "SUBSCRIBE" message has the following format

[SUBSCRIBE, Request|id, Topic|uri, Options|dict]

Here is an example message conforming to the above format

[32, 713845233, "com.myapp.mytopic1", {}]

6.1. Extensibility

Some ITMP messages contain "Options|dict" or "Details|dict" elements. This allows for future extensibility and implementations that only provide subsets of functionality by ignoring unimplemented attributes. Keys in "Options" and "Details" MUST be of type "string" and MUST match the regular expression "[a-z][a-z0-9_]{2,}" for ITMP predefined keys. Implementations MAY use implementation-specific keys that MUST match the regular expression "_[a-z0-9_]{3,}". Attributes unknown to an implementation MUST be ignored.

6.2. No Polymorphism

For a given "MessageType" and number of message elements the expected types are uniquely defined. Hence there are no polymorphic messages in ITMP. This leads to a message parsing and validation control flow that is efficient, simple to implement and simple to code for rigorous message format checking.

6.3. Structure

The application payload (that is call arguments, call results, event payload etc) is always at the end of the message element list. The rationale is: Brokers and Dealers have no need to inspect (parse) the application payload. Their business is call/event routing. Having the application payload at the end of the list allows Brokers and Dealers to skip parsing it altogether. This can improve efficiency and performance.

6.4. Message Definitions

ITMP defines the following messages that are explained in detail in the following sections.

The messages concerning the ITMP session itself are mandatory for all Peers, i.e. a Client MUST implement "HELLO", "ABORT" and "GOODBYE", while a Router MUST implement "WELCOME", "ABORT" and "GOODBYE".

All other messages are mandatory per role, i.e. in an implementation that only provides a Client with the role of Publisher MUST additionally implement sending "PUBLISH" and receiving "PUBLISHED" and "ERROR" messages.

6.4.1. Session Lifecycle

6.4.1.1. CONNECT

Sent by a Client to initiate opening of a ITMP session to a Server attaching to a Realm.

[CONNECT, Realm|uri, Details|dict]

6.4.1.2. CONNECTED

Sent by a Server to accept a Client. The ITMP session is now open.

[CONNECTED, Session|id, Details|dict]

6.4.1.3. ABORT

Sent by a Peer*to abort the opening of a ITMP session. No response is expected.

[ABORT, Details|dict, Reason|uri]

6.4.1.4. DISCONNECT

Sent by a Peer to close a previously opened ITMP session. Must be echo'ed by the receiving Peer.

[DISCONNECT, Details|dict, Reason|uri]

6.4.2. Publish & Subscribe

6.4.2.1. PUBLISH

Sent by a Publisher to a Subscriber/Broker to publish an event.

[PUBLISH, Request|id, Topic|uri, Arguments|list, Options|dict]

6.4.2.2. PUBLISHED

Acknowledge sent by a Broker to a Publisher for acknowledged publications.

[PUBLISHED, PUBLISH.Request|id, Publication|id]

6.4.2.3. SUBSCRIBE

Subscribe request sent by a Subscriber to a Broker to subscribe to a topic.

[SUBSCRIBE, Request|id, Options|dict, Topic|uri]

6.4.2.4. CONFIRMED

Acknowledge sent by a Broker to a Subscriber to acknowledge a
subscription.

[CONFIRMED, SUBSCRIBE.Request|id, Subscription|id]

6.4.2.5. UNSUBSCRIBE

Unsubscribe request sent by a Subscriber to a Broker to unsubscribe a subscription.

[UNSUBSCRIBE, Request|id, SUBSCRIBED.Subscription|id]

6.4.2.7. EVENT

Event dispatched by Broker to Subscribers for subscriptions the event
was matching.

[EVENT, SUBSCRIBED.Subscription|id, PUBLISHED.Publication|id,
Details|dict]

[EVENT, SUBSCRIBED.Subscription|id, PUBLISHED.Publication|id,
Details|dict, PUBLISH.Arguments|list]

[EVENT, SUBSCRIBED.Subscription|id, PUBLISHED.Publication|id,
Details|dict, PUBLISH.Arguments|list,
PUBLISH.ArgumentsKw|dict]

An event is dispatched to a Subscriber for a given "Subscription|id" only once. On the other hand, a Subscriber that holds subscriptions with different "Subscription|id"s that all match a given event will receive the event on each matching subscription.

6.4.3. Remote Procedure Calls

6.4.3.1. CALL

Call as originally issued by the Caller to the Dealer.

[CALL, Request|id, Options|dict, Procedure|uri]

[CALL, Request|id, Options|dict, Procedure|uri, Arguments|list]

[CALL, Request|id, Options|dict, Procedure|uri, Arguments|list,
ArgumentsKw|dict]

6.4.3.2. RESULT

Result of a call as returned by Dealer to Caller.

[RESULT, CALL.Request|id, Details|dict]

[RESULT, CALL.Request|id, Details|dict, YIELD.Arguments|list]

[RESULT, CALL.Request|id, Details|dict, YIELD.Arguments|list, YIELD.ArgumentsKw|dict]

6.4.3.3. REGISTER

A Callees request to register an endpoint at a Dealer.

[REGISTER, Request|id, Options|dict, Procedure|uri]

6.4.3.4. REGISTERED

Acknowledge sent by a Dealer to a Callee for successful registration.

[REGISTERED, REGISTER.Request|id, Registration|id]

6.4.3.5. UNREGISTER

A Callees request to unregister a previously established
registration.

[UNREGISTER, Request|id, REGISTERED.Registration|id]

6.4.3.6. UNREGISTERED

Acknowledge sent by a Dealer to a Callee for successful
unregistration.

[UNREGISTERED, UNREGISTER.Request|id]


6.4.3.7. INVOCATION

Actual invocation of an endpoint sent by Dealer to a Callee.

[INVOCATION, Request|id, REGISTERED.Registration|id,
Details|dict]

[INVOCATION, Request|id, REGISTERED.Registration|id,
Details|dict, C* Arguments|list]

[INVOCATION, Request|id, REGISTERED.Registration|id,
Details|dict, CALL.Arguments|list, CALL.ArgumentsKw|dict]

6.4.3.8. YIELD

Actual yield from an endpoint sent by a Callee to Dealer.

[YIELD, INVOCATION.Request|id, Options|dict]

[YIELD, INVOCATION.Request|id, Options|dict, Arguments|list]

[YIELD, INVOCATION.Request|id, Options|dict, Arguments|list, ArgumentsKw|dict]

6.5. Message Codes and Direction

The following table lists the message type code for all 25 messages
defined in the ITMP basic profile and their direction between peer
roles.

Reserved codes may be used to identify additional message types in
future standards documents.

"Tx" indicates the message is sent by the respective role, and
"Rx" indicates the message is received by the respective role.


+-----+----------------+------+------+------+------+-------+--------+
| Cod | Message | Pub | Brk | Subs | Calr | Dealr | Callee |
+-----+----------------+------+------+------+------+-------+--------+
| 1 | "HELLO" | Tx | Rx | Tx | Tx | Rx | Tx |
| 2 | "WELCOME" | Rx | Tx | Rx | Rx | Tx | Rx |
| 3 | "ABORT" | Rx | TxRx | Rx | Rx | TxRx | Rx |
| 6 | "GOODBYE" | TxRx | TxRx | TxRx | TxRx | TxRx | TxRx |
| | | | | | | | |
| 8 | "ERROR" | Rx | Tx | Rx | Rx | TxRx | TxRx |
| | | | | | | | |
| 16 | "PUBLISH" | Tx | Rx | | | | |
| 17 | "PUBLISHED" | Rx | Tx | | | | |
| | | | | | | | |
| 32 | "SUBSCRIBE" | | Rx | Tx | | | |
| 33 | "SUBSCRIBED" | | Tx | Rx | | | |
| 34 | "UNSUBSCRIBE" | | Rx | Tx | | | |
| 35 | "UNSUBSCRIBED" | | Tx | Rx | | | |
| 36 | "EVENT" | | Tx | Rx | | | |
| | | | | | | | |
| 48 | "CALL" | | | | Tx | Rx | |
| 50 | "RESULT" | | | | Rx | Tx | |
| | | | | | | | |
| 64 | "REGISTER" | | | | | Rx | Tx |
| 65 | "REGISTERED" | | | | | Tx | Rx |
| 66 | "UNREGISTER" | | | | | Rx | Tx |
| 67 | "UNREGISTERED" | | | | | Tx | Rx |
| 68 | "INVOCATION" | | | | | Tx | Rx |
| 70 | "YIELD" | | | | | Rx | Tx |
+-----+----------------+------+------+------+------+-------+--------+

6.6. Extension Messages

ITMP uses type codes from the core range [0, 255]. Implementations MAY define and use implementation specific messages with message type codes from the extension message range [256, 1023]. For example, a router MAY implement router-to-router communication by using extension messages.

6.7. Empty Arguments and Keyword Arguments

Implementations SHOULD avoid sending empty "Arguments" lists.

E.g. a "CALL" message

[CALL, Request|id, Options|dict, Procedure|uri, Arguments|list]

where "Arguments == []" SHOULD be avoided, and instead

[CALL, Request|id, Options|dict, Procedure|uri]

SHOULD be sent.

Implementations SHOULD avoid sending empty "ArgumentsKw"
dictionaries.

E.g. a "CALL" message

[CALL, Request|id, Options|dict, Procedure|uri,
Arguments|list, ArgumentsKw|dict]

where "ArgumentsKw == {}" SHOULD be avoided, and instead

[CALL, Request|id, Options|dict, Procedure|uri,
Arguments|list]

SHOULD be sent when "Arguments" is non-empty.

7. Sessions

The message flow between Clients and Routers for opening and closing
ITMP sessions involves the following messages:

1. "HELLO"

2. "WELCOME"

3. "ABORT"

4. "GOODBYE"

7.1. Session Establishment

7.1.1. HELLO

After the underlying transport has been established, the opening of a
ITMP session is initiated by the Client sending a "HELLO" message to
the Router

[HELLO, Realm|uri, Details|dict]

where

o "Realm" is a string identifying the realm this session should
attach to





Oberstein & Goedde Expires April 13, 2016 [Page 28]

Internet-Draft ITMP October 2015


o "Details" is a dictionary that allows to provide additional
opening information (see below).

The "HELLO" message MUST be the very first message sent by the Client
after the transport has been established.

In the ITMP Basic Profile without session authentication the Router
will reply with a "WELCOME" or "ABORT" message.

,------. ,------.
|Client| |Router|
`--+---' `--+---'
| HELLO |
| ---------------->
| |
| WELCOME |
| <----------------
,--+---. ,--+---.
|Client| |Router|
`------' `------'

A ITMP session starts its lifetime when the Router has sent a
"WELCOME" message to the Client, and ends when the underlying
transport closes or when the session is closed explicitly by either
peer sending the "GOODBYE" message (see below).

It is a protocol error to receive a second "HELLO" message during the
lifetime of the session and the Peer must fail the session if that
happens.

7.1.1.1. Client: Role and Feature Announcement

ITMP uses _Role & Feature announcement_ instead of _protocol versioning_ to allow

o implementations only supporting subsets of functionality

o future extensibility

A Client must announce the roles it supports via
"Hello.Details.roles|dict", with a key mapping to a
"Hello.Details.roles.<role>|dict" where "<role>" can be:

o "publisher"

o "subscriber"

o "caller"



Oberstein & Goedde Expires April 13, 2016 [Page 29]

Internet-Draft ITMP October 2015


o "callee"

A Client can support any combination of the above roles but must
support at least one role.

The "<role>|dict" is a dictionary describing features supported by
the peer for that role.

This MUST be empty for ITMP Basic Profile implementations, and MUST
be used by implementations implementing parts of the Advanced Profile
to list the specific set of features they support.

_Example: A Client that implements the Publisher and Subscriber roles
of the ITMP Basic Profile._

[1, "somerealm", {
"roles": {
"publisher": {},
"subscriber": {}
}
}]

7.1.2. WELCOME

A Router completes the opening of a ITMP session by sending a
"WELCOME" reply message to the Client.

[WELCOME, Session|id, Details|dict]

where

o "Session" MUST be a randomly generated ID specific to the ITMP
session. This applies for the lifetime of the session.

o "Details" is a dictionary that allows to provide additional
information regarding the open session (see below).

In the ITMP Basic Profile without session authentication, a "WELCOME"
message MUST be the first message sent by the Router, directly in
response to a "HELLO" message received from the Client. Extensions
in the Advanced Profile MAY include intermediate steps and messages
for authentication.

Note. The behavior if a requested "Realm" does not presently
exist is router-specific. A router may e.g. automatically create
the realm, or deny the establishment of the session with a "ABORT"
reply message.




Oberstein & Goedde Expires April 13, 2016 [Page 30]

Internet-Draft ITMP October 2015


7.1.2.1. Router: Role and Feature Announcement

Similar to a Client announcing Roles and Features supported in the
`"HELLO" message, a Router announces its supported Roles and Features
in the "WELCOME" message.

A Router MUST announce the roles it supports via
"Welcome.Details.roles|dict", with a key mapping to a
"Welcome.Details.roles.<role>|dict" where "<role>" can be:

o "broker"

o "dealer"

A Router must support at least one role, and MAY support both roles.

The "<role>|dict" is a dictionary describing features supported by
the peer for that role. With ITMP Basic Profile implementations,
this MUST be empty, but MUST be used by implementations implementing
parts of the Advanced Profile to list the specific set of features
they support

_Example: A Router implementing the Broker role of the ITMP Basic
Profile._

[2, 9129137332, {
"roles": {
"broker": {}
}
}]

7.1.3. ABORT

Both the Router and the Client may abort the opening of a ITMP
session by sending an "ABORT" message.

[ABORT, Details|dict, Reason|uri]

where

o "Reason" MUST be an URI.

o "Details" MUST be a dictionary that allows to provide additional,
optional closing information (see below).

No response to an "ABORT" message is expected.





Oberstein & Goedde Expires April 13, 2016 [Page 31]

Internet-Draft ITMP October 2015


,------. ,------.
|Client| |Router|
`--+---' `--+---'
| HELLO |
| ---------------->
| |
| ABORT |
| <----------------
,--+---. ,--+---.
|Client| |Router|
`------' `------'

_Example_

[3, {"message": "The realm does not exist."},
"wamp.error.no_such_realm"]

7.2. Session Closing

A ITMP session starts its lifetime with the Router sending a
"WELCOME" message to the Client and ends when the underlying
transport disappears or when the ITMP session is closed explicitly by
a "GOODBYE" message sent by one Peer and a "GOODBYE" message sent
from the other Peer in response.

[GOODBYE, Details|dict, Reason|uri]

where

o "Reason" MUST be an URI.

o "Details" MUST be a dictionary that allows to provide additional,
optional closing information (see below).

,------. ,------.
|Client| |Router|
`--+---' `--+---'
| GOODBYE |
| ---------------->
| |
| GOODBYE |
| <----------------
,--+---. ,--+---.
|Client| |Router|
`------' `------'






Oberstein & Goedde Expires April 13, 2016 [Page 32]

Internet-Draft ITMP October 2015


,------. ,------.
|Client| |Router|
`--+---' `--+---'
| GOODBYE |
| <----------------
| |
| GOODBYE |
| ---------------->
,--+---. ,--+---.
|Client| |Router|
`------' `------'

_Example_. One Peer initiates closing

[6, {"message": "The host is shutting down now."},
"wamp.error.system_shutdown"]

and the other peer replies

[6, {}, "wamp.error.goodbye_and_out"]

_Example_. One Peer initiates closing

[6, {}, "wamp.error.close_realm"]

and the other peer replies

[6, {}, "wamp.error.goodbye_and_out"]

7.2.1. Difference between ABORT and GOODBYE

The differences between "ABORT" and "GOODBYE" messages are:

1. "ABORT" gets sent only _before_ a Session is established, while
"GOODBYE" is sent only _after_ a Session is already established.

2. "ABORT" is never replied to by a Peer, whereas "GOODBYE" must be
replied to by the receiving Peer

Though "ABORT" and "GOODBYE" are structurally identical, using
different message types serves to reduce overloaded meaning of
messages and simplify message handling code.

7.2.2. Session Statechart

The following state chart gives the states that a ITMP peer can be in
during the session lifetime cycle.




Oberstein & Goedde Expires April 13, 2016 [Page 33]

Internet-Draft ITMP October 2015


+--------------+
+--------(6)-------------> |
| | CLOSED <--------------------------+
| +------(4)-------------> <---+ |
| | +--------------+ | |
| | | | |
| | (1) (7) |
| | | | |
| | +--------v-----+ | (11)
| | | +---+ |
| | +------------+ ESTABLISHING +----------------+ |
| | | | | | |
| | | +--------------+ | |
| | | | (10) |
| | | (9) | |
| | | | | |
| | (2) +--------v-----+ +--------v-------+ |
| | | | | | | |
| | | +------> FAILED <--(13)-+ CHALLENGING / +-+
| | | | | | | AUTHENTICATING |
| | | | +--------------+ +----------------+
| | | (8) |
| | | | |
| | | | |
| | +-------v-------+ |
| | | <-------------------(12)-------------+
| | | ESTABLISHED |
| | | +--------------+
| | +---------------+ |
| | | |
| | (3) (5)
| | | |
| | +-------v-------+ +--------v-----+
| | | +--+ | |
| +-+ SHUTTING DOWN | | | CLOSING |
| | |(14) | |
| +-------^-------+ | +--------------+
| |----------+ |
+----------------------------------+












Oberstein & Goedde Expires April 13, 2016 [Page 34]

Internet-Draft ITMP October 2015


+----+--------------------------------------------------------------+
| # | State |
+----+--------------------------------------------------------------+
| 1 | Sent HELLO |
| 2 | Received WELCOME |
| 3 | Sent GOODBYE |
| 4 | Received GOODBYE |
| 5 | Received GOODBYE |
| 6 | Sent GOODBYE |
| 7 | Received invalid HELLO / Send ABORT |
| 8 | Received HELLO or AUTHENTICATE |
| 9 | Received other |
| 10 | Received valid HELLO [needs authentication] / Send CHALLENGE |
| 11 | Received invalid AUTHENTICATE / Send ABORT |
| 12 | Received valid AUTHENTICATE / Send WELCOME |
| 13 | Received other |
| 14 | Received other / ignore |
+----+--------------------------------------------------------------+

8. Agent Identification

When a software agent operates in a network rotocol, it often
identifies itself, its application type, operating system, software
vendor, or software revision, by submitting a characteristic
identification string to its operating peer.

Similar to what browsers do with the "User-Agent" HTTP header, both
the "HELLO" and the "WELCOME" message MAY disclose the ITMP
implementation in use to its peer:

HELLO.Details.agent|string

and

WELCOME.Details.agent|string

_Example: A Client "HELLO" message._

[1, "somerealm", {
"agent": "AutobahnJS-0.9.14",
"roles": {
"subscriber": {},
"publisher": {}
}
}]

_Example: A Router "WELCOME" message._




Oberstein & Goedde Expires April 13, 2016 [Page 35]

Internet-Draft ITMP October 2015


[2, 9129137332, {
"agent": "Crossbar.io-0.10.11",
"roles": {
"broker": {}
}
}]

9. Publish and Subscribe

All of the following features for Publish & Subscribe are mandatory
for ITMP Basic Profile implementations supporting the respective
roles, i.e. _Publisher_, _Subscriber_ and _Dealer_.

9.1. Subscribing and Unsubscribing

The message flow between Clients implementing the role of Subscriber
and Routers implementing the role of Broker for subscribing and
unsubscribing involves the following messages:

1. "SUBSCRIBE"

2. "SUBSCRIBED"

3. "UNSUBSCRIBE"

4. "UNSUBSCRIBED"

5. "ERROR"























Oberstein & Goedde Expires April 13, 2016 [Page 36]

Internet-Draft ITMP October 2015


,---------. ,------. ,----------.
|Publisher| |Broker| |Subscriber|
`----+----' `--+---' `----+-----'
| | |
| | |
| | SUBSCRIBE |
| | <---------------------
| | |
| | SUBSCRIBED or ERROR |
| | --------------------->
| | |
| | |
| | |
| | |
| | UNSUBSCRIBE |
| | <---------------------
| | |
| | UNSUBSCRIBED or ERROR|
| | --------------------->
,----+----. ,--+---. ,----+-----.
|Publisher| |Broker| |Subscriber|
`---------' `------' `----------'

A Subscriber may subscribe to zero, one or more topics, and a
Publisher publishes to topics without knowledge of subscribers.

Upon subscribing to a topic via the "SUBSCRIBE" message, a Subscriber
will receive any future events published to the respective topic by
Publishers, and will receive those events asynchronously.

A subscription lasts for the duration of a session, unless a
Subscriber opts out from a previously established subscription via
the "UNSUBSCRIBE" message.

A Subscriber may have more than one event handler attached to the
same subscription. This can be implemented in different ways: a)
a Subscriber can recognize itself that it is already subscribed
and just attach another handler to the subscription for incoming
events, b) or it can send a new "SUBSCRIBE" message to broker (as
it would be first) and upon receiving a
"SUBSCRIBED.Subscription|id" it already knows about, attach the
handler to the existing subscription

9.1.1. SUBSCRIBE

A Subscriber communicates its interest in a topic to a Broker by
sending a "SUBSCRIBE" message:




Oberstein & Goedde Expires April 13, 2016 [Page 37]

Internet-Draft ITMP October 2015


[SUBSCRIBE, Request|id, Options|dict, Topic|uri]

where

o "Request" MUST be a random, ephemeral ID chosen by the Subscriber
and used to correlate the Broker's response with the request.

o "Options" MUST be a dictionary that allows to provide additional
subscription request details in a extensible way. This is
described further below.

o "Topic" is the topic the Subscriber wants to subscribe to and MUST
be an URI.

_Example_

[32, 713845233, {}, "com.myapp.mytopic1"]

A Broker, receiving a "SUBSCRIBE" message, can fullfill or reject the
subscription, so it answers with "SUBSCRIBED" or "ERROR" messages.

9.1.2. SUBSCRIBED

If the Broker is able to fulfill and allow the subscription, it
answers by sending a "SUBSCRIBED" message to the Subscriber

[SUBSCRIBED, SUBSCRIBE.Request|id, Subscription|id]

where

o "SUBSCRIBE.Request" MUST be the ID from the original request.

o "Subscription" MUST be an ID chosen by the Broker for the
subscription.

_Example_

[33, 713845233, 5512315355]

Note. The "Subscription" ID chosen by the broker need not be
unique to the subscription of a single Subscriber, but may be
assigned to the "Topic", or the combination of the "Topic" and
some or all "Options", such as the topic pattern matching method
to be used. Then this ID may be sent to all Subscribers for the
"Topic" or "Topic" / "Options" combination. This allows the
Broker to serialize an event to be delivered only once for all
actual receivers of the event.




Oberstein & Goedde Expires April 13, 2016 [Page 38]

Internet-Draft ITMP October 2015


In case of receiving a "SUBSCRIBE" message from the same
Subscriber and to already subscribed topic, Broker should answer
with "SUBSCRIBED" message, containing the existing
"Subscription|id".

9.1.3. Subscribe ERROR

When the request for subscription cannot be fulfilled by the Broker,
the Broker sends back an "ERROR" message to the Subscriber

[ERROR, SUBSCRIBE, SUBSCRIBE.Request|id, Details|dict,
Error|uri]

where

o "SUBSCRIBE.Request" MUST be the ID from the original request.

o "Error" MUST be an URI that gives the error of why the request
could not be fulfilled.

_Example_

[8, 32, 713845233, {}, "wamp.error.not_authorized"]

9.1.4. UNSUBSCRIBE

When a Subscriber is no longer interested in receiving events for a
subscription it sends an "UNSUBSCRIBE" message

[UNSUBSCRIBE, Request|id, SUBSCRIBED.Subscription|id]

where

o "Request" MUST be a random, ephemeral ID chosen by the Subscriber
and used to correlate the Broker's response with the request.

o "SUBSCRIBED.Subscription" MUST be the ID for the subscription to
unsubscribe from, originally handed out by the Broker to the
Subscriber.

_Example_

[34, 85346237, 5512315355]








Oberstein & Goedde Expires April 13, 2016 [Page 39]

Internet-Draft ITMP October 2015


9.1.5. UNSUBSCRIBED

Upon successful unsubscription, the Broker sends an "UNSUBSCRIBED"
message to the Subscriber

[UNSUBSCRIBED, UNSUBSCRIBE.Request|id]

where

o "UNSUBSCRIBE.Request" MUST be the ID from the original request.

_Example_

[35, 85346237]

9.1.6. Unsubscribe ERROR

When the request fails, the Broker sends an "ERROR"

[ERROR, UNSUBSCRIBE, UNSUBSCRIBE.Request|id, Details|dict,
Error|uri]

where

o "UNSUBSCRIBE.Request" MUST be the ID from the original request.

o "Error" MUST be an URI that gives the error of why the request
could not be fulfilled.

_Example_

[8, 34, 85346237, {}, "wamp.error.no_such_subscription"]

9.2. Publishing and Events

The message flow between Publishers, a Broker and Subscribers for
publishing to topics and dispatching events involves the following
messages:

1. "PUBLISH"

2. "PUBLISHED"

3. "EVENT"

4. "ERROR"





Oberstein & Goedde Expires April 13, 2016 [Page 40]

Internet-Draft ITMP October 2015


,---------. ,------. ,----------.
|Publisher| |Broker| |Subscriber|
`----+----' `--+---' `----+-----'
| PUBLISH | |
|------------------> |
| | |
|PUBLISHED or ERROR| |
|<------------------ |
| | |
| | EVENT |
| | ------------------>
,----+----. ,--+---. ,----+-----.
|Publisher| |Broker| |Subscriber|
`---------' `------' `----------'

9.2.1. PUBLISH

When a Publisher requests to publish an event to some topic, it sends
a "PUBLISH" message to a Broker:

[PUBLISH, Request|id, Options|dict, Topic|uri]

or

[PUBLISH, Request|id, Options|dict, Topic|uri, Arguments|list]

or

[PUBLISH, Request|id, Options|dict, Topic|uri, Arguments|list,
ArgumentsKw|dict]

where

o "Request" is a random, ephemeral ID chosen by the Publisher and
used to correlate the Broker's response with the request.

o "Options" is a dictionary that allows to provide additional
publication request details in an extensible way. This is
described further below.

o "Topic" is the topic published to.

o "Arguments" is a list of application-level event payload elements.
The list may be of zero length.

o "ArgumentsKw" is an optional dictionary containing application-
level event payload, provided as keyword arguments. The
dictionary may be empty.



Oberstein & Goedde Expires April 13, 2016 [Page 41]

Internet-Draft ITMP October 2015


If the Broker is able to fulfill and allowing the publication, the
Broker will send the event to all current Subscribers of the topic of
the published event.

By default, publications are unacknowledged, and the Broker will not
respond, whether the publication was successful indeed or not. This
behavior can be changed with the option
"PUBLISH.Options.acknowledge|bool" (see below).

_Example_

[16, 239714735, {}, "com.myapp.mytopic1"]

_Example_

[16, 239714735, {}, "com.myapp.mytopic1", ["Hello, world!"]]

_Example_

[16, 239714735, {}, "com.myapp.mytopic1", [], {"color": "orange",
"sizes": [23, 42, 7]}]

9.2.2. PUBLISHED

If the Broker is able to fulfill and allowing the publication, and
"PUBLISH.Options.acknowledge == true", the Broker replies by sending
a "PUBLISHED" message to the Publisher:

[PUBLISHED, PUBLISH.Request|id, Publication|id]

where

o "PUBLISH.Request" is the ID from the original publication request.

o "Publication" is a ID chosen by the Broker for the publication.

_Example_

[17, 239714735, 4429313566]

9.2.3. Publish ERROR

When the request for publication cannot be fulfilled by the Broker,
and "PUBLISH.Options.acknowledge == true", the Broker sends back an
"ERROR" message to the Publisher

[ERROR, PUBLISH, PUBLISH.Request|id, Details|dict, Error|uri]




Oberstein & Goedde Expires April 13, 2016 [Page 42]

Internet-Draft ITMP October 2015


where

o "PUBLISH.Request" is the ID from the original publication request.

o "Error" is an URI that gives the error of why the request could
not be fulfilled.

_Example_

[8, 16, 239714735, {}, "wamp.error.not_authorized"]

9.2.4. EVENT

When a publication is successful and a Broker dispatches the event, it determines a list of receivers for the event based on Subscribers for the topic published to and, possibly, other information in the
event.

Note that the Publisher of an event will never receive the published event even if the Publisher is also a Subscriber of the topic published to.

The Advanced Profile provides options for more detailed control over publication.

When a Subscriber is deemed to be a receiver, the Broker sends the
Subscriber an "EVENT" message:

[EVENT, SUBSCRIBED.Subscription|id, PUBLISHED.Publication|id,
Details|dict]

or

[EVENT, SUBSCRIBED.Subscription|id, PUBLISHED.Publication|id,
Details|dict, PUBLISH.Arguments|list]

or

[EVENT, SUBSCRIBED.Subscription|id, PUBLISHED.Publication|id,
Details|dict, PUBLISH.Arguments|list, PUBLISH.ArgumentKw|dict]

where

o "SUBSCRIBED.Subscription" is the ID for the subscription under
which the Subscriber receives the event - the ID for the
subscription originally handed out by the Broker to the
Subscribe*.




Oberstein & Goedde Expires April 13, 2016 [Page 43]

Internet-Draft ITMP October 2015


o "PUBLISHED.Publication" is the ID of the publication of the
published event.

o "Details" is a dictionary that allows the Broker to provide
additional event details in a extensible way. This is described
further below.

o "PUBLISH.Arguments" is the application-level event payload that
was provided with the original publication request.

o "PUBLISH.ArgumentKw" is the application-level event payload that
was provided with the original publication request.

_Example_

[36, 5512315355, 4429313566, {}]

_Example_

[36, 5512315355, 4429313566, {}, ["Hello, world!"]]

_Example_

[36, 5512315355, 4429313566, {}, [], {"color": "orange",
"sizes": [23, 42, 7]}]

10. Remote Procedure Calls

All of the following features for Remote Procedure Calls are
mandatory for ITMP Basic Profile implementations supporting the
respective roles.

10.1. Registering and Unregistering

The message flow between Callees and a Dealer for registering and
unregistering endpoints to be called over RPC involves the following
messages:

1. "REGISTER"

2. "REGISTERED"

3. "UNREGISTER"

4. "UNREGISTERED"

5. "ERROR"




Oberstein & Goedde Expires April 13, 2016 [Page 44]

Internet-Draft ITMP October 2015


,------. ,------. ,------.
|Caller| |Dealer| |Callee|
`--+---' `--+---' `--+---'
| | |
| | |
| | REGISTER |
| | <---------------------
| | |
| | REGISTERED or ERROR |
| | --------------------->
| | |
| | |
| | |
| | |
| | |
| | UNREGISTER |
| | <---------------------
| | |
| | UNREGISTERED or ERROR|
| | --------------------->
,--+---. ,--+---. ,--+---.
|Caller| |Dealer| |Callee|
`------' `------' `------'

10.1.1. REGISTER

A Callee announces the availability of an endpoint implementing a
procedure with a Dealer by sending a "REGISTER" message:

[REGISTER, Request|id, Options|dict, Procedure|uri]

where

o "Request" is a random, ephemeral ID chosen by the Callee and used
to correlate the Dealer's response with the request.

o "Options" is a dictionary that allows to provide additional
registration request details in a extensible way. This is
described further below.

o "Procedure"is the procedure the Callee wants to register

_Example_

[64, 25349185, {}, "com.myapp.myprocedure1"]






Oberstein & Goedde Expires April 13, 2016 [Page 45]

Internet-Draft ITMP October 2015


10.1.2. REGISTERED

If the Dealer is able to fulfill and allowing the registration, it
answers by sending a "REGISTERED" message to the "Callee":

[REGISTERED, REGISTER.Request|id, Registration|id]

where

o "REGISTER.Request" is the ID from the original request.

o "Registration" is an ID chosen by the Dealer for the registration.

_Example_

[65, 25349185, 2103333224]

10.1.3. Register ERROR

When the request for registration cannot be fulfilled by the Dealer,
the Dealer sends back an "ERROR" message to the Callee:

[ERROR, REGISTER, REGISTER.Request|id, Details|dict, Error|uri]

where

o "REGISTER.Request" is the ID from the original request.

o "Error" is an URI that gives the error of why the request could
not be fulfilled.

_Example_

[8, 64, 25349185, {}, "wamp.error.procedure_already_exists"]

10.1.4. UNREGISTER

When a Callee is no longer willing to provide an implementation of
the registered procedure, it sends an "UNREGISTER" message to the
Dealer:

[UNREGISTER, Request|id, REGISTERED.Registration|id]

where

o "Request" is a random, ephemeral ID chosen by the Callee and used
to correlate the Dealer's response with the request.




Oberstein & Goedde Expires April 13, 2016 [Page 46]

Internet-Draft ITMP October 2015


o "REGISTERED.Registration" is the ID for the registration to
revoke, originally handed out by the Dealer to the Callee.

_Example_

[66, 788923562, 2103333224]

10.1.5. UNREGISTERED

Upon successful unregistration, the Dealer sends an "UNREGISTERED"
message to the Callee:

[UNREGISTERED, UNREGISTER.Request|id]

where

o "UNREGISTER.Request" is the ID from the original request.

_Example_

[67, 788923562]

10.1.6. Unregister ERROR

When the unregistration request fails, the Dealer sends an "ERROR"
message:

[ERROR, UNREGISTER, UNREGISTER.Request|id, Details|dict,
Error|uri]

where

o "UNREGISTER.Request" is the ID from the original request.

o "Error" is an URI that gives the error of why the request could
not be fulfilled.

_Example_

[8, 66, 788923562, {}, "wamp.error.no_such_registration"]

10.2. Calling and Invocations

The message flow between Callers, a Dealer and Callees for calling
procedures and invoking endpoints involves the following messages:

1. "CALL"




Oberstein & Goedde Expires April 13, 2016 [Page 47]

Internet-Draft ITMP October 2015


2. "RESULT"

3. "INVOCATION"

4. "YIELD"

5. "ERROR"

,------. ,------. ,------.
|Caller| |Dealer| |Callee|
`--+---' `--+---' `--+---'
| CALL | |
| ----------------> |
| | |
| | INVOCATION |
| | ---------------->
| | |
| | YIELD or ERROR |
| | <----------------
| | |
| RESULT or ERROR | |
| <---------------- |
,--+---. ,--+---. ,--+---.
|Caller| |Dealer| |Callee|
`------' `------' `------'

The execution of remote procedure calls is asynchronous, and there
may be more than one call outstanding. A call is called outstanding
(from the point of view of the Caller), when a (final) result or
error has not yet been received by the Caller.

10.2.1. CALL

When a Caller wishes to call a remote procedure, it sends a "CALL"
message to a Dealer:

[CALL, Request|id, Options|dict, Procedure|uri]

or

[CALL, Request|id, Options|dict, Procedure|uri, Arguments|list]

or

[CALL, Request|id, Options|dict, Procedure|uri, Arguments|list,
ArgumentsKw|dict]

where


o "Request" is a random, ephemeral ID chosen by the Caller and used
to correlate the Dealer's response with the request.

o "Options" is a dictionary that allows to provide additional call
request details in an extensible way. This is described further
below.

o "Procedure" is the URI of the procedure to be called.

o "Arguments" is a list of positional call arguments (each of
arbitrary type). The list may be of zero length.

_Example_

[48, 7814135, {}, "com.myapp.ping"]

_Example_

[48, 7814135, {}, "com.myapp.echo", ["Hello, world!"]]

_Example_

[48, 7814135, {}, "com.myapp.add2", [23, 7]]

_Example_

[48, 7814135, {}, "com.myapp.user.new", ["johnny"],
{"firstname": "John", "surname": "Doe"}]

10.2.2. INVOCATION

If the Dealer is able to fulfill (mediate) the call and it allows the
call, it sends a "INVOCATION" message to the respective Callee
implementing the procedure:

[INVOCATION, Request|id, REGISTERED.Registration|id,
Details|dict]

or

[INVOCATION, Request|id, REGISTERED.Registration|id,
Details|dict, CALL.Arguments|list]

or

[INVOCATION, Request|id, REGISTERED.Registration|id,
Details|dict, CALL.Arguments|list, CALL.ArgumentsKw|dict]

where

o "Request" is a random, ephemeral ID chosen by the Dealer and used
to correlate the _Callee's_ response with the request.

o "REGISTERED.Registration" is the registration ID under which the
procedure was registered at the Dealer.

o "Details" is a dictionary that allows to provide additional invocation request details in an extensible way. This is described further below.

o "CALL.Arguments" is the original list of positional call arguments as provided by the Caller.

o "CALL.ArgumentsKw" is the original dictionary of keyword call arguments as provided by the Caller.

_Example_

[68, 6131533, 9823526, {}]

_Example_

[68, 6131533, 9823527, {}, ["Hello, world!"]]

_Example_

[68, 6131533, 9823528, {}, [23, 7]]

_Example_

[68, 6131533, 9823529, {}, ["johnny"], {"firstname": "John",
"surname": "Doe"}]

10.2.3. YIELD

If the Callee is able to successfully process and finish the
execution of the call, it answers by sending a "YIELD" message to the
Dealer:

[YIELD, INVOCATION.Request|id, Options|dict]

or




Oberstein & Goedde Expires April 13, 2016 [Page 50]

Internet-Draft ITMP October 2015


[YIELD, INVOCATION.Request|id, Options|dict, Arguments|list]

or

[YIELD, INVOCATION.Request|id, Options|dict, Arguments|list,
ArgumentsKw|dict]

where

o "INVOCATION.Request" is the ID from the original invocation
request.

o "Options"is a dictionary that allows to provide additional
options.

o "Arguments" is a list of positional result elements (each of
arbitrary type). The list may be of zero length.

o "ArgumentsKw" is a dictionary of keyword result elements (each of
arbitrary type). The dictionary may be empty.

_Example_

[70, 6131533, {}]

_Example_

[70, 6131533, {}, ["Hello, world!"]]

_Example_

[70, 6131533, {}, [30]]

_Example_

[70, 6131533, {}, [], {"userid": 123, "karma": 10}]

10.2.4. RESULT

The Dealer will then send a "RESULT" message to the original Caller:

[RESULT, CALL.Request|id, Details|dict]

or

[RESULT, CALL.Request|id, Details|dict, YIELD.Arguments|list]

or



Oberstein & Goedde Expires April 13, 2016 [Page 51]

Internet-Draft ITMP October 2015


[RESULT, CALL.Request|id, Details|dict, YIELD.Arguments|list,
YIELD.ArgumentsKw|dict]

where

o "CALL.Request" is the ID from the original call request.

o "Details" is a dictionary of additional details.

o "YIELD.Arguments" is the original list of positional result
elements as returned by the Callee.

o "YIELD.ArgumentsKw" is the original dictionary of keyword result
elements as returned by the Callee.

_Example_

[50, 7814135, {}]

_Example_

[50, 7814135, {}, ["Hello, world!"]]

_Example_

[50, 7814135, {}, [30]]

_Example_

[50, 7814135, {}, [], {"userid": 123, "karma": 10}]

10.2.5. Invocation ERROR

If the Callee is unable to process or finish the execution of the
call, or the application code implementing the procedure raises an
exception or otherwise runs into an error, the Callee sends an
"ERROR" message to the Dealer:

[ERROR, INVOCATION, INVOCATION.Request|id, Details|dict,
Error|uri]

or

[ERROR, INVOCATION, INVOCATION.Request|id, Details|dict,
Error|uri, Arguments|list]

or




Oberstein & Goedde Expires April 13, 2016 [Page 52]

Internet-Draft ITMP October 2015


[ERROR, INVOCATION, INVOCATION.Request|id, Details|dict,
Error|uri, Arguments|list, ArgumentsKw|dict]

where

o "INVOCATION.Request" is the ID from the original "INVOCATION"
request previously sent by the Dealer to the Callee.

o "Details" is a dictionary with additional error details.

o "Error" is an URI that identifies the error of why the request
could not be fulfilled.

o "Arguments" is a list containing arbitrary, application defined,
positional error information. This will be forwarded by the
Dealer to the Caller that initiated the call.

o "ArgumentsKw" is a dictionary containing arbitrary, application
defined, keyword-based error information. This will be forwarded
by the Dealer to the Caller that initiated the call.

_Example_

[8, 68, 6131533, {}, "com.myapp.error.object_write_protected",
["Object is write protected."], {"severity": 3}]

10.2.6. Call ERROR

The Dealer will then send a "ERROR" message to the original Caller:

[ERROR, CALL, CALL.Request|id, Details|dict, Error|uri]

or

[ERROR, CALL, CALL.Request|id, Details|dict, Error|uri,
Arguments|list]

or

[ERROR, CALL, CALL.Request|id, Details|dict, Error|uri,
Arguments|list, ArgumentsKw|dict]

where

o "CALL.Request" is the ID from the original "CALL" request sent by
the Caller to the Dealer.

o "Details" is a dictionary with additional error details.



Oberstein & Goedde Expires April 13, 2016 [Page 53]

Internet-Draft ITMP October 2015


o "Error" is an URI identifying the type of error as returned by the
Callee to the Dealer.

o "Arguments" is a list containing the original error payload list
as returned by the Callee to the Dealer.

o "ArgumentsKw" is a dictionary containing the original error
payload dictionary as returned by the Callee to the Dealer

_Example_

[8, 48, 7814135, {}, "com.myapp.error.object_write_protected",
["Object is write protected."], {"severity": 3}]

If the original call already failed at the Dealer *before* the call
would have been forwarded to any Callee, the Dealer will send an
"ERROR" message to the Caller:

[ERROR, CALL, CALL.Request|id, Details|dict, Error|uri]

_Example_

[8, 48, 7814135, {}, "wamp.error.no_such_procedure"]

11. Predefined URIs

ITMP pre-defines the following error URIs for the basic and for the
advanced profile. ITMP peers MUST use only the defined error
messages.

11.1. Basic Profile

11.1.1. Incorrect URIs

When a Peer provides an incorrect URI for any URI-based attribute of
a ITMP message (e.g. realm, topic), then the other Peer MUST respond
with an "ERROR" message and give the following _Error URI_:

wamp.error.invalid_uri

11.1.2. Interaction

Peer provided an incorrect URI for any URI-based attribute of ITMP
message, such as realm, topic or procedure

wamp.error.invalid_uri





Oberstein & Goedde Expires April 13, 2016 [Page 54]

Internet-Draft ITMP October 2015


A Dealer could not perform a call, since no procedure is currently
registered under the given URI.

wamp.error.no_such_procedure

A procedure could not be registered, since a procedure with the given
URI is already registered.

wamp.error.procedure_already_exists

A Dealer could not perform an unregister, since the given
registration is not active.

wamp.error.no_such_registration

A Broker could not perform an unsubscribe, since the given
subscription is not active.

wamp.error.no_such_subscription

A call failed since the given argument types or values are not
acceptable to the called procedure. In this case the Callee may
throw this error. Alternatively a Router may throw this error if it
performed _payload validation_ of a call, call result, call error or
publish, and the payload did not conform to the requirements.

wamp.error.invalid_argument

11.1.3. Session Close

The Peer is shutting down completely - used as a "GOODBYE" (or
"ABORT") reason.

wamp.error.system_shutdown

The Peer want to leave the realm - used as a "GOODBYE" reason.

wamp.error.close_realm

A Peer acknowledges ending of a session - used as a "GOODBYE" reply
reason.

wamp.error.goodbye_and_out








Oberstein & Goedde Expires April 13, 2016 [Page 55]

Internet-Draft ITMP October 2015


11.1.4. Authorization

A join, call, register, publish or subscribe failed, since the Peer
is not authorized to perform the operation.

wamp.error.not_authorized

A Dealer or Broker could not determine if the Peer is authorized to
perform a join, call, register, publish or subscribe, since the
authorization operation _itself_ failed. E.g. a custom authorizer
did run into an error.

wamp.error.authorization_failed

Peer wanted to join a non-existing realm (and the Router did not
allow to auto-create the realm).

wamp.error.no_such_realm

A Peer was to be authenticated under a Role that does not (or no
longer) exists on the Router. For example, the Peer was successfully
authenticated, but the Role configured does not exists - hence there
is some misconfiguration in the Router.

wamp.error.no_such_role

11.2. Advanced Profile

uri_Dealer_ or _Callee_ canceled a call previously issued

wamp.error.canceled

A _Peer_ requested an interaction with an option that was disallowed
by the _Router_

wamp.error.option_not_allowed

A _Dealer_ could not perform a call, since a procedure with the given
URI is registered, but _Callee Black- and Whitelisting_ and/or
_Caller Exclusion_ lead to the exclusion of (any) _Callee_ providing
the procedure.

wamp.error.no_eligible_callee

A _Router_ rejected client request to disclose its identity

wamp.error.option_disallowed.disclose_me




Oberstein & Goedde Expires April 13, 2016 [Page 56]

Internet-Draft ITMP October 2015


A _Router_ encountered a network failure

wamp.error.network_failure

12. Ordering Guarantees

All ITMP implementations, in particular Routers MUST support the
following ordering guarantees.

A ITMP Advanced Profile may provide applications options to relax
ordering guarantees, in particular with distributed calls.

12.1. Publish & Subscribe Ordering

Regarding *Publish & Subscribe*, the ordering guarantees are as
follows:

If _Subscriber A_ is subscribed to both *Topic 1* and *Topic 2*, and
_Publisher B_ first publishes an *Event 1* to *Topic 1* and then an
*Event 2* to *Topic 2*, then _Subscriber A_ will first receive *Event
1* and then *Event 2*. This also holds if *Topic 1* and *Topic 2* are
identical.

In other words, ITMP guarantees ordering of events between any given
_pair_ of Publisher and Subscriber.

Further, if _Subscriber A_ subscribes to *Topic 1*, the "SUBSCRIBED"
message will be sent by the _Broker_ to _Subscriber A_ before any
"EVENT" message for *Topic 1*.

There is no guarantee regarding the order of return for multiple
subsequent subscribe requests. A subscribe request might require the
_Broker_ to do a time-consuming lookup in some database, whereas
another subscribe request second might be permissible immediately.

12.2. Remote Procedure Call Ordering

Regarding *Remote Procedure Calls*, the ordering guarantees are as
follows:

If _Callee A_ has registered endpoints for both *Procedure 1* and
*Procedure 2*, and _Caller B_ first issues a *Call 1* to *Procedure
1* and then a *Call 2* to *Procedure 2*, and both calls are routed to
_Callee A_, then _Callee A_ will first receive an invocation
corresponding to *Call 1* and then *Call 2*. This also holds if
*Procedure 1* and *Procedure 2* are identical.





Oberstein & Goedde Expires April 13, 2016 [Page 57]

Internet-Draft ITMP October 2015


In other words, ITMP guarantees ordering of invocations between any
given _pair_ of Caller and Callee.

There are no guarantees on the order of call results and errors in
relation to _different_ calls, since the execution of calls upon
different invocations of endpoints in Callees are running
independently. A first call might require an expensive, long-running
computation, whereas a second, subsequent call might finish
immediately.

Further, if _Callee A_ registers for *Procedure 1*, the "REGISTERED"
message will be sent by _Dealer_ to _Callee A_ before any
"INVOCATION" message for *Procedure 1*.

There is no guarantee regarding the order of return for multiple
subsequent register requests. A register request might require the
_Broker_ to do a time-consuming lookup in some database, whereas
another register request second might be permissible immediately.

13. Security Model

The following discusses the security model for the Basic Profile.
Any changes or extensions to this for the Advanced Profile are
discussed further on as part of the Advanced Profile definition.

13.1. Transport Encryption and Integrity

ITMP transports may provide (optional) transport-level encryption and
integrity verification. If so, encryption and integrity is point-to-
point: between a Client and the Router it is connected to.

Transport-level encryption and integrity is solely at the transport-
level and transparent to ITMP. ITMP itself deliberately does not
specify any kind of transport-level encryption.

Implementations that offer TCP based transport such as ITMP-over-
WebSocket or ITMP-over-RawSocket SHOULD implement Transport Layer
Security (TLS).

ITMP deployments are encouraged to stick to a TLS-only policy with
the TLS code and setup being hardened.

Further, when a Client connects to a Router over a local-only
transport such as Unix domain sockets, the integrity of the data
transmitted is implicit (the OS kernel is trusted), and the privacy
of the data transmitted can be assured using file system permissions
(no one can tap a Unix domain socket without appropriate permissions
or being root).



Oberstein & Goedde Expires April 13, 2016 [Page 58]

Internet-Draft ITMP October 2015


13.2. Router Authentication

To authenticate Routers to Clients, deployments MUST run TLS and
Clients MUST verify the Router server certificate presented. ITMP
itself does not provide mechanisms to authenticate a Router (only a
Client).

The verification of the Router server certificate can happen

1. against a certificate trust database that comes with the Clients
operating system

2. against an issuing certificate/key hard-wired into the Client

3. by using new mechanisms like DNS-based Authentication of Named
Enitities (DNSSEC)/TLSA

Further, when a Client connects to a Router over a local-only
transport such as Unix domain sockets, the file system permissions
can be used to create implicit trust. E.g. if only the OS user under
which the Router runs has the permission to create a Unix domain
socket under a specific path, Clients connecting to that path can
trust in the router authenticity.

13.3. Client Authentication

Authentication of a Client to a Router at the ITMP level is not part
of the basic profile.

When running over TLS, a Router MAY authenticate a Client at the
transport level by doing a _client certificate based authentication_.

13.3.1. Routers are trusted

Routers are _trusted_ by Clients.

In particular, Routers can read (and modify) any application payload
transmitted in events, calls, call results and call errors (the
"Arguments" or "ArgumentsKw" message fields).

Hence, Routers do not provide confidentiality with respect to
application payload, and also do not provide authenticity or
integrity of application payloads that could be verified by a
receiving Client.

Routers need to read the application payloads in cases of automatic
conversion between different serialization formats.




Oberstein & Goedde Expires April 13, 2016 [Page 59]

Internet-Draft ITMP October 2015


Further, Routers are trusted to *actually perform* routing as
specified. E.g. a Client that publishes an event has to trust a
Router that the event is actually dispatched to all (eligible)
Subscribers by the Router.

A rogue Router might deny normal routing operation without a Client
taking notice.

14. Advanced Profile

While implementations MUST implement the subset of the Basic Profile
necessary for the particular set of ITMP roles they provide, they MAY
implement any subset of features from the Advanced Profile.
Implementers SHOULD implement the maximum of features possible
considering the aims of an implementation.

Note: Features listed here may be experimental or underspecced and
yet unimplemented in any implementation. This is part of the
specification is very much a work in progress. An approximate
status of each feature is given at the beginning of the feature
section.

14.1. Messages

The Advanced Profile defines the following additional messages which
are explained in detail in separate sections.

14.1.1. Message Definitions

The following 4 additional message types MAY be used in the Advanced
Profile.

14.1.1.1. CHALLENGE

The "CHALLENGE" message is used with certain Authentication Methods.
During authenticated session establishment, a *Router* sends a
challenge message.

[CHALLENGE, AuthMethod|string, Extra|dict]

14.1.1.2. AUTHENTICATE

The "AUTHENTICATE" message is used with certain Authentication
Methods. A *Client* having received a challenge is expected to
respond by sending a signature or token.

[AUTHENTICATE, Signature|string, Extra|dict]




Oberstein & Goedde Expires April 13, 2016 [Page 60]

Internet-Draft ITMP October 2015


14.1.1.3. CANCEL

The "CANCEL" message is used with the Call Canceling advanced
feature. A _Caller_ can cancel and issued call actively by sending a
cancel message to the _Dealer_.

[CANCEL, CALL.Request|id, Options|dict]

14.1.1.4. INTERRUPT

The "INTERRUPT" message is used with the Call Canceling advanced
feature. Upon receiving a cancel for a pending call, a _Dealer_ will
issue an interrupt to the _Callee_.

[INTERRUPT, INVOCATION.Request|id, Options|dict]

14.1.2. Message Codes and Direction

The following table list the message type code for *the OPTIONAL
messages* defined in this part of the document and their direction
between peer roles.

+-----+----------------+-----+-----+------+------+-------+--------+
| Cod | Message | Pub | Brk | Subs | Calr | Dealr | Callee |
+-----+----------------+-----+-----+------+------+-------+--------+
| 4 | "CHALLENGE" | Rx | Tx | Rx | Rx | Tx | Rx |
| 5 | "AUTHENTICATE" | Tx | Rx | Tx | Tx | Rx | Tx |
| 49 | "CANCEL" | | | | Tx | Rx | |
| 69 | "INTERRUPT" | | | | | Tx | Rx |
+-----+----------------+-----+-----+------+------+-------+--------+

"Tx" ("Rx") means the message is sent (received) by a peer of the
respective role.

14.2. Features

Support for advanced features must be announced by the peers which
implement them. The following is a complete list of advanced
features currently defined or proposed.












Oberstein & Goedde Expires April 13, 2016 [Page 61]

Internet-Draft ITMP October 2015


+--------+----------------------------------------------------------+
| Status | Description |
+--------+----------------------------------------------------------+
| sketch | There is a rough description of an itch to scratch, but |
| | the feature use case isn't clear, and there is no |
| | protocol proposal at all. |
| alpha | The feature use case is still fuzzy and/or the feature |
| | definition is unclear, but there is at least a protocol |
| | level proposal. |
| beta | The feature use case is clearly defined and the feature |
| | definition in the spec is sufficient to write a |
| | prototype implementation. The feature definition and |
| | details may still be incomplete and change. |
| stable | The feature definition in the spec is complete and |
| | stable and the feature use case is field proven in real |
| | applications. There are multiple, interoperatble |
| | implementations. |
+--------+----------------------------------------------------------+

14.2.1. RPC Features

+----------------------------+--------+---+---+---+----+---+----+
| Feature | Status | P | B | S | Cr | D | Ce |
+----------------------------+--------+---+---+---+----+---+----+
| progressive_call_results | beta | | | | X | X | X |
| progressive_calls | sketch | | | | X | X | X |
| call_timeout | alpha | | | | X | X | X |
| call_canceling | alpha | | | | X | X | X |
| caller_identification | alpha | | | | X | X | X |
| call_trustlevels | alpha | | | | | X | X |
| registration_meta_api | beta | | | | | X | |
| pattern_based_registration | beta | | | | | X | X |
| shared_registration | beta | | | | | X | X |
| sharded_registration | alpha | | | | | X | X |
| registration_revocation | alpha | | | | | X | X |
| procedure_reflection | sketch | | | | | X | |
+----------------------------+--------+---+---+---+----+---+----+

14.2.2. PubSub Features












Oberstein & Goedde Expires April 13, 2016 [Page 62]

Internet-Draft ITMP October 2015


+-------------------------------+--------+---+---+---+----+---+----+
| Feature | Status | P | B | S | Cr | D | Ce |
+-------------------------------+--------+---+---+---+----+---+----+
| subscriber_blackwhite_listing | stable | X | X | | | | |
| publisher_exclusion | stable | X | X | | | | |
| publisher_identification | alpha | X | X | X | | | |
| publication_trustlevels | alpha | | X | X | | | |
| subscription_meta_api | beta | | X | | | | |
| pattern_based_subscription | beta | | X | X | | | |
| sharded_subscription | alpha | | X | X | | | |
| event_history | alpha | | X | X | | | |
| topic_reflection | sketch | | X | | | | |
+-------------------------------+--------+---+---+---+----+---+----+

14.2.3. Other Advanced Features

+-----------------------------------+--------+
| Feature | Status |
+-----------------------------------+--------+
| challenge-response authentication | beta |
| cookie authentication | beta |
| ticket authentication | beta |
| rawsocket transport | stable |
| batched WS transport | sketch |
| longpoll transport | beta |
| session meta api | beta |
+-----------------------------------+--------+

14.3. Advanced RPC Features

14.3.1. Progressive Call Results

14.3.1.1. Feature Definition

A procedure implemented by a _Callee_ and registered at a _Dealer_
may produce progressive results. Progressive results can e.g. be
used to return partial results for long-running operations, or to
chunk the transmission of larger results sets.

The message flow for progressive results involves:

,------. ,------. ,------.
|Caller| |Dealer| |Callee|
`--+---' `--+---' `--+---'
| CALL | |
| -----------------> |
| | |
| | INVOCATION |
| | ---------------->
| | |
| | YIELD (progress)|
| | <----------------
| | |
| RESULT (progress)| |
| <----------------- |
| | |
| | YIELD (progress)|
| | <----------------
| | |
| RESULT (progress)| |
| <----------------- |
| | |
| | |
| ... | ... |
| | |
| | YIELD or ERROR |
| | <----------------
| | |
| RESULT or ERROR | |
| <----------------- |
,--+---. ,--+---. ,--+---.
|Caller| |Dealer| |Callee|
`------' `------' `------'

A _Caller_ indicates its willingness to receive progressive results
by setting

CALL.Options.receive_progress|bool := true

_Example._ Caller-to-Dealer "CALL"












Oberstein & Goedde Expires April 13, 2016 [Page 64]

Internet-Draft ITMP October 2015


[
48,
77133,
{
"receive_progress": true
},
"com.myapp.compute_revenue",
[2010, 2011, 2012]
]

If the _Callee_ supports progressive calls, the _Dealer_ will forward
the _Caller's_ willingness to receive progressive results by setting

INVOCATION.Options.receive_progress|bool := true

_Example._ Dealer-to-Callee "INVOCATION"

[
68,
87683,
324,
{
"receive_progress": true
},
[2010, 2011, 2012]
]

An endpoint implementing the procedure produces progressive results
by sending "YIELD" messages to the _Dealer_ with

YIELD.Options.progress|bool := true

_Example._ Callee-to-Dealer progressive "YIELDs"

[
70,
87683,
{
"progress": true
},
["Y2010", 120]
]









Oberstein & Goedde Expires April 13, 2016 [Page 65]

Internet-Draft ITMP October 2015


[
70,
87683,
{
"progress": true
},
["Y2011", 205]
]

Upon receiving an "YIELD" message from a _Callee_ with
"YIELD.Options.progress == true" (for a call that is still ongoing),
the _Dealer_ will *immediately* send a "RESULT" message to the
original _Caller_ with

RESULT.Details.progress|bool := true

_Example._ Dealer-to-Caller progressive "RESULTs"

[
50,
77133,
{
"progress": true
},
["Y2010", 120]
]

[
50,
77133,
{
"progress": true
},
["Y2011", 205]
]

...

An invocation MUST _always_ end in either a _normal_ "RESULT" or
"ERROR" message being sent by the _Callee_ and received by the
_Dealer_.

_Example._ Callee-to-Dealer final "YIELD"








Oberstein & Goedde Expires April 13, 2016 [Page 66]

Internet-Draft ITMP October 2015


[
70,
87683,
{},
["Total", 490]
]

_Example._ Callee-to-Dealer final "ERROR"

[
4,
87683,
{},
"com.myapp.invalid_revenue_year",
[1830]
]

A call MUST _always_ end in either a _normal_ "RESULT" or "ERROR"
message being sent by the _Dealer_ and received by the _Caller_.

_Example._ Dealer-to-Caller final "RESULT"

[
50,
77133,
{},
["Total", 490]
]

_Example._ Dealer-to-Caller final "ERROR"

[
4,
77133,
{},
"com.myapp.invalid_revenue_year",
[1830]
]

In other words: "YIELD" with "YIELD.Options.progress == true" and
"RESULT" with "RESULT.Details.progress == true" messages may only be
sent _during_ a call or invocation is still ongoing.

The final "YIELD" and final "RESULT" may also be empty, e.g. when all
actual results have already been transmitted in progressive result
messages.

_Example._ Callee-to-Dealer "YIELDs"



Oberstein & Goedde Expires April 13, 2016 [Page 67]

Internet-Draft ITMP October 2015


[70, 87683, {"progress": true}, ["Y2010", 120]]
[70, 87683, {"progress": true}, ["Y2011", 205]]
...
[70, 87683, {"progress": true}, ["Total", 490]]
[70, 87683, {}]

_Example._ Dealer-to-Caller "RESULTs"

[50, 77133, {"progress": true}, ["Y2010", 120]]
[50, 77133, {"progress": true}, ["Y2011", 205]]
...
[50, 77133, {"progress": true}, ["Total", 490]]
[50, 77133, {}]

The progressive "YIELD" and progressive "RESULT" may also be empty,
e.g. when those messages are only used to signal that the procedure
is still running and working, and the actual result is completely
delivered in the final "YIELD" and "RESULT":

_Example._ Callee-to-Dealer "YIELDs"

[70, 87683, {"progress": true}]
[70, 87683, {"progress": true}]
...
[70, 87683, {}, [["Y2010", 120], ["Y2011", 205], ...,
["Total", 490]]]

_Example._ Dealer-to-Caller "RESULTs"

[50, 77133, {"progress": true}]
[50, 77133, {"progress": true}]
...
[50, 77133, {}, [["Y2010", 120], ["Y2011", 205], ...,
["Total", 490]]]

Note that intermediate, progressive results and/or the final
result MAY have different structure. The ITMP peer implementation
is responsible for mapping everything into a form suitable for
consumption in the host language.

_Example._ Callee-to-Dealer "YIELDs"

[70, 87683, {"progress": true}, ["partial 1", 10]]
[70, 87683, {"progress": true}, [], {"foo": 10,
"bar": "partial 1"}]
...
[70, 87683, {}, [1, 2, 3], {"moo": "hello"}]




Oberstein & Goedde Expires April 13, 2016 [Page 68]

Internet-Draft ITMP October 2015


_Example._ Dealer-to-Caller "RESULTs"

[50, 77133, {"progress": true}, ["partial 1", 10]]
[50, 77133, {"progress": true}, [], {"foo": 10,
"bar": "partial 1"}]
...
[50, 77133, {}, [1, 2, 3], {"moo": "hello"}]

Even if a _Caller_ has indicated it's expectation to receive
progressive results by setting "CALL.Options.receive_progress|bool :=
true", a _Callee_ is *not required* to produce progressive results.
"CALL.Options.receive_progress" and
"INVOCATION.Options.receive_progress" are simply indications that the
_Caller_ is prepared to process progressive results, should there be
any produced. In other words, _Callees_ are free to ignore such
"receive_progress" hints at any time.

14.3.1.2. Feature Announcement

Support for this advanced feature MUST be announced by _Callers_
("role := "caller""), _Callees_ ("role := "callee"") and _Dealers_
("role := "dealer"") via

HELLO.Details.roles.<role>.features.
progressive_call_results|bool := true

14.3.2. Progressive Calls

14.3.2.1. Feature Definition

A procedure implemented by a _Callee_ and registered at a _Dealer_
may receive a progressive call. Progressive results can e.g. be used
to start processing initial data where a larger data set may not yet
have been generated or received by the _Caller_.

See this GitHub issue for more discussion: <https://github.com/wamp-
proto/wamp-proto/issues/167>

14.3.3. Call Timeouts

14.3.3.1. Feature Definition

A _Caller_ might want to issue a call providing a _timeout_ for the
call to finish.

A _timeout_ allows to *automatically* cancel a call after a specified
time either at the _Callee_ or at the _Dealer_.




Oberstein & Goedde Expires April 13, 2016 [Page 69]

Internet-Draft ITMP October 2015


A _Caller_ specifies a timeout by providing

CALL.Options.timeout|integer

in ms. A timeout value of "0" deactivates automatic call timeout.
This is also the default value.

The timeout option is a companion to, but slightly different from the
"CANCEL" and "INTERRUPT" messages that allow a _Caller_ and _Dealer_
to *actively* cancel a call or invocation.

In fact, a timeout timer might run at three places:

o _Caller_

o _Dealer_

o _Callee_

14.3.3.2. Feature Announcement

Support for this feature MUST be announced by _Callers_ ("role :=
"caller""), _Callees_ ("role := "callee"") and _Dealers_ ("role :=
"dealer"") via

HELLO.Details.roles.<role>.features.call_timeout|bool := true

14.3.4. Call Canceling

14.3.4.1. Feature Definition

A _Caller_ might want to actively cancel a call that was issued, but
not has yet returned. An example where this is useful could be a
user triggering a long running operation and later changing his mind
or no longer willing to wait.

The message flow between _Callers_, a _Dealer_ and _Callees_ for
canceling remote procedure calls involves the following messages:

o "CANCEL"

o "INTERRUPT"

A call may be cancelled at the _Callee_







Oberstein & Goedde Expires April 13, 2016 [Page 70]

Internet-Draft ITMP October 2015


,------. ,------. ,------.
|Caller| |Dealer| |Callee|
`--+---' `--+---' `--+---'
| CALL | |
| ----------------> |
| | |
| | INVOCATION |
| | ---------------->
| | |
| CANCEL | |
| ----------------> |
| | |
| | INTERRUPT |
| | ---------------->
| | |
| | ERROR |
| | <----------------
| | |
| ERROR | |
| <---------------- |
,--+---. ,--+---. ,--+---.
|Caller| |Dealer| |Callee|
`------' `------' `------'

A call may be cancelled at the _Dealer_


























Oberstein & Goedde Expires April 13, 2016 [Page 71]

Internet-Draft ITMP October 2015


,------. ,------. ,------.
|Caller| |Dealer| |Callee|
`--+---' `--+---' `--+---'
| CALL | |
| ----------------> |
| | |
| | INVOCATION |
| | ---------------->
| | |
| CANCEL | |
| ----------------> |
| | |
| ERROR | |
| <---------------- |
| | |
| | INTERRUPT |
| | ---------------->
| | |
| | ERROR |
| | <----------------
,--+---. ,--+---. ,--+---.
|Caller| |Dealer| |Callee|
`------' `------' `------'

A _Caller_ cancels a remote procedure call initiated (but not yet
finished) by sending a "CANCEL" message to the _Dealer_:

[CANCEL, CALL.Request|id, Options|dict]

A _Dealer_ cancels an invocation of an endpoint initiated (but not
yet finished) by sending a "INTERRUPT" message to the _Callee_:

[INTERRUPT, INVOCATION.Request|id, Options|dict]

Options:

CANCEL.Options.mode|string == "skip" | "kill" | "killnowait"

14.3.4.2. Feature Announcement

Support for this feature MUST be announced by _Callers_ ("role :=
"caller""), _Callees_ ("role := "callee"") and _Dealers_ ("role :=
"dealer"") via

HELLO.Details.roles.<role>.features.call_canceling|bool := true






Oberstein & Goedde Expires April 13, 2016 [Page 72]

Internet-Draft ITMP October 2015


14.3.5. Caller Identification

14.3.5.1. Feature Definition

A _Caller_ MAY *request* the disclosure of its identity (its ITMP
session ID) to endpoints of a routed call via

CALL.Options.disclose_me|bool := true

_Example_

[48, 7814135, {"disclose_me": true}, "com.myapp.echo",
["Hello, world!"]]

If above call is issued by a _Caller_ with ITMP session ID "3335656",
the _Dealer_ sends an "INVOCATION" message to _Callee_ with the
_Caller's_ ITMP session ID in "INVOCATION.Details.caller":

_Example_

[68, 6131533, 9823526, {"caller": 3335656}, ["Hello, world!"]]

Note that a _Dealer_ MAY disclose the identity of a _Caller_ even
without the _Caller_ having explicitly requested to do so when the
_Dealer_ configuration (for the called procedure) is setup to do so.

A _Dealer_ MAY deny a _Caller's_ request to disclose its identity:

_Example_

[8, 7814135, "wamp.error.disclose_me.not_allowed"]

A _Callee_ MAY *request* the disclosure of caller identity via

REGISTER.Options.disclose_caller|bool := true

_Example_

[64, 927639114088448, {"disclose_caller":true},
"com.maypp.add2"]

With the above registration, the registered procedure is called with
the caller's sessionID as part of the call details object.








Oberstein & Goedde Expires April 13, 2016 [Page 73]

Internet-Draft ITMP October 2015


14.3.5.2. Feature Announcement

Support for this feature MUST be announced by _Callers_ ("role :=
"caller""), _Callees_ ("role := "callee"") and _Dealers_ ("role :=
"dealer"") via

HELLO.Details.roles.<role>.features.
caller_identification|bool := true

14.3.6. Call Trust Levels

14.3.6.1. Feature Defintion

A _Dealer_ may be configured to automatically assign _trust levels_
to calls issued by _Callers_ according to the _Dealer_ configuration
on a per-procedure basis and/or depending on the application defined
role of the (authenticated) _Caller_.

A _Dealer_ supporting trust level will provide

INVOCATION.Details.trustlevel|integer

in an "INVOCATION" message sent to a _Callee_. The trustlevel "0"
means lowest trust, and higher integers represent (application-
defined) higher levels of trust.

_Example_

[68, 6131533, 9823526, {"trustlevel": 2}, ["Hello, world!"]]

In above event, the _Dealer_ has (by configuration and/or other
information) deemed the call (and hence the invocation) to be of
trustlevel "2".

14.3.6.2. Feature Announcement

Support for this feature MUST be announced by _Callees_ ("role :=
"callee"") and _Dealers_ ("role := "dealer"") via

HELLO.Details.roles.<role>.features.call_trustlevels|bool := true

14.3.7. Registration Meta API

14.3.7.1. Feature Definition







Oberstein & Goedde Expires April 13, 2016 [Page 74]

Internet-Draft ITMP October 2015


14.3.7.1.1. Introduction

*Registration Meta Events* are fired when registrations are first
created, when _Callees_ are attached (removed) to (from) a
registration, and when registrations are finally destroyed.

Furthermore, ITMP allows actively retrieving information about
registrations via *Registration Meta Procedures*.

Meta-events are created by the router itself. This means that the
events as well as the data received when calling a meta-procedure can
be accorded the same trust level as the router.

Note that an implementation that only supports a _Broker_ or
_Dealer_ role, not both at the same time, essentially cannot offer
the *Registration Meta API*, as it requires both roles to support
this feature.

14.3.7.1.2. Registration Meta Events

A client can subscribe to the following registration meta-events,
which cover the lifecycle of a registration:

o "wamp.registration.on_create": Fired when a registration is
created through a registration request for an URI which was
previously without a registration.

o "wamp.registration.on_register": Fired when a _Callee_ session is
added to a registration.

o "wamp.registration.on_unregister": Fired when a _Callee_ session
is removed from a registration.

o "wamp.registration.on_delete": Fired when a registration is
deleted after the last _Callee_ session attached to it has been
removed.

A "wamp.registration.on_register" event MUST be fired subsequent to a
"wamp.registration.on_create" event, since the first registration
results in both the creation of the registration and the addition of
a session.

Similarly, the "wamp.registration.on_delete" event MUST be preceded
by a "wamp.registration.on_unregister" event.

*Registration Meta Events* MUST be dispatched by the router to the
same realm as the ITMP session which triggered the event.




Oberstein & Goedde Expires April 13, 2016 [Page 75]

Internet-Draft ITMP October 2015


14.3.7.1.2.1. wamp.registration.on_create

Fired when a registration is created through a registration request
for an URI which was previously without a registration.

*Event Arguments*

o "session|id": The session ID performing the registration request.

o "RegistrationDetails|dict": Information on the created
registration.

*Object Schemas*

RegistrationDetails :=
{
"id": registration|id,
"created": time_created|iso_8601_string,
"uri": procedure|uri,
"match": match_policy|string,
"invoke": invocation_policy|string
}

See Pattern-based Registrations [2] for a description of
"match_policy".

NOTE: invocation_policy IS NOT YET DESCRIBED IN THE ADVANCED SPEC

14.3.7.1.2.2. wamp.registration.on_register

Fired when a session is added to a registration.

*Event Arguments*

o "session|id": The ID of the session being added to a registration.

o "registration|id": The ID of the registration to which a session
is being added.

14.3.7.1.2.3. wamp.registration.on_unregister

Fired when a session is removed from a subscription.

*Event Arguments*

o "session|id": The ID of the session being removed from a
registration.




Oberstein & Goedde Expires April 13, 2016 [Page 76]

Internet-Draft ITMP October 2015


o "registration|id": The ID of the registration from which a session
is being removed.

14.3.7.1.2.4. wamp.registration.on_delete

Fired when a registration is deleted after the last session attached
to it has been removed.

*Event Arguments*

o "session|id": The ID of the last session being removed from a
registration.

o "registration|id": The ID of the registration being deleted.

14.3.7.1.3. Registration Meta-Procedures

A client can actively retrieve information about registrations via
the following meta-procedures:

o "wamp.registration.list": Retrieves registration IDs listed
according to match policies.

o "wamp.registration.lookup": Obtains the registration (if any)
managing a procedure, according to some match policy.

o "wamp.registration.match": Obtains the registration best matching
a given procedure URI.

o "wamp.registration.get": Retrieves information on a particular
registration.

o "wamp.registration.list_callees": Retrieves a list of session IDs
for sessions currently attached to the registration.

o "wamp.registration.count_callees": Obtains the number of sessions
currently attached to the registration.

14.3.7.1.3.1. wamp.registration.list

Retrieves registration IDs listed according to match policies.

*Arguments*

o None

*Results*




Oberstein & Goedde Expires April 13, 2016 [Page 77]

Internet-Draft ITMP October 2015


o "RegistrationLists|dict": A dictionary with a list of registration
IDs for each match policy.

*Object Schemas*

RegistrationLists :=
{
"exact": registration_ids|list,
"prefix": registration_ids|list,
"wildcard": registration_ids|list
}

See Pattern-based Registrations [3] for a description of match
policies.

14.3.7.1.3.2. wamp.registration.lookup

Obtains the registration (if any) managing a procedure, according to
some match policy.

*Arguments*

o "procedure|uri": The procedure to lookup the registration for.

o (Optional) "options|dict": Same options as when registering a
procedure.

*Results*

o (Nullable) "registration|id": The ID of the registration managing
the procedure, if found, or null.

14.3.7.1.3.3. wamp.registration.match

Obtains the registration best matching a given procedure URI.

*Arguments*

o "procedure|uri": The procedure URI to match

*Results*

o (Nullable) "registration|id": The ID of best matching
registration, or null.







Oberstein & Goedde Expires April 13, 2016 [Page 78]

Internet-Draft ITMP October 2015


14.3.7.1.3.4. wamp.registration.get

Retrieves information on a particular registration.

*Arguments*

o "registration|id": The ID of the registration to retrieve.

*Results*

o "RegistrationDetails|dict": Details on the registration.

*Error URIs*

o "wamp.error.no_such_registration": No registration with the given
ID exists on the router.

*Object Schemas*

RegistrationDetails :=
{
"id": registration|id,
"created": time_created|iso_8601_string,
"uri": procedure|uri,
"match": match_policy|string,
"invoke": invocation_policy|string
}

See Pattern-based Registrations [4] for a description of match
policies.

_NOTE: invocation_policy IS NOT YET DESCRIBED IN THE ADVANCED SPEC_

14.3.7.1.3.5. wamp.registration.list_callees

Retrieves a list of session IDs for sessions currently attached to
the registration.

*Arguments*

o "registration|id": The ID of the registration to get calles for.

*Results*

o "callee_ids|list": A list of ITMP session IDs of callees currently
attached to the registration.

*Error URIs*



Oberstein & Goedde Expires April 13, 2016 [Page 79]

Internet-Draft ITMP October 2015


o "wamp.error.no_such_registration": No registration with the given
ID exists on the router.

14.3.7.1.3.6. wamp.registration.count_callees

Obtains the number of sessions currently attached to a registration.

*Arguments*

o "registration|id": The ID of the registration to get the number of
callees for.

*Results*

o "count|int": The number of callees currently attached to a
registration.

*Error URIs*

o "wamp.error.no_such_registration": No registration with the given
ID exists on the router.

14.3.7.2. Feature Announcement

Support for this feature MUST be announced by a _Dealers_ ("role :=
"dealer"") via:

HELLO.Details.roles.<role>.features.
session_meta_api|bool := true

*Example*

Here is a "WELCOME" message from a _Router_ with support for both the
_Broker_ and _Dealer_ role, and with support for *Registration Meta
API*:
















Oberstein & Goedde Expires April 13, 2016 [Page 80]

Internet-Draft ITMP October 2015


[
2,
4580268554656113,
{
"authid":"OL3AeppwDLXiAAPbqm9IVhnw",
"authrole": "anonymous",
"authmethod": "anonymous",
"roles": {
"broker": {
"features": {
}
},
"dealer": {
"features": {
"registration_meta_api": true
}
}
}
}
]

14.3.8. Pattern-based Registrations

14.3.8.1. Feature Definition

14.3.8.1.1. Introduction

By default, _Callees_ register procedures with *exact matching
policy*. That is a call will only be routed to a _Callee_ by the
_Dealer_ if the procedure called ("CALL.Procedure") _exactly_ matches
the endpoint registered ("REGISTER.Procedure").

A _Callee_ might want to register procedures based on a _pattern_.
This can be useful to reduce the number of individual registrations
to be set up or to subscribe to a open set of topics, not known
beforehand by the _Subscriber_.

If the _Dealer_ and the _Callee_ support *pattern-based
registrations*, this matching can happen by

o *prefix-matching policy*

o *wildcard-matching policy*








Oberstein & Goedde Expires April 13, 2016 [Page 81]

Internet-Draft ITMP October 2015


14.3.8.1.2. Prefix Matching

A _Callee_ requests *prefix-matching policy* with a registration
request by setting

REGISTER.Options.match|string := "prefix"

_Example_

[
64,
612352435,
{
"match": "prefix"
},
"com.myapp.myobject1"
]

When a *prefix-matching policy* is in place, any call with a
procedure that has "REGISTER.Procedure" as a _prefix_ will match the
registration, and potentially be routed to _Callees_ on that
registration.

In above example, the following calls with "CALL.Procedure"

o "com.myapp.myobject1.myprocedure1"

o "com.myapp.myobject1-mysubobject1"

o "com.myapp.myobject1.mysubobject1.myprocedure1"

o "com.myapp.myobject1"

will all apply for call routing. A call with one of the following
"CALL.Procedure"

o "com.myapp.myobject2"

o "com.myapp.myobject"

will not apply.

14.3.8.1.3. Wildcard Matching

A _Callee_ requests *wildcard-matching policy* with a registration
request by setting

REGISTER.Options.match|string := "wildcard"



Oberstein & Goedde Expires April 13, 2016 [Page 82]

Internet-Draft ITMP October 2015


Wildcard-matching allows to provide wildcards for *whole* URI
components.

_Example_

[
64,
612352435,
{
"match": "wildcard"
},
"com.myapp..myprocedure1"
]

In the above registration request, the 3rd URI component is empty,
which signals a wildcard in that URI component position. In this
example, calls with "CALL.Procedure" e.g.

o "com.myapp.myobject1.myprocedure1"

o "com.myapp.myobject2.myprocedure1"

will all apply for call routing. Calls with "CALL.Procedure" e.g.

o "com.myapp.myobject1.myprocedure1.mysubprocedure1"

o "com.myapp.myobject1.myprocedure2"

o "com.myapp2.myobject1.myprocedure1"

will not apply for call routing.

When a single call matches more than one of a _Callees_
registrations, the call MAY be routed for invocation on multiple
registrations, depending on call settings.

14.3.8.1.4. General

14.3.8.1.4.1. No set semantics

Since each _Callee_'s' registrations "stands on it's own", there is
no _set semantics_ implied by pattern-based registrations.

E.g. a _Callee_ cannot register to a broad pattern, and then
unregister from a subset of that broad pattern to form a more complex
registration. Each registration is separate.





Oberstein & Goedde Expires April 13, 2016 [Page 83]

Internet-Draft ITMP October 2015


14.3.8.1.4.2. Calls matching multiple registrations

The behavior when a single call matches more than one of a _Callee's_
registrations or more than one registration in general is still being
discussed - see <https://github.com/tavendo/ITMP/issues/182>.

14.3.8.1.4.3. Concrete procedure called

If an endpoint was registered with a pattern-based matching policy, a
_Dealer_ MUST supply the original "CALL.Procedure" as provided by the
_Caller_ in

INVOCATION.Details.procedure

to the _Callee_.

_Example_

[
68,
6131533,
9823527,
{
"procedure": "com.myapp.procedure.proc1"
},
["Hello, world!"]
]

14.3.8.2. Feature Announcement

Support for this feature MUST be announced by _Callees_ ("role :=
"callee"") and _Dealers_ ("role := "dealer"") via

HELLO.Details.roles.<role>.features.
pattern_based_registration|bool := true

14.3.9. Shared Registration

Feature status: *alpha*

14.3.9.1. Feature Definition

As a default, only a single *Callee* may register a procedure for an
URI.

There are use cases where more flexibility is required. As an
example, for an application component with a high computing load,
several instances may run, and load balancing of calls across these



Oberstein & Goedde Expires April 13, 2016 [Page 84]

Internet-Draft ITMP October 2015


may be desired. As another example, in an an application a second or
third component providing a procedure may run, which are only to be
called in case the primary component is no longer reachable (hot
standby).

When shared registrations are supported, then the first *Callee* to
register a procedure for a particular URI MAY determine that
additional registrations for this URI are allowed, and what
*Invocation Rules* to apply in case such additional registrations are
made.

This is done through setting

REGISTER.Options.invoke|string := <invocation_policy>

where is one of

o 'single'

o 'roundrobin'

o 'random'

o 'first'

o 'last'

If the option is not set, 'single' is applied as a default.

With 'single', the *Dealer* MUST fail all subsequent attempts to
register a procedure for the URI while the registration remains in
existence.

With the other values, the *Dealer* MUST fail all subsequent attempst
to register a procedure for the URI where the value for this option
does not match that of the initial registration.

14.3.9.1.1. Load Balancing

For sets of registrations registered using either 'roundrobin' or
'random', load balancing is performed across calls to the URI.

For 'roundrobin', callees are picked subsequently from the list of
registrations (ordered by the order of registration), with the
picking looping back to the beginning of the list once the end has
been reached.





Oberstein & Goedde Expires April 13, 2016 [Page 85]

Internet-Draft ITMP October 2015


For 'random' a callee is picked randomly from the list of
registrations for each call.

14.3.9.1.2. Hot Stand-By

For sets of registrations registered using either 'first' or 'last',
the first respectively last callee on the current list of
registrations (ordered by the order of registration) is called.

14.3.9.2. Feature Announcement

Support for this feature MUST be announced by _Callees_ ("role :=
"callee"") and _Dealers_ ("role := "dealer"") via

HELLO.Details.roles.<role>.features.
shared_registration|bool := true

14.3.10. Sharded Registration

Feature status: *sketch*

14.3.10.1. Feature Definition

*Sharded Registrations* are intended to allow calling a procedure
which is offered by a sharded database, by routing the call to a
single shard.

14.3.10.2. "Partitioned" Calls

If "CALL.Options.runmode == "partition"", then "CALL.Options.rkey"
MUST be present.

The call is then routed to all endpoints that were registered ..

The call is then processed as for "All" Calls.

14.3.10.3. Feature Announcement

Support for this feature MUST be announced by _Callers_ ("role :=
"caller""), _Callees_ ("role := "callee"") and _Dealers_ ("role :=
"dealer"") via

HELLO.Details.roles.<role>.features.sharded_registration|bool := true








Oberstein & Goedde Expires April 13, 2016 [Page 86]

Internet-Draft ITMP October 2015


14.3.11. Registration Revocation

14.3.11.1. Feature Definition

Actively and forcefully revoke a previously granted registration from
a session.

14.3.11.2. Feature Announcement

14.3.12. Procedure Reflection

Feature status: *sketch*

_Reflection_ denotes the ability of ITMP peers to examine the
procedures, topics and errors provided or used by other peers.

I.e. a ITMP _Caller_, _Callee_, _Subscriber_ or _Publisher_ may be
interested in retrieving a machine readable list and description of
ITMP procedures and topics it is authorized to access or provide in
the context of a ITMP session with a _Dealer_ or _Broker_.

Reflection may be useful in the following cases:

o documentation

o discoverability

o generating stubs and proxies

ITMP predefines the following procedures for performing run-time
reflection on ITMP peers which act as _Brokers_ and/or _Dealers_.

Predefined ITMP reflection procedures to _list_ resources by type:

wamp.reflection.topic.list
wamp.reflection.procedure.list
wamp.reflection.error.list

Predefined ITMP reflection procedures to _describe_ resources by
type:

wamp.reflection.topic.describe
wamp.reflection.procedure.describe
wamp.reflection.error.describe

A peer that acts as a _Broker_ SHOULD announce support for the
reflection API by sending




Oberstein & Goedde Expires April 13, 2016 [Page 87]

Internet-Draft ITMP October 2015


HELLO.Details.roles.broker.reflection|bool := true

A peer that acts as a _Dealer_ SHOULD announce support for the
reflection API by sending

HELLO.Details.roles.dealer.reflection|bool := true

Since _Brokers_ might provide (broker) procedures and _Dealers_
might provide (dealer) topics, both SHOULD implement the complete
API above (even if the peer only implements one of _Broker_ or
_Dealer_ roles).

*Reflection*

A topic or procedure is defined for reflection:

wamp.reflect.define

A topic or procedure was asked to be described (reflected upon):

wamp.reflect.describe

*Reflection*

A topic or procedure has been defined for reflection:

wamp.reflect.on_define

A topic or procedure has been unfined from reflection:

wamp.reflect.on_undefine

14.4. Advanced PubSub Features

14.4.1. Subscriber Black- and Whitelisting

14.4.1.1. Introduction

*Subscriber Black- and Whitelisting* is an advanced _Broker_ feature
where a _Publisher_ is able to restrict the set of receivers of a
published event.

Under normal Publish & Subscriber event dispatching, a _Broker_ will
dispatch a published event to all (authorized) _Subscribers_ other
than the _Publisher_ itself. This set of receivers can be further
reduced on a per-publication basis by the _Publisher_ using
*Subscriber Black- and Whitelisting*.




Oberstein & Goedde Expires April 13, 2016 [Page 88]

Internet-Draft ITMP October 2015


The _Publisher_ can explicitly *exclude* _Subscribers_ based on ITMP
"sessionid", "authid" or "authrole". This is referred to as
*Blacklisting*.

A _Publisher_ may also explicitly define a *eligible* list of
*Subscribers** based on ITMP "sessionid", "authid" or "authrole".
This is referred to as *Whitelisting*.

14.4.1.2. Use Cases

14.4.1.2.1. Avoiding Callers from being self-notified

Consider an application that exposes a procedure to update a product
price. The procedure might not only actually update the product
price (e.g. in a backend database), but additionally publish an event
with the updated product price, so that *all* application components
get notified actively of the new price.

However, the application might want to exclude the originator of the
product price update (the *Caller* of the price update procedure)
from receiving the update event - as the originator naturally already
knows the new price, and might get confused when it receives an
update the *Caller* has triggered himself.

The product price update procedure can use
"PUBLISH.Options.exclude|list[int]" to exclude the *Caller* of the
procedure.

Note that the product price update procedure needs to know the
session ID of the *Caller* to be able to exclude him. For this,
please see *Caller Identification*.

A similar approach can be used for other CRUD-like procedures.

14.4.1.2.2. Restricting receivers of sensitive information

Consider an application with users that have different "authroles",
such as "manager" and "staff" that publishes events with updates to
"customers". The topics being published to could be structured like

com.example.myapp.customer.<customer ID>

The application might want to restrict the receivers of customer
updates depending on the "authrole" of the user. E.g. a user
authenticated under "authrole" "manager" might be allowed to receive
any kind of customer update, including personal and business
sensitive information. A user under "authrole" "staff" might only be
allowed to receive a subset of events.



Oberstein & Goedde Expires April 13, 2016 [Page 89]

Internet-Draft ITMP October 2015


The application can publish *all* customer updates to the *same*
topic "com.example.myapp.customer.<customer ID>" and use
"PUBLISH.Options.eligible_authrole|list[string]" to safely restrict
the set of actual receivers as desired.

14.4.1.3. Feature Definition

A _Publisher_ may restrict the actual receivers of an event from the
set of _Subscribers_ through the use of

o Blacklisting Options

* "PUBLISH.Options.exclude|list[int]"

* "PUBLISH.Options.exclude_authid|list[string]"

* "PUBLISH.Options.exclude_authrole|list[string]"

o Whitelisting Options

* "PUBLISH.Options.eligible|list[int]"

* "PUBLISH.Options.eligible_authid|list[string]"

* "PUBLISH.Options.eligible_authrole|list[string]"

"PUBLISH.Options.exclude" is a list of integers with ITMP
"sessionids" providing an explicit list of (potential) _Subscribers_
that won't receive a published event, even though they may be
subscribed. In other words, "PUBLISH.Options.exclude" is a
*blacklist* of (potential) _Subscribers_.

"PUBLISH.Options.eligible" is a list of integeres with ITMP ITMP
"sessionids" providing an explicit list of (potential) _Subscribers_
that are allowed to receive a published event. In other words,
"PUBLISH.Options.eligible" is a *whitelist* of (potential)
_Subscribers_.

The "exclude_authid", "exclude_authrole", "eligible_authid" and
"eligible_authrole" options work similar, but not on the basis of
ITMP "sessionid", but "authid" and "authrole".

An (authorized) _Subscriber_ to topic T will receive an event
published to T if and only if all of the following statements hold
true:

1. if there is an "eligible" attribute present, the _Subscriber_'s
"sessionid" is in this list



Oberstein & Goedde Expires April 13, 2016 [Page 90]

Internet-Draft ITMP October 2015


2. if there is an "eligible_authid" attribute present, the
_Subscriber_'s "authid" is in this list

3. if there is an "eligible_authrole" attribute present, the
_Subscriber_'s "authrole" is in this list

4. if there is an "exclude attribute" present, the _Subscriber_'s
"sessionid" is NOT in this list

5. if there is an "exclude_authid" attribute present, the
_Subscriber_'s "authid" is NOT in this list

6. if there is an "exclude_authrole" attribute present, the
_Subscriber_'s "authrole" is NOT in this list

For example, if both "PUBLISH.Options.exclude" and
"PUBLISH.Options.eligible" are present, the _Broker_ will dispatch
events published only to _Subscribers_ that are not explicitly
excluded in "PUBLISH.Options.exclude" *and* which are explicitly
eligible via "PUBLISH.Options.eligible".

_Example_

[
16,
239714735,
{
"exclude": [
7891255,
1245751
]
},
"com.myapp.mytopic1",
[
"Hello, world!"
]
]

The above event will get dispatched to all _Subscribers_ of
"com.myapp.mytopic1", but not ITMP sessions with IDs "7891255" or
"1245751" (and also not the publishing session).

_Example_








Oberstein & Goedde Expires April 13, 2016 [Page 91]

Internet-Draft ITMP October 2015


[
16,
239714735,
{
"eligible": [
7891255,
1245751
]
},
"com.myapp.mytopic1",
[
"Hello, world!"
]
]

The above event will get dispatched to ITMP sessions with IDs
"7891255" or "1245751" only - but only if those are actually
subscribed to the topic "com.myapp.mytopic1".

_Example_

[
16,
239714735,
{
"eligible": [
7891255,
1245751,
9912315
],
"exclude": [
7891255
]
},
"com.myapp.mytopic1",
[
"Hello, world!"
]
]

The above event will get dispatched to ITMP sessions with IDs
"1245751" or "9912315" only, since "7891255" is excluded - but only
if those are actually subscribed to the topic "com.myapp.mytopic1".








Oberstein & Goedde Expires April 13, 2016 [Page 92]

Internet-Draft ITMP October 2015


14.4.1.4. Feature Announcement

Support for this feature MUST be announced by _Publishers_ ("role :=
"publisher"") and _Brokers_ ("role := "broker"") via

HELLO.Details.roles.<role>.features.
subscriber_blackwhite_listing|bool := true

14.4.2. Publisher Exclusion

14.4.2.1. Feature Definition

By default, a _Publisher_ of an event will *not* itself receive an
event published, even when subscribed to the "Topic" the _Publisher_
is publishing to. This behavior can be overridden using this
feature.

To override the exclusion of a publisher from it's own publication,
the "PUBLISH" message must include the following option:

PUBLISH.Options.exclude_me|bool

When publishing with "PUBLISH.Options.exclude_me := false", the
_Publisher_ of the event will receive that event, if it is subscribed
to the "Topic" published to.

_Example_

[
16,
239714735,
{
"exclude_me": false
},
"com.myapp.mytopic1",
["Hello, world!"]
]

In this example, the _Publisher_ will receive the published event, if
it is subscribed to "com.myapp.mytopic1".

14.4.2.2. Feature Announcement

Support for this feature MUST be announced by _Publishers_ ("role :=
"publisher"") and _Brokers_ ("role := "broker"") via

HELLO.Details.roles.<role>.features.
publisher_exclusion|bool := true



Oberstein & Goedde Expires April 13, 2016 [Page 93]

Internet-Draft ITMP October 2015


14.4.3. Publisher Identification

14.4.3.1. Feature Definition

A _Publisher_ may request the disclosure of its identity (its ITMP
session ID) to receivers of a published event by setting

PUBLISH.Options.disclose_me|bool := true

_Example_

[16, 239714735, {"disclose_me": true}, "com.myapp.mytopic1",
["Hello, world!"]]

If above event is published by a _Publisher_ with ITMP session ID
"3335656", the _Broker_ would send an "EVENT" message to
_Subscribers_ with the _Publisher's_ ITMP session ID in
"EVENT.Details.publisher":

_Example_

[36, 5512315355, 4429313566, {"publisher": 3335656},
["Hello, world!"]]

Note that a _Broker_ may deny a _Publisher's_ request to disclose its
identity:

_Example_

[8, 239714735, {}, "wamp.error.option_disallowed.disclose_me"]

A _Broker_ may also (automatically) disclose the identity of a
_Publisher_ even without the _Publisher_ having explicitly requested
to do so when the _Broker_ configuration (for the publication topic)
is set up to do so.

14.4.3.2. Feature Announcement

Support for this feature MUST be announced by _Publishers_ ("role :=
"publisher""), _Brokers_ ("role := "broker"") and _Subscribers_
("role := "subscriber"") via

HELLO.Details.roles.<role>.features.
publisher_identification|bool := true







Oberstein & Goedde Expires April 13, 2016 [Page 94]

Internet-Draft ITMP October 2015


14.4.4. Publication Trust Levels

14.4.4.1. Feature Definition

A _Broker_ may be configured to automatically assign _trust levels_
to events published by _Publishers_ according to the _Broker_
configuration on a per-topic basis and/or depending on the
application defined role of the (authenticated) _Publisher_.

A _Broker_ supporting trust level will provide

EVENT.Details.trustlevel|integer

in an "EVENT" message sent to a _Subscriber_. The trustlevel "0"
means lowest trust, and higher integers represent (application-
defined) higher levels of trust.

_Example_

[36, 5512315355, 4429313566, {"trustlevel": 2},
["Hello, world!"]]

In above event, the _Broker_ has (by configuration and/or other
information) deemed the event publication to be of trustlevel "2".

14.4.4.2. Feature Announcement

Support for this feature MUST be announced by _Subscribers_ ("role :=
"subscriber"") and _Brokers_ ("role := "broker"") via

HELLO.Details.roles.<role>.features.
publication_trustlevels|bool := true

14.4.5. Subscription Meta API

Within an application, it may be desirable for a publisher to know
whether a publication to a specific topic currently makes sense, i.e.
whether there are any subscribers who would receive an event based on
the publication. It may also be desirable to keep a current count of
subscribers to a topic to then be able to filter out any subscribers
who are not supposed to receive an event.

Subscription _meta-events_ are fired when topics are first created,
when clients subscribe/unsubscribe to them, and when topics are
deleted. ITMP allows retrieving information about subscriptions via
subscription _meta-procedures_.

Support for this feature MUST be announced by Brokers via



Oberstein & Goedde Expires April 13, 2016 [Page 95]

Internet-Draft ITMP October 2015


HELLO.Details.roles.broker.features.subscription_meta_api|
bool := true

Meta-events are created by the router itself. This means that the
events as well as the data received when calling a meta-procedure can
be accorded the same trust level as the router.

14.4.5.1. Subscription Meta-Events

A client can subscribe to the following session meta-events, which
cover the lifecycle of a subscription:

o "wamp.subscription.on_create": Fired when a subscription is
created through a subscription request for a topic which was
previously without subscribers.

o "wamp.subscription.on_subscribe": Fired when a session is added to
a subscription.

o "wamp.subscription.on_unsubscribe": Fired when a session is
removed from a subscription.

o "wamp.subscription.on_delete": Fired when a subscription is
deleted after the last session attached to it has been removed.

A "wamp.subscription.on_subscribe" event MUST always be fired
subsequent to a "wamp.subscription.on_create" event, since the first
subscribe results in both the creation of the subscription and the
addition of a session. Similarly, the "wamp.subscription.on_delete"
event MUST always be preceded by a "wamp.subscription.on_unsubscribe"
event.

The ITMP subscription meta events shall be dispatched by the router
to the same realm as the ITMP session which triggered the event.

14.4.5.1.1. Meta-Event Specifications

14.4.5.1.1.1. wamp.subscription.on_create

Fired when a subscription is created through a subscription request
for a topic which was previously without subscribers.

*Event Arguments*

o "session|id": ID of the session performing the subscription
request.





Oberstein & Goedde Expires April 13, 2016 [Page 96]

Internet-Draft ITMP October 2015


o "SubscriptionDetails|dict": Information on the created
subscription.

*Object Schemas*

SubscriptionDetails :=
{
"id": subscription|id,
"created": time_created|iso_8601_string,
"uri": topic|uri,
"match": match_policy|string
}

See Section 14.4.6 for a description of "match_policy".

14.4.5.1.1.2. wamp.subscription.on_subscribe

Fired when a session is added to a subscription.

*Event Arguments*

o "session|id": ID of the session being added to a subscription.

o "subscription|id": ID of the subscription to which the session is
being added.

14.4.5.1.1.3. wamp.subscription.on_unsubscribe

Fired when a session is removed from a subscription.

*Event Arguments*

o "session|id": ID of the session being removed from a subscription.

o "subscription|id": ID of the subscription from which the session
is being removed.

14.4.5.1.1.4. wamp.subscription.on_delete

Fired when a subscription is deleted after the last session attached
to it has been removed.

*Arguments*

o "session|id": ID of the last session being removed from a
subscription.

o "subscription|id": ID of the subscription being deleted.



Oberstein & Goedde Expires April 13, 2016 [Page 97]

Internet-Draft ITMP October 2015


14.4.5.2. Subscription Meta-Procedures

A client can actively retrieve information about subscriptions via
the following meta-procedures:

o "wamp.subscription.list": Retrieves subscription IDs listed
according to match policies.

o "wamp.subscription.lookup": Obtains the subscription (if any)
managing a topic, according to some match policy.

o "wamp.subscription.match": Retrieves a list of IDs of
subscriptions matching a topic URI, irrespective of match policy.

o "wamp.subscription.get": Retrieves information on a particular
subscription.

o "wamp.subscription.list_subscribers": Retrieves a list of session
IDs for sessions currently attached to the subscription.

o "wamp.subscription.count_subscribers": Obtains the number of
sessions currently attached to the subscription.

14.4.5.2.1. Meta-Procedure Specifications

14.4.5.2.1.1. wamp.subscription.list

Retrieves subscription IDs listed according to match policies.

*Arguments*

o None

*Results*

o "SubscriptionLists|dict": A dictionary with a list of subscription
IDs for each match policy.

*Object Schemas*

SubscriptionLists :=
{
"exact": subscription_ids|list,
"prefix": subscription_ids|list,
"wildcard": subscription_ids|list
}

See Section 14.4.6 for information on match policies.



Oberstein & Goedde Expires April 13, 2016 [Page 98]

Internet-Draft ITMP October 2015


14.4.5.2.1.2. wamp.subscription.lookup

Obtains the subscription (if any) managing a topic, according to some
match policy.

*Arguments*

o "topic|uri": The URI of the topic.

o (Optional) "options|dict": Same options as when subscribing to a
topic.

*Results*

o (Nullable) "subscription|id": The ID of the subscription managing
the topic, if found, or null.

14.4.5.2.1.3. wamp.subscription.match

Retrieves a list of IDs of subscriptions matching a topic URI,
irrespective of match policy.

*Arguments*

o "topic|uri": The topic to match.

*Results*

o (Nullable) "subscription_ids|list": A list of all matching
subscription IDs, or null.

14.4.5.2.1.4. wamp.subscription.get

Retrieves information on a particular subscription.

*Arguments*

o "subscription|id": The ID of the subscription to retrieve.

*Results*

o "SubscriptionDetails|dict": Details on the subscription.

*Error URIs*

o "wamp.error.no_such_subscription": No subscription with the given
ID exists on the router.




Oberstein & Goedde Expires April 13, 2016 [Page 99]

Internet-Draft ITMP October 2015


*Object Schemas*

SubscriptionDetails :=
{
"id": subscription|id,
"created": time_created|iso_8601_string,
"uri": topic|uri,
"match": match_policy|string
}

See Section 14.4.6 for information on match policies.

14.4.5.2.1.5. wamp.subscription.list_subscribers

Retrieves a list of session IDs for sessions currently attached to
the subscription.

*Arguments*

o "subscription|id": The ID of the subscription to get subscribers
for.

*Results*

o "subscribers_ids|list": A list of ITMP session IDs of subscribers
currently attached to the subscription.

*Error URIs*

o "wamp.error.no_such_subscription": No subscription with the given
ID exists on the router.

14.4.5.2.1.6. wamp.subscription.count_subscribers

Obtains the number of sessions currently attached to a subscription.

*Arguments*

o "subscription|id": The ID of the subscription to get the number of
subscribers for.

*Results*

o "count|int": The number of sessions currently attached to a
subscription.

*Error URIs*




Oberstein & Goedde Expires April 13, 2016 [Page 100]

Internet-Draft ITMP October 2015


o "wamp.error.no_such_subscription": No subscription with the given
ID exists on the router.

14.4.6. Pattern-based Subscriptions

14.4.6.1. Introdution

By default, _Subscribers_ subscribe to topics with *exact matching
policy*. That is an event will only be dispatched to a _Subscriber_
by the _Broker_ if the topic published to ("PUBLISH.Topic") _exactly_
matches the topic subscribed to ("SUBSCRIBE.Topic").

A _Subscriber_ might want to subscribe to topics based on a
_pattern_. This can be useful to reduce the number of individual
subscriptions to be set up and to subscribe to topics the
_Subscriber_ is not aware of at the time of subscription, or which do
not yet exist at this time.

If the _Broker_ and the _Subscriber_ support *pattern-based
subscriptions*, this matching can happen by

o prefix-matching policy

o wildcard-matching policy

14.4.6.2. Prefix Matching

A _Subscriber_ requests *prefix-matching policy* with a subscription
request by setting

SUBSCRIBE.Options.match|string := "prefix"

_Example_

[
32,
912873614,
{
"match": "prefix"
},
"com.myapp.topic.emergency"
]

When a *prefix-matching policy* is in place, any event with a topic
that has "SUBSCRIBE.Topic" as a _prefix_ will match the subscription,
and potentially be delivered to _Subscribers_ on the subscription.

In the above example, events with "PUBLISH.Topic"



Oberstein & Goedde Expires April 13, 2016 [Page 101]

Internet-Draft ITMP October 2015


o "com.myapp.topic.emergency.11"

o "com.myapp.topic.emergency-low"

o "com.myapp.topic.emergency.category.severe"

o "com.myapp.topic.emergency"

will all apply for dispatching. An event with "PUBLISH.Topic" e.g.
"com.myapp.topic.emerge" will not apply.

14.4.6.3. Wildcard Matching

A _Subscriber_ requests *wildcard-matching policy* with a
subscription request by setting

SUBSCRIBE.Options.match|string := "wildcard"

Wildcard-matching allows to provide wildcards for *whole* URI
components.

_Example_

[
32,
912873614,
{
"match": "wildcard"
},
"com.myapp..userevent"
]

In above subscription request, the 3rd URI component is empty, which
signals a wildcard in that URI component position. In this example,
events with "PUBLISH.Topic"

o "com.myapp.foo.userevent"

o "com.myapp.bar.userevent"

o "com.myapp.a12.userevent"

will all apply for dispatching. Events with "PUBLISH.Topic"

o "com.myapp.foo.userevent.bar"

o "com.myapp.foo.user"




Oberstein & Goedde Expires April 13, 2016 [Page 102]

Internet-Draft ITMP October 2015


o "com.myapp2.foo.userevent"

will not apply for dispatching.

14.4.6.4. General

14.4.6.4.1. No set semantics

Since each _Subscriber's_ subscription "stands on its own", there is
no _set semantics_ implied by pattern-based subscriptions.

E.g. a _Subscriber_ cannot subscribe to a broad pattern, and then
unsubscribe from a subset of that broad pattern to form a more
complex subscription. Each subscription is separate.

14.4.6.4.2. Events matching multiple subscriptions

When a single event matches more than one of a _Subscriber's_
subscriptions, the event will be delivered for each subscription.

The _Subscriber_ can detect the delivery of that same event on
multiple subscriptions via "EVENT.PUBLISHED.Publication", which will
be identical.

14.4.6.4.3. Concrete topic published to

If a subscription was established with a pattern-based matching
policy, a _Broker_ MUST supply the original "PUBLISH.Topic" as
provided by the _Publisher_ in

EVENT.Details.topic|uri

to the _Subscribers_.

_Example_

[
36,
5512315355,
4429313566,
{
"topic": "com.myapp.topic.emergency.category.severe"
},
["Hello, world!"]
]






Oberstein & Goedde Expires April 13, 2016 [Page 103]

Internet-Draft ITMP October 2015


14.4.6.5. Feature Announcement

Support for this feature MUST be announced by _Subscribers_ ("role :=
"subscriber"") and _Brokers_ ("role := "broker"") via

HELLO.Details.roles.<role>.features.
pattern_based_subscription|bool := true

14.4.7. Sharded Subscriptions

Feature status: *alpha*

Support for this feature MUST be announced by _Publishers_ ("role :=
"publisher""), _Subscribers_ ("role := "subscriber"") and _Brokers_
("role := "broker"") via

HELLO.Details.roles.<role>.features.shareded_subscriptions|
bool := true

Resource keys: "PUBLISH.Options.rkey|string" is a stable, technical
*resource key*.

E.g. if your sensor has a unique serial identifier, you can use
that.

_Example_

[16, 239714735, {"rkey": "sn239019"}, "com.myapp.sensor.sn239019.
temperature", [33.9]]

Node keys: "SUBSCRIBE.Options.nkey|string" is a stable, technical
*node key*.

E.g. if your backend process runs on a dedicated host, you can use
its hostname.

_Example_

[32, 912873614, {"match": "wildcard", "nkey": "node23"},
"com.myapp.sensor..temperature"]

14.4.8. Event History

14.4.8.1. Feature Definition

Instead of complex QoS for message delivery, a _Broker_ may provide
_message history_. A _Subscriber_ is responsible to handle overlaps




Oberstein & Goedde Expires April 13, 2016 [Page 104]

Internet-Draft ITMP October 2015


(duplicates) when it wants "exactly-once" message processing across
restarts.

The _Broker_ may allow for configuration on a per-topic basis.

The event history may be transient or persistent message history
(surviving _Broker_ restarts).

A _Broker_ that implements _event history_ must (also) announce role
"HELLO.roles.callee", indicate "HELLO.roles.broker.history == 1" and
provide the following (builtin) procedures.

A _Caller_ can request message history by calling the _Broker_
procedure

wamp.topic.history.last

with "Arguments = [topic|uri, limit|integer]" where

o "topic" is the topic to retrieve event history for

o "limit" indicates the number of last N events to retrieve

or by calling

wamp.topic.history.since

with "Arguments = [topic|uri, timestamp|string]" where

o "topic" is the topic to retrieve event history for

o "timestamp" indicates the UTC timestamp since when to retrieve the
events in the ISO-8601 format "yyyy-MM-ddThh:mm:ss:SSSZ" (e.g.
""2013-12-21T13:43:11:000Z"")

or by calling

wamp.topic.history.after

with "Arguments = [topic|uri, publication|id]"

o "topic" is the topic to retrieve event history for

o "publication" is the id of an event which marks the start of the
events to retrieve from history

_FIXME_




Oberstein & Goedde Expires April 13, 2016 [Page 105]

Internet-Draft ITMP October 2015


1. Should we use "topic|uri" or "subscription|id" in "Arguments"?

* Since we need to be able to get history for pattern-based
subscriptions as well, a subscription|id makes more sense:
create pattern-based subscription, then get the event history
for this.

* The only restriction then is that we may not get event history
without a current subscription covering the events. This is a
minor inconvenience at worst.

2. Can "wamp.topic.history.after" be implemented (efficiently) at
all?

3. How does that interact with pattern-based subscriptions?

4. The same question as with the subscriber lists applies where: to
stay within our separation of roles, we need a broker + a
separate peer which implements the callee role. Here we do not
have a mechanism to get the history from the broker.

14.4.8.2. Feature Announcement

Support for this feature MUST be announced by _Subscribers_ ("role :=
"subscriber"") and _Brokers_ ("role := "broker"") via

HELLO.Details.roles.<role>.features.event_history|bool := true

14.4.9. Registration Revocation

14.4.9.1. Feature Definition

Actively and forcefully revoke a previously granted subscription from
a session.

14.4.9.2. Feature Announcement

14.4.10. Topic Reflection

o see *Procedure Reflection* for now

14.5. Other Advanced Features

14.5.1. Session Meta API







Oberstein & Goedde Expires April 13, 2016 [Page 106]

Internet-Draft ITMP October 2015


14.5.1.1. Introduction

ITMP enables the monitoring of when sessions join a realm on the
router or when they leave it via *Session Meta Events*. It also
allows retrieving information about currently connected sessions via
*Session Meta Procedures*.

Meta events are created by the router itself. This means that the
events, as well as the data received when calling a meta procedure,
can be accorded the same trust level as the router.

Note that an implementation that only supports a _Broker_ or
_Dealer_ role, not both at the same time, essentially cannot offer
the *Session Meta API*, as it requires both roles to support this
feature.

14.5.1.2. Session Meta Events

A client can subscribe to the following session meta-events, which
cover the lifecycle of a session:

o "wamp.session.on_join": Fired when a session joins a realm on the
router.

o "wamp.session.on_leave": Fired when a session leaves a realm on
the router or is disconnected.

*Session Meta Events* MUST be dispatched by the _Router_ to the same
realm as the ITMP session which triggered the event.

14.5.1.2.1. wamp.session.on_join

Fired when a session joins a realm on the router. The event payload
consists of a single positional argument "details|dict":

o "session|id" - The session ID of the session that joined

o "authid|string" - The authentication ID of the session that joined

o "authrole|string" - The authentication role of the session that
joined

o "authmethod|string" - The authentication method that was used for
authentication the session that joined

o "authprovider|string"- The provider that performed the
authentication of the session that joined




Oberstein & Goedde Expires April 13, 2016 [Page 107]

Internet-Draft ITMP October 2015


o "transport|dict" - Optional, implementation defined information
about the ITMP transport the joined session is running over.

See *Authentication* for a description of the "authid",
"authrole", "authmethod" and "authprovider" properties.

14.5.1.2.2. wamp.session.on_leave

Fired when a session leaves a realm on the router or is disconnected.
The event payload consists of a single positional argument
"session|id" with the session ID of the session that left.

14.5.1.3. Session Meta Procedures

A client can actively retrieve information about sessions via the
following meta-procedures:

o "wamp.session.count": Obtains the number of sessions currently
attached to the realm.

o "wamp.session.list": Retrieves a list of the session IDs for all
sessions currently attached to the realm.

o "wamp.session.get": Retrieves information on a specific session.

Session meta procedures MUST be registered by the _Router_ on the
same realm as the ITMP session about which information is retrieved.

14.5.1.3.1. wamp.session.count

Obtains the number of sessions currently attached to the realm:

*Positional arguments*

1. "filter_authroles|list[string]" - Optional filter: if provided,
only count sessions with an "authrole" from this list.

*Positional results*

1. "count|int" - The number of sessions currently attached to the
realm.

14.5.1.3.2. wamp.session.list

Retrieves a list of the session IDs for all sessions currently
attached to the realm.

*Positional arguments*



Oberstein & Goedde Expires April 13, 2016 [Page 108]

Internet-Draft ITMP October 2015


1. "filter_authroles|list[string]" - Optional filter: if provided,
only count sessions with an "authrole" from this list.

*Positional results*

1. "session_ids|list" - List of ITMP session IDs (order undefined).

14.5.1.3.3. wamp.session.get

Retrieves information on a specific session.

*Positional arguments*

1. "session|id" - The session ID of the session to retrieve details
for.

*Positional results*

1. "details|dict" - Information on a particular session:

* "session|id" - The session ID of the session that joined

* "authid|string" - The authentication ID of the session that
joined

* "authrole|string" - The authentication role of the session
that joined

* "authmethod|string" - The authentication method that was used
for authentication the session that joined

* "authprovider|string"- The provider that performed the
authentication of the session that joined

* "transport|dict" - Optional, implementation defined
information about the ITMP transport the joined session is
running over.

See *Authentication* for a description of the "authid",
"authrole", "authmethod" and "authprovider" properties.

*Errors*

o "wamp.error.no_such_session" - No session with the given ID exists
on the router.






Oberstein & Goedde Expires April 13, 2016 [Page 109]

Internet-Draft ITMP October 2015


14.5.1.4. Feature Announcement

Support for this feature MUST be announced by *both* _Dealers_ and
_Brokers_ via:

HELLO.Details.roles.<role>.features.
session_meta_api|bool := true

*Example*

Here is a "WELCOME" message from a _Router_ with support for both the
_Broker_ and _Dealer_ role, and with support for *Session Meta API*:

[
2,
4580268554656113,
{
"authid":"OL3AeppwDLXiAAPbqm9IVhnw",
"authrole": "anonymous",
"authmethod": "anonymous",
"roles": {
"broker": {
"features": {
"session_meta_api": true
}
},
"dealer": {
"features": {
"session_meta_api": true
}
}
}
}
]

Note in particular that the feature is announced on both the
_Broker_ and the _Dealer_ roles.

14.5.2. Authentication

Authentication is a complex area.

Some applications might want to leverage authentication information
coming from the transport underlying ITMP, e.g. HTTP cookies or TLS
certificates.






Oberstein & Goedde Expires April 13, 2016 [Page 110]

Internet-Draft ITMP October 2015


Some transports might imply trust or implicit authentication by their
very nature, e.g. Unix domain sockets with appropriate file system
permissions in place.

Other application might want to perform their own authentication
using external mechanisms (completely outside and independent of
ITMP).

Some applications might want to perform their own authentication
schemes by using basic ITMP mechanisms, e.g. by using application-
defined remote procedure calls.

And some applications might want to use a transport independent
scheme, nevertheless predefined by ITMP.

14.5.2.1. ITMP-level Authentication

The message flow between Clients and Routers for establishing and
tearing down sessions MAY involve the following messages which
authenticate a session:

1. "CHALLENGE"

2. "AUTHENTICATE"

,------. ,------.
|Client| |Router|
`--+---' `--+---'
| HELLO |
| ---------------->
| |
| CHALLENGE |
| <----------------
| |
| AUTHENTICATE |
| ---------------->
| |
| WELCOME or ABORT|
| <----------------
,--+---. ,--+---.
|Client| |Router|
`------' `------'

Concrete use of "CHALLENGE" and "AUTHENTICATE" messages depends on
the specific authentication method.

See Section 14.5.2.3 or Section 14.5.2.4 for the use in these
authentication methods.



Oberstein & Goedde Expires April 13, 2016 [Page 111]

Internet-Draft ITMP October 2015


If two-factor authentication is desired, then two subsequent rounds
of "CHALLENGE" and "RESPONSE" may be employed.

14.5.2.1.1. CHALLENGE

An authentication MAY be required for the establishment of a session.
Such requirement MAY be based on the "Realm" the connection is
requested for.

To request authentication, the Router MUST send a "CHALLENGE" message
to the _Endpoint_.

[CHALLENGE, AuthMethod|string, Extra|dict]

14.5.2.1.2. AUTHENTICATE

In response to a "CHALLENGE" message, the Client MUST send an
"AUTHENTICATION" message.

[AUTHENTICATE, Signature|string, Extra|dict]

If the authentication succeeds, the Router MUST send a "WELCOME"
message, else it MUST send an "ABORT" message.

14.5.2.2. Transport-level Authentication

14.5.2.2.1. Cookie-based Authentication

When running ITMP over WebSocket, the transport provides HTTP client
cookies during the WebSocket opening handshake. The cookies can be
used to authenticate one peer (the client) against the other (the
server). The other authentication direction cannot be supported by
cookies.

This transport-level authentication information may be forward to the
ITMP level within "HELLO.Details.transport.auth|any" in the client-
to-server direction.

14.5.2.2.2. TLS Certificate Authentication

When running ITMP over a TLS (either secure WebSocket or raw TCP)
transport, a peer may authenticate to the other via the TLS
certificate mechanism. A server might authenticate to the client,
and a client may authenticate to the server (TLS client-certificate
based authentication).






Oberstein & Goedde Expires April 13, 2016 [Page 112]

Internet-Draft ITMP October 2015


This transport-level authentication information may be forward to the
ITMP level within "HELLO.Details.transport.auth|any" in both
directions (if available).

14.5.2.3. Challenge Response Authentication

ITMP Challenge-Response ("ITMP-CRA") authentication is a simple,
secure authentication mechanism using a shared secret. The client
and the server share a secret. The secret never travels the wire,
hence ITMP-CRA can be used via non-TLS connections. The actual pre-
sharing of the secret is outside the scope of the authentication
mechanism.

A typical authentication begins with the client sending a "HELLO"
message specifying the "wampcra" method as (one of) the
authentication methods:

[1, "realm1",
{
"roles": ...,
"authmethods": ["wampcra"],
"authid": "peter"
}
]

The "HELLO.Details.authmethods|list" is used by the client to
announce the authentication methods it is prepared to perform. For
ITMP-CRA, this MUST include ""wampcra"".

The "HELLO.Details.authid|string" is the authentication ID (e.g.
username) the client wishes to authenticate as. For ITMP-CRA, this
MUST be provided.

If the server is unwilling or unable to perform ITMP-CRA
authentication, it MAY either skip forward trying other
authentication methods (if the client announced any) or send an
"ABORT" message.

If the server is willing to let the client authenticate using ITMP-
CRA, and the server recognizes the provided "authid", it MUST send a
"CHALLENGE" message:










Oberstein & Goedde Expires April 13, 2016 [Page 113]

Internet-Draft ITMP October 2015


[4, "wampcra",
{
"challenge": "{ \"nonce\": \"LHRTC9zeOIrt_9U3\",
\"authprovider\": \"userdb\", \"authid\": \"peter\",
\"timestamp\": \"2014-06-22T16:36:25.448Z\",
\"authrole\": \"user\", \"authmethod\": \"wampcra\",
\"session\": 3251278072152162}"
}
]

The "CHALLENGE.Details.challenge|string" is a string the client needs
to create a signature for. The string MUST BE a JSON serialized
object which MUST contain:

1. "authid|string": The authentication ID the client will be
authenticated as when the authentication succeeds.

2. "authrole|string": The authentication role the client will be
authenticated as when the authentication succeeds.

3. "authmethod|string": The authentication methods, here ""wampcra""

4. "authprovider|string": The actual provider of authentication.
For ITMP-CRA, this can be freely chosen by the app, e.g.
"userdb".

5. "nonce|string": A random value.

6. "timestamp|string": The UTC timestamp (ISO8601 format) the
authentication was started, e.g. "2014-06-22T16:51:41.643Z".

7. "session|int": The ITMP session ID that will be assigned to the
session once it is authenticated successfully.

The client needs to compute the signature as follows:

signature := HMAC[SHA256]_{secret} (challenge)

That is, compute the HMAC-SHA256 using the shared "secret" over the
"challenge".

After computing the signature, the client will send an "AUTHENTICATE"
message containing the signature:

[5, "gir1mSx+deCDUV7wRM5SGIn/+R/ClqLZuH4m7FJeBVI=", {}]

The server will then check if




Oberstein & Goedde Expires April 13, 2016 [Page 114]

Internet-Draft ITMP October 2015


o the signature matches the one expected

o the "AUTHENTICATE" message was sent in due time

If the authentication succeeds, the server will finally respond with
a "WELCOME" message:

[2, 3251278072152162,
{
"authid": "peter",
"authrole": "user",
"authmethod": "wampcra",
"authprovider": "userdb",
"roles": ...
}
]

The "WELCOME.Details" again contain the actual authentication
information active.

If the authentication fails, the server will response with an "ABORT"
message.

14.5.2.3.1. Server-side Verification

The challenge sent during ITMP-CRA contains

1. random information (the "nonce") to make ITMP-CRA robust against
replay attacks

2. timestamp information (the "timestamp") to allow ITMP-CRA timeout
on authentication requests that took too long

3. session information (the "session") to bind the authentication to
a ITMP session ID

4. all the authentication information that relates to authorization
like "authid" and "authrole"

14.5.2.3.2. Three-legged Authentication

The signing of the challenge sent by the server usually is done
directly on the client. However, this is no strict requirement.

E.g. a client might forward the challenge to another party (hence the
"three-legged") for creating the signature. This can be used when
the client was previously already authenticated to that third party,
and ITMP-CRA should run piggy packed on that authentication.



Oberstein & Goedde Expires April 13, 2016 [Page 115]

Internet-Draft ITMP October 2015


The third party would, upon receiving a signing request, simply check
if the client is already authenticated, and if so, create a signature
for ITMP-CRA.

In this case, the secret is actually shared between the ITMP server
who wants to authenticate clients using ITMP-CRA and the third party
server, who shares a secret with the ITMP server.

This scenario is also the reason the challenge sent with ITMP-CRA is
not simply a random value, but a JSON serialized object containing
sufficient authentication information for the thrid party to check.

14.5.2.3.3. Password Salting

ITMP-CRA operates using a shared secret. While the secret is never
sent over the wire, a shared secret often requires storage of that
secret on the client and the server - and storing a password verbatim
(unencrypted) is not recommended in general.

ITMP-CRA allows the use of salted passwords following the PBKDF2 [5]
key derivation scheme. With salted passwords, the password itself is
never stored, but only a key derived from the password and a password
salt. This derived key is then practically working as the new shared
secret.

When the password is salted, the server will during ITMP-CRA send a
"CHALLENGE" message containing additional information:

[4, "wampcra",
{
"challenge": "{ \"nonce\": \"LHRTC9zeOIrt_9U3\",
\"authprovider\": \"userdb\", \"authid\": \"peter\",
\"timestamp\": \"2014-06-22T16:36:25.448Z\",
\"authrole\": \"user\", \"authmethod\": \"wampcra\",
\"session\": 3251278072152162}",
"salt": "salt123",
"keylen": 32,
"iterations": 1000
}
]

The "CHALLENGE.Details.salt|string" is the password salt in use. The
"CHALLENGE.Details.keylen|int" and "CHALLENGE.Details.iterations|int"
are parameters for the PBKDF2 algorithm.







Oberstein & Goedde Expires April 13, 2016 [Page 116]

Internet-Draft ITMP October 2015


14.5.2.4. Ticket-based Authentication

With _Ticket-based authentication_, the client needs to present the
server an authentication "ticket" - some magic value to authenticate
itself to the server.

This "ticket" could be a long-lived, pre-agreed secret (e.g. a user
password) or a short-lived authentication token (like a Kerberos
token). ITMP does not care or interpret the ticket presented by the
client.

Caution: This scheme is extremely simple and flexible, but the
resulting security may be limited. E.g., the ticket value will be
sent over the wire. If the transport ITMP is running over is not
encrypted, a man-in-the-middle can sniff and possibly hijack the
ticket. If the ticket value is reused, that might enable replay
attacks.

A typical authentication begins with the client sending a "HELLO"
message specifying the "ticket" method as (one of) the authentication
methods:

[1, "realm1",
{
"roles": ...,
"authmethods": ["ticket"],
"authid": "joe"
}
]

The "HELLO.Details.authmethods|list" is used by the client to
announce the authentication methods it is prepared to perform. For
Ticket-based, this MUST include ""ticket"".

The "HELLO.Details.authid|string" is the authentication ID (e.g.
username) the client wishes to authenticate as. For Ticket-based
authentication, this MUST be provided.

If the server is unwilling or unable to perform Ticket-based
authentication, it'll either skip forward trying other authentication
methods (if the client announced any) or send an "ABORT" message.

If the server is willing to let the client authenticate using a
ticket and the server recognizes the provided "authid", it'll send a
"CHALLENGE" message:

[4, "ticket", {}]




Oberstein & Goedde Expires April 13, 2016 [Page 117]

Internet-Draft ITMP October 2015


The client will send an "AUTHENTICATE" message containing a ticket:

[5, "secret!!!", {}]

The server will then check if the ticket provided is permissible (for
the "authid" given).

If the authentication succeeds, the server will finally respond with
a "WELCOME" message:

[2, 3251278072152162,
{
"authid": "joe",
"authrole": "user",
"authmethod": "ticket",
"authprovider": "static",
"roles": ...
}
]

where

1. "authid|string": The authentication ID the client was (actually)
authenticated as.

2. "authrole|string": The authentication role the client was
authenticated for.

3. "authmethod|string": The authentication method, here ""ticket""

4. "authprovider|string": The actual provider of authentication.
For Ticket-based authentication, this can be freely chosen by the
app, e.g. "static" or "dynamic".

The "WELCOME.Details" again contain the actual authentication
information active. If the authentication fails, the server will
response with an "ABORT" message.

14.5.3. Alternative Transports

The only requirements that ITMP expects from a transport are: the
transport must be message-based, bidirectional, reliable and ordered.
This allows ITMP to run over different transports without any impact
at the application layer.

Besides the WebSocket transport, the following ITMP transports are
currently specified:




Oberstein & Goedde Expires April 13, 2016 [Page 118]

Internet-Draft ITMP October 2015


o Section 14.5.3.1

o Section 14.5.3.2

o Section 14.5.3.3

o Section 14.5.3.4

Other transports such as HTTP 2.0 ("SPDY") or UDP might be defined
in the future.

14.5.3.1. RawSocket Transport

*ITMP-over-RawSocket* is an (alternative) transport for ITMP that
uses length-prefixed, binary messages - a message framing different
from WebSocket.

Compared to ITMP-over-WebSocket, ITMP-over-RawSocket is simple to
implement, since there is no need to implement the WebSocket protocol
which has some features that make it non-trivial (like a full HTTP-
based opening handshake, message fragmentation, masking and variable
length integers).

ITMP-over-RawSocket has even lower overhead than WebSocket, which can
be desirable in particular when running on local connections like
loopback TCP or Unix domain sockets. It is also expected to allow
implementations in microcontrollers in under 2KB RAM.

ITMP-over-RawSocket can run over TCP, TLS, Unix domain sockets or any
reliable streaming underlying transport. When run over TLS on the
standard port for secure HTTPS (443), it is also able to traverse
most locked down networking environments such as enterprise or mobile
networks (unless man-in-the-middle TLS intercepting proxies are in
use).

However, ITMP-over-RawSocket cannot be used with Web browser clients,
since browsers do not allow raw TCP connections. Browser extensions
would do, but those need to be installed in a browser. ITMP-over-
RawSocket also (currently) does not support transport-level
compression as WebSocket does provide ("permessage-deflate" WebSocket
extension).

14.5.3.1.1. Endianess

ITMP-over-RawSocket uses _network byte order_ ("big-endian"). That
means, given a unsigned 32 bit integer

0x 11 22 33 44



Oberstein & Goedde Expires April 13, 2016 [Page 119]

Internet-Draft ITMP October 2015


the first octet sent out to (or received from) the wire is "0x11" and
the last octet sent out (or received) is "0x44".

Here is how you would convert octets received from the wire into an
integer in Python:

<CODE BEGINS>
import struct

octets_received = b"\x11\x22\x33\x44"
i = struct.unpack(">L", octets_received)[0]
<CODE ENDS>

The integer received has the value "287454020".

And here is how you would send out an integer to the wire in Python:

<CODE BEGINS>
octets_to_be_send = struct.pack(">L", i)
<CODE ENDS>

The octets to be sent are "b"\x11\x22\x33\x44"".

14.5.3.1.2. Handshake

*Client-to-Router Request*

ITMP-over-RawSocket starts with a handshake where the client
connecting to a router sends 4 octets:

MSB LSB
31 0
0111 1111 LLLL SSSS RRRR RRRR RRRR RRRR

The _first octet_ is a magic octet with value "0x7F". This value is
chosen to avoid any possible collision with the first octet of a
valid HTTP request (see here [6] and here [7]). No valid HTTP
request can have "0x7F" as its first octet.

By using a magic first octet that cannot appear in a regular HTTP
request, ITMP-over-RawSocket can be run e.g. on the same TCP
listening port as ITMP-over-WebSocket or ITMP-over-LongPoll.

The _second octet_ consists of a 4 bit "LENGTH" field and a 4 bit
"SERIALIZER" field.

The "LENGTH" value is used by the _Client_ to signal the *maximum
message length* of messages it is willing to *receive*. When the



Oberstein & Goedde Expires April 13, 2016 [Page 120]

Internet-Draft ITMP October 2015


handshake completes successfully, a _Router_ MUST NOT send messages
larger than this size.

The possible values for "LENGTH" are:

0: 2**9 octets
1: 2**10 octets
...
15: 2**24 octets

This means a _Client_ can choose the maximum message length between
*512* and *16M* octets.

The "SERIALIZER" value is used by the _Client_ to request a specific
serializer to be used. When the handshake completes successfully,
the _Client_ and _Router_ will use the serializer requested by the
_Client_.

The possible values for "SERIALIZER" are:

0: illegal
1: JSON
2: MsgPack
3 - 15: reserved for future serializers

Here is a Python program that prints all (currently) permissible
values for the _second octet_:

<CODE BEGINS>
SERMAP = {
1: 'json',
2: 'msgpack'
}

## map serializer / max. msg length to RawSocket handshake
## request or success reply (2nd octet)
##
for ser in SERMAP:
for l in range(16):
octet_2 = (l << 4) | ser
print("serializer: {}, maxlen: {} =>
0x{:02x}".format(SERMAP[ser], 2 ** (l + 9), octet_2))
<CODE ENDS>

The _third and forth octet_ are *reserved* and MUST be all zeros for
now.

*Router-to-Client Reply*



Oberstein & Goedde Expires April 13, 2016 [Page 121]

Internet-Draft ITMP October 2015


After a _Client_ has connected to a _Router_, the _Router_ will first
receive the 4 octets handshake request from the _Client_.

If the _first octet_ differs from "0x7F", it is not a ITMP-over-
RawSocket request. Unless the _Router_ also supports other
transports on the connecting port (such as WebSocket or LongPoll),
the _Router_ MUST *fail the connection*.

Here is an example of how a _Router_ could parse the _second octet_
in a _Clients_ handshake request:

<CODE BEGINS>
## map RawSocket handshake request (2nd octet) to
## serializer / max. msg length
##
for i in range(256):
ser_id = i & 0x0f
if ser_id != 0:
ser = SERMAP.get(ser_id, 'currently undefined')
maxlen = 2 ** ((i >> 4) + 9)
print("{:02x} => serializer: {}, maxlen: {}".
format(i, ser, maxlen))
else:
print("fail the connection: illegal serializer value")
<CODE ENDS>

When the _Router_ is willing to speak the serializer requested by the
_Client_, it will answer with a 4 octets response of identical
structure as the _Client_ request:

MSB LSB
31 0
0111 1111 LLLL SSSS RRRR RRRR RRRR RRRR

Again, the _first octet_ MUST be the value "0x7F". The _third and
forth octets_ are reserved and MUST be all zeros for now.

In the _second octet_, the _Router_ MUST echo the serializer value in
"SERIALIZER" as requested by the _Client_.

Similar to the _Client_, the _Router_ sets the "LENGTH" field to
request a limit on the length of messages sent by the _Client_.

During the connection, _Router_ MUST NOT send messages to the
_Client_ longer than the "LENGTH" requested by the _Client_, and the
_Client_ MUST NOT send messages larger than the maximum requested by
the _Router_ in it's handshake reply.




Oberstein & Goedde Expires April 13, 2016 [Page 122]

Internet-Draft ITMP October 2015


If a message received during a connection exceeds the limit
requested, a _Peer_ MUST *fail the connection*.

When the _Router_ is unable to speak the serializer requested by the
_Client_, or it is denying the _Client_ for other reasons, the
_Router_ replies with an error:

MSB LSB
31 0
0111 1111 EEEE 0000 RRRR RRRR RRRR RRRR

An error reply has 4 octets: the _first octet_ is again the magic
"0x7F", and the _third and forth octet_ are reserved and MUST all be
zeros for now.

The _second octet_ has its lower 4 bits zero'ed (which distinguishes
the reply from an success/accepting reply) and the upper 4 bits
encode the error:

0: illegal (must not be used)
1: serializer unsupported
2: maximum message length unacceptable
3: use of reserved bits (unsupported feature)
4: maximum connection count reached
5 - 15: reserved for future errors

Note that the error code "0" MUST NOT be used. This is to allow
storage of error state in a host language variable, while allowing
"0" to signal the current state "no error"

Here is an example of how a _Router_ might create the _second octet_
in an error response:

<CODE BEGINS>
ERRMAP = {
0: "illegal (must not be used)",
1: "serializer unsupported",
2: "maximum message length unacceptable",
3: "use of reserved bits (unsupported feature)",
4: "maximum connection count reached"
}

## map error to RawSocket handshake error reply (2nd octet)
##
for err in ERRMAP:
octet_2 = err << 4
print("error: {} => 0x{:02x}").format(ERRMAP[err], err)
<CODE ENDS>



Oberstein & Goedde Expires April 13, 2016 [Page 123]

Internet-Draft ITMP October 2015


The _Client_ - after having sent its handshake request - will wait
for the 4 octets from _Router_ handshake reply.

Here is an example of how a _Client_ might parse the _second octet_
in a _Router_ handshake reply:

<CODE BEGINS>
## map RawSocket handshake reply (2nd octet)
##
for i in range(256):
ser_id = i & 0x0f
if ser_id:
## verify the serializer is the one we requested!
## if not, fail the connection!
ser = SERMAP.get(ser_id, 'currently undefined')
maxlen = 2 ** ((i >> 4) + 9)
print("{:02x} => serializer: {}, maxlen: {}".
format(i, ser, maxlen))
else:
err = i >> 4
print("error: {}".format(ERRMAP.get(err,
'currently undefined')))
<CODE ENDS>

14.5.3.1.3. Serialization

To send a ITMP message, the message is serialized according to the
ITMP serializer agreed in the handshake (e.g. JSON or MsgPack).

The length of the serialized messages in octets MUST NOT exceed the
maximum requested by the _Peer_.

If the serialized length exceed the maximum requested, the ITMP
message can not be sent to the _Peer_. Handling situations like the
latter is left to the implementation.

E.g. a _Router_ that is to forward a ITMP "EVENT" to a _Client_ which
exceeds the maximum length requested by the _Client_ when serialized
might:

o drop the event (not forwarding to that specific client) and track
dropped events

o prohibit publishing to the topic already

o remove the event payload, and send an event with extra information
("payload_limit_exceeded = true")


14.5.3.1.4. Framing

The serialized octets for a message to be sent are prefixed with
exactly 4 octets.

MSB LSB
31 0
RRRR RTTT LLLL LLLL LLLL LLLL LLLL LLLL

The _first octet_ has the following structure

MSB LSB
7 0
RRRR RTTT

The five bits "RRRRR" are reserved for future use and MUST be all
zeros for now.

The three bits "TTT" encode the type of the transport message:

0: regular ITMP message
1: PING
2: PONG
3-7: reserved

The _three remaining octets_ constitute an unsigned 24 bit integer
that provides the length of transport message payload following,
excluding the 4 octets that constitute the prefix.

For a regular ITMP message ("TTT == 0"), the length is the length of
the serialized ITMP message: the number of octets after serialization
(excluding the 4 octets of the prefix).

For a "PING" message ("TTT == 1"), the length is the length of the
arbitrary payload that follows. A _Peer_ MUST reply to each "PING"
by sending exactly one "PONG" immediately, and the "PONG" MUST echo
back the payload of the "PING" exactly.

For receiving messages with ITMP-over-RawSocket, a _Peer_ will
usually read exactly 4 octets from the incoming stream, decode the
transport level message type and payload length, and then receive as
many octets as the length was giving.

When the transport level message type indicates a regular ITMP
message, the transport level message payload is unserialized
according to the serializer agreed in the handshake and the processed
at the ITMP level.

14.5.3.2. Batched WebSocket Transport for ITMP

_ITMP-over-Batched-WebSocket_ is a variant of ITMP-over-WebSocket
where multiple ITMP messages are sent in one WebSocket message.

Using ITMP message batching can increase wire level efficiency
further. In particular when using TLS and the WebSocket
implementation is forcing every WebSocket message into a new TLS
segment.

ITMP-over-Batched-WebSocket is negotiated between Peers in the
WebSocket opening handshake by agreeing on one of the following
WebSocket subprotocols:

o "wamp.2.json.batched"

o "wamp.2.msgpack.batched"

Batching with JSON works by serializing each ITMP message to JSON as
normally, appending the single ASCII control character "\30" (record
separator [8]) octet "0x1e" to _each_ serialized messages, and
packing a sequence of such serialized messages into a single
WebSocket message:

Serialized JSON ITMP Msg 1 | 0x1e |
Serialized JSON ITMP Msg 2 | 0x1e | ...

Batching with MsgPack works by serializing each ITMP message to
MsgPack as normally, prepending a 32 bit unsigned integer (4 octets
in big-endian byte order) with the length of the serialized MsgPack
message (excluding the 4 octets for the length prefix), and packing a
sequence of such serialized (length-prefixed) messages into a single
WebSocket message:

Length of Msg 1 serialization (uint32) |
serialized MsgPack ITMP Msg 1 | ...

With batched transport, even if only a single ITMP message is to be
sent in a WebSocket message, the (single) ITMP message needs to be
framed as described above. In other words, a single ITMP message is
sent as a batch of length *1*. Sending a batch of length *0* (no ITMP
message) is illegal and a _Peer_ MUST fail the transport upon
receiving such a transport message.








Oberstein & Goedde Expires April 13, 2016 [Page 126]

Internet-Draft ITMP October 2015


14.5.3.3. A HTTP Longpoll Transport for ITMP

The _Long-Poll Transport_ is able to transmit a ITMP session over
plain old HTTP 1.0/1.1. This is realized by the Client issuing HTTP/
POSTs requests, one for sending, and one for receiving. Those latter
requests are kept open at the server when there are no messages
currently pending to be received.

*Opening a Session*

With the Long-Poll Transport, a Client opens a new ITMP session by
sending a HTTP/POST request to a well-known URL, e.g.

http://mypp.com/longpoll/open

Here, "http://mypp.com/longpoll" is the base URL for the Long-Poll
Transport and "/open" is a path dedicated for opening new sessions.

The HTTP/POST request SHOULD have a "Content-Type" header set to
"application/json" and MUST have a request body with a JSON document
that is a dictionary:

{
"protocols": ["wamp.2.json"]
}

The (mandatory) "protocols" attribute specifies the protocols the
client is willing to speak. The server will chose one from this list
when establishing the session or fail the request when no protocol
overlap was found.

The valid protocols are:

o "wamp.2.json.batched"

o "wamp.2.json"

o "wamp.2.msgpack.batched"

o "wamp.2.msgpack"

The request path with this and subsequently described HTTP/POST
requests MAY contain a query parameter "x" with some random or
sequentially incremented value:

<http://mypp.com/longpoll/open?x=382913>





Oberstein & Goedde Expires April 13, 2016 [Page 127]

Internet-Draft ITMP October 2015


The value is ignored, but may help in certain situations to
prevent intermediaries from caching the request.

Returned is a JSON document containing a transport ID and the
protocol to speak:

{
"protocol": "wamp.2.json",
"transport": "kjmd3sBLOUnb3Fyr"
}

As an implied side-effect, two HTTP endpoints are created

http://mypp.com/longpoll/<transport_id>/receive
http://mypp.com/longpoll/<transport_id>/send

where "transport_id" is the transport ID returned from "open", e.g.

http://mypp.com/longpoll/kjmd3sBLOUnb3Fyr/receive
http://mypp.com/longpoll/kjmd3sBLOUnb3Fyr/send

*Receiving ITMP Messages*

The Client will then issue HTTP/POST requests (with empty request
body) to

http://mypp.com/longpoll/kjmd3sBLOUnb3Fyr/receive

When there are ITMP messages pending downstream, a request will
return with a single ITMP message (unbatched modes) or a batch of
serialized ITMP messages (batched mode).

The serialization format used is the one agreed during opening the
session.

The batching uses the same scheme as with "wamp.2.json.batched" and
"wamp.2.msgpack.batched" transport over WebSocket.

Note: In unbatched mode, when there is more than one message
pending, there will be at most one message returned for each
request. The other pending messages must be retrieved by new
requests. With batched mode, all messages pending at request time
will be returned in one batch of messages.

*Sending ITMP Messages*

For sending ITMP messages, the _Client_ will issue HTTP/POST requests
to



Oberstein & Goedde Expires April 13, 2016 [Page 128]

Internet-Draft ITMP October 2015


http://mypp.com/longpoll/kjmd3sBLOUnb3Fyr/send

with request body being a single ITMP message (unbatched modes) or a
batch of serialized ITMP messages (batched mode).

The serialization format used is the one agreed during opening the
session.

The batching uses the same scheme as with "wamp.2.json.batched" and
"wamp.2.msgpack.batched" transport over WebSocket.

Upon success, the request will return with HTTP status code 202 ("no
content"). Upon error, the request will return with HTTP status code
400 ("bad request").

*Closing a Session*

To orderly close a session, a Client will issue a HTTP/POST to

http://mypp.com/longpoll/kjmd3sBLOUnb3Fyr/close

with an empty request body. Upon success, the request will return
with HTTP status code 202 ("no content").

14.5.3.4. Multiplexed Transport

A Transport may support the multiplexing of multiple logical
transports over a single "physical" transport.

By using such a Transport, multiple ITMP sessions can be transported
over a single underlying transport at the same time.

As an example, the proposed WebSocket extension "permessage-priority"
[9] would allow creating multiple logical Transports for ITMP over a
single underlying WebSocket connection.

Sessions running over a multiplexed Transport are completely
independent: they get assigned different session IDs, may join
different realms and each session needs to authenticate itself.

Because of above, Multiplexed Transports for ITMP are actually not
detailed in the ITMP spec, but a feature of the transport being used.

Note: Currently no ITMP transport supports multiplexing. The work
on the MUX extension with WebSocket has stalled, and the
"permessage-priority" proposal above is still just a proposal.
However, with RawSocket, we should be able to add multiplexing in
the the future (with downward compatibility).



Oberstein & Goedde Expires April 13, 2016 [Page 129]

Internet-Draft ITMP October 2015


14.5.3.5. Ticket-based Authentication

With _Ticket-based authentication_, the client needs to present the
server an authentication "ticket" - some magic value to authenticate
itself to the server.

This "ticket" could be a long-lived, pre-agreed secret (e.g. a user
password) or a short-lived authentication token (like a Kerberos
token). ITMP does not care or interpret the ticket presented by the
client.

Caution: This scheme is extremely simple and flexible, but the
resulting security may be limited. E.g., the ticket value will be
sent over the wire. If the transport ITMP is running over is not
encrypted, a man-in-the-middle can sniff and possibly hijack the
ticket. If the ticket value is reused, that might enable replay
attacks.

A typical authentication begins with the client sending a "HELLO"
message specifying the "ticket" method as (one of) the authentication
methods:

[1, "realm1",
{
"roles": ...,
"authmethods": ["ticket"],
"authid": "joe"
}
]

The "HELLO.Details.authmethods|list" is used by the client to
announce the authentication methods it is prepared to perform. For
Ticket-based, this MUST include ""ticket"".

The "HELLO.Details.authid|string" is the authentication ID (e.g.
username) the client wishes to authenticate as. For Ticket-based
authentication, this MUST be provided.

If the server is unwilling or unable to perform Ticket-based
authentication, it'll either skip forward trying other authentication
methods (if the client announced any) or send an "ABORT" message.

If the server is willing to let the client authenticate using a
ticket and the server recognizes the provided "authid", it'll send a
"CHALLENGE" message:

[4, "ticket", {}]




Oberstein & Goedde Expires April 13, 2016 [Page 130]

Internet-Draft ITMP October 2015


The client will send an "AUTHENTICATE" message containing a ticket:

[5, "secret!!!", {}]

The server will then check if the ticket provided is permissible (for
the "authid" given).

If the authentication succeeds, the server will finally respond with
a "WELCOME" message:

[2, 3251278072152162,
{
"authid": "joe",
"authrole": "user",
"authmethod": "ticket",
"authprovider": "static",
"roles": ...
}
]

where

1. "authid|string": The authentication ID the client was (actually)
authenticated as.

2. "authrole|string": The authentication role the client was
authenticated for.

3. "authmethod|string": The authentication method, here ""ticket""

4. "authprovider|string": The actual provider of authentication.
For Ticket-based authentication, this can be freely chosen by the
app, e.g. "static" or "dynamic".

The "WELCOME.Details" again contain the actual authentication
information active. If the authentication fails, the server will
response with an "ABORT" message.

14.5.3.6. Ticket-based Authentication

With _Ticket-based authentication_, the client needs to present the
server an authentication "ticket" - some magic value to authenticate
itself to the server.

This "ticket" could be a long-lived, pre-agreed secret (e.g. a user
password) or a short-lived authentication token (like a Kerberos
token). ITMP does not care or interpret the ticket presented by the
client.



Oberstein & Goedde Expires April 13, 2016 [Page 131]

Internet-Draft ITMP October 2015


Caution: This scheme is extremely simple and flexible, but the
resulting security may be limited. E.g., the ticket value will be
sent over the wire. If the transport ITMP is running over is not
encrypted, a man-in-the-middle can sniff and possibly hijack the
ticket. If the ticket value is reused, that might enable replay
attacks.

A typical authentication begins with the client sending a "HELLO"
message specifying the "ticket" method as (one of) the authentication
methods:

[1, "realm1",
{
"roles": ...,
"authmethods": ["ticket"],
"authid": "joe"
}
]

The "HELLO.Details.authmethods|list" is used by the client to
announce the authentication methods it is prepared to perform. For
Ticket-based, this MUST include ""ticket"".

The "HELLO.Details.authid|string" is the authentication ID (e.g.
username) the client wishes to authenticate as. For Ticket-based
authentication, this MUST be provided.

If the server is unwilling or unable to perform Ticket-based
authentication, it'll either skip forward trying other authentication
methods (if the client announced any) or send an "ABORT" message.

If the server is willing to let the client authenticate using a
ticket and the server recognizes the provided "authid", it'll send a
"CHALLENGE" message:

[4, "ticket", {}]

The client will send an "AUTHENTICATE" message containing a ticket:

[5, "secret!!!", {}]

The server will then check if the ticket provided is permissible (for
the "authid" given).

If the authentication succeeds, the server will finally respond with
a "WELCOME" message:





Oberstein & Goedde Expires April 13, 2016 [Page 132]

Internet-Draft ITMP October 2015


[2, 3251278072152162,
{
"authid": "joe",
"authrole": "user",
"authmethod": "ticket",
"authprovider": "static",
"roles": ...
}
]

where

1. "authid|string": The authentication ID the client was (actually)
authenticated as.

2. "authrole|string": The authentication role the client was
authenticated for.

3. "authmethod|string": The authentication method, here ""ticket""

4. "authprovider|string": The actual provider of authentication.
For Ticket-based authentication, this can be freely chosen by the
app, e.g. "static" or "dynamic".

The "WELCOME.Details" again contain the actual authentication
information active. If the authentication fails, the server will
response with an "ABORT" message.

15. Binary conversion of JSON Strings

Binary data follows a convention for conversion to JSON strings.

A byte array is converted to a JSON string as follows:

1. convert the byte array to a Base64 encoded (host language) string

2. prepend the string with a "\0" character

3. serialize the string to a JSON string

where Base64 encoding follows Section 4 of [RFC4648].

_Example_

Consider the byte array (hex representation):

10e3ff9053075c526f5fc06d4fe37cdb




Oberstein & Goedde Expires April 13, 2016 [Page 133]

Internet-Draft ITMP October 2015


This will get converted to Base64

EOP/kFMHXFJvX8BtT+N82w==

prepended with "\0"

\x00EOP/kFMHXFJvX8BtT+N82w==

and serialized to a JSON string

"\\u0000EOP/kFMHXFJvX8BtT+N82w=="

A JSON string is unserialized to either a string or a byte array
using the following procedure:

1. Unserialize a JSON string to a host language (Unicode) string

2. If the string starts with a "\0" character, interpret the rest
(after the first character) as Base64 and decode to a byte array

3. Otherwise, return the Unicode string

Below are complete Python and JavaScript code examples for conversion
between byte arrays and JSON strings.

15.1. Python

Here is a complete example in Python showing how byte arrays are
converted to and from JSON:






















Oberstein & Goedde Expires April 13, 2016 [Page 134]

Internet-Draft ITMP October 2015


<CODE BEGINS>

import os, base64, json, sys, binascii
PY3 = sys.version_info >= (3,)
if PY3:
unicode = str

data_in = os.urandom(16)
print("In: {}".format(binascii.hexlify(data_in)))

## encoding
encoded = json.dumps('\0' + base64.b64encode(data_in).
decode('ascii'))

print("JSON: {}".format(encoded))

## decoding
decoded = json.loads(encoded)
if type(decoded) == unicode:
if decoded[0] == '\0':
data_out = base64.b64decode(decoded[1:])
else:
data_out = decoded

print("Out: {}".format(binascii.hexlify(data_out)))

assert(data_out == data_in)

<CODE ENDS>

15.2. JavaScript

Here is a complete example in JavaScript showing how byte arrays are
converted to and from JSON:

















Oberstein & Goedde Expires April 13, 2016 [Page 135]

Internet-Draft ITMP October 2015


<CODE BEGINS>

var data_in = new Uint8Array(new ArrayBuffer(16));

// initialize test data
for (var i = 0; i < data_in.length; ++i) {
data_in[i] = i;
}
console.log(data_in);

// convert byte array to raw string
var raw_out = '';
for (var i = 0; i < data_in.length; ++i) {
raw_out += String.fromCharCode(data_in[i]);
}

// base64 encode raw string, prepend with \0
// and serialize to JSON
var encoded = JSON.stringify("\0" + window.btoa(raw_out));
console.log(encoded); // "\u0000AAECAwQFBgcICQoLDA0ODw=="

// unserialize from JSON
var decoded = JSON.parse(encoded);

var data_out;
if (decoded.charCodeAt(0) === 0) {
// strip first character and decode base64 to raw string
var raw = window.atob(decoded.substring(1));

// convert raw string to byte array
var data_out = new Uint8Array(new ArrayBuffer(raw.length));
for (var i = 0; i < raw.length; ++i) {
data_out[i] = raw.charCodeAt(i);
}
} else {
data_out = decoded;
}

console.log(data_out);

<CODE ENDS>

16. Security Considerations

-- write me --






Oberstein & Goedde Expires April 13, 2016 [Page 136]

Internet-Draft ITMP October 2015


17. IANA Considerations

TBD

18. Contributors

19. Acknowledgements

ITMP was developed in an open process from the beginning, and a lot
of people have contributed ideas and other feedback. Here we are
listing people who have opted in to being mentioned:

Konstantin Burkalev (@KSDaemon on GitHub)

20. References

20.1. Normative References

[RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO
10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November
2003, <http://www.rfc-editor.org/info/rfc3629>.

[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
Resource Identifier (URI): Generic Syntax", STD 66, RFC
3986, DOI 10.17487/RFC3986, January 2005,
<http://www.rfc-editor.org/info/rfc3986>.

[RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data
Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006,
<http://www.rfc-editor.org/info/rfc4648>.

[RFC6455] Fette, I. and A. Melnikov, "The WebSocket Protocol", RFC
6455, DOI 10.17487/RFC6455, December 2011,
<http://www.rfc-editor.org/info/rfc6455>.

20.2. Informative References

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/
RFC2119, March 1997,
<http://www.rfc-editor.org/info/rfc2119>.

20.3. URIs

[1] http://www.iana.org/assignments/websocket/websocket.xml

[2] pattern-based-registration.md




Oberstein & Goedde Expires April 13, 2016 [Page 137]

Internet-Draft ITMP October 2015


[3] pattern-based-registration.md

[4] pattern-based-registration.md

[5] http://en.wikipedia.org/wiki/PBKDF2

[6] http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1

[7] http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2

[8] http://en.wikipedia.org/wiki/Record_separator#Field_separators

[9] https://github.com/oberstet/permessage-priority/blob/master/
draft-oberstein-hybi-permessage-priority.txt

Authors' Addresses

Tobias G. Oberstein
Tavendo GmbH

Email: Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.


Alexander Goedde
Tavendo GmbH

Email: Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.
























Oberstein & Goedde Expires April 13, 2016 [Page 138]

6LoWPAN

From Wikipedia, the free encyclopedia

6LoWPAN is an acronym of IPv6 over Low power Wireless Personal Area Networks.[1] 6LoWPAN is the name of a concluded working group in the Internet area of the IETF.[2]

The 6LoWPAN concept originated from the idea that "the Internet Protocol could and should be applied even to the smallest devices,"[3] and that low-power devices with limited processing capabilities should be able to participate in the Internet of Things.[4]

The 6LoWPAN group has defined encapsulation and header compression mechanisms that allow IPv6 packets to be sent and received over IEEE 802.15.4 based networks. IPv4 and IPv6 are the work horses for data delivery for local-area networks, metropolitan area networks, and wide-area networks such as the Internet. Likewise, IEEE 802.15.4 devices provide sensing communication-ability in the wireless domain. The inherent natures of the two networks though, are different.

The base specification developed by the 6LoWPAN IETF group is RFC 4944 (updated by RFC 6282 with header compression, and by RFC 6775 with neighbor discovery optimizations). The problem statement document is RFC 4919.

Contents

Application areas

The target for IP networking for low-power radio communication are applications that need wireless internet connectivity at lower data rates for devices with very limited form factor. An example is automation and entertainment applications in home, office and factory environments. The header compression mechanisms standardized in RFC6282 can be used to provide header compression of IPv6 packets over such networks.

IPv6 is also in use on the smart grid enabling smart meters and other devices to build a micro mesh network before sending the data back to the billing system using the IPv6 backbone. Some of these networks run over IEEE 802.15.4 radios, and therefore use the header compression and fragmentation as specified by RFC6282.

Thread

Thread is an effort of over 50 companies to standardize on a closed-documentation[5], royalty-free protocol running over 6LoWPAN to enable home automation. It is to be launched in the second half of 2015.[6] The protocol will most directly compete with Z-Wave and Zigbee IP.[7]

Functions

As with all link-layer mappings of IP, RFC4944 provides a number of functions. Beyond the usual differences between L2 and L3 networks, mapping from the IPv6 network to the IEEE 802.15.4 network poses additional design challenges (see RFC 4919 for an overview).

Adapting the packet sizes of the two networks
IPv6 requires the maximum transmission unit (MTU) to be at least 1280 Bytes. In contrast, IEEE 802.15.4's standard packet size is 127 octets. A maximum frame overhead of 25 octets spares 102 octets at the media access control layer. An optional but highly recommended security feature at the link layer poses an additional overhead. For example, 21 octets are consumed for AES-CCM-128 leaving only 81 octets for upper layers.
Address resolution
IPv6 nodes are assigned 128 bit IP addresses in a hierarchical manner, through an arbitrary length network prefix. IEEE 802.15.4 devices may use either of IEEE 64 bit extended addresses or, after an association event, 16 bit addresses that are unique within a PAN. There is also a PAN-ID for a group of physically collo-cated IEEE 802.15.4 devices.
Differing device designs
IEEE 802.15.4 devices are intentionally constrained in form factor to reduce costs (allowing for large-scale network of many devices), reduce power consumption (allowing battery powered devices) and allow flexibility of installation (e.g. small devices for body-worn networks). On the other hand, wired nodes in the IP domain are not constrained in this way; they can be larger and make use of mains power supplies.
Differing focus on parameter optimization
IPv6 nodes are geared towards attaining high speeds. Algorithms and protocols implemented at the higher layers such as TCP kernel of the TCP/IP are optimized to handle typical network problems such as congestion. In IEEE 802.15.4-compliant devices, energy conservation and code-size optimization remain at the top of the agenda.
Adaptation layer for interoperability and packet formats
An adaptation mechanism to allow interoperability between IPv6 domain and the IEEE 802.15.4 can best be viewed as a layer problem. Identifying the functionality of this layer and defining newer packet formats, if needed, is an enticing research area. RFC 4944 proposes an adaptation layer to allow the transmission of IPv6 datagrams over IEEE 802.15.4 networks.
Addressing management mechanisms
The management of addresses for devices that communicate across the two dissimilar domains of IPv6 and IEEE 802.15.4 is cumbersome, if not exhaustingly complex.
Routing considerations and protocols for mesh topologies in 6LoWPAN
Routing per se is a two phased problem that is being considered for low-power IP networking:
  • Mesh routing in the personal area network (PAN) space.
  • The routability of packets between the IPv6 domain and the PAN domain.

Several routing protocol have been proposed by the 6LoWPAN community such as LOAD,[8] DYMO-LOW,[9] HI-LOW.[10] However, only two routing protocols are currently legitimate for large-scale deployments: LOADng [11] standardized by the ITU [4] under the recommendation ITU-T G.9903 and RPL [12] standardized by the IETF ROLL working group.[13]

Device and service discovery
Since IP-enabled devices may require the formation of ad hoc networks, the current state of neighboring devices and the services hosted by such devices will need to be known. IPv6 neighbour discovery extensions is an internet draft proposed as a contribution in this area.
Security
IEEE 802.15.4 nodes can operate in either secure mode or non-secure mode. Two security modes are defined in the specification in order to achieve different security objectives: Access Control List (ACL) and Secure mode[14]

Further reading

See also

  • DASH7 active RFID standard
  • MyriaNed low power, biology inspired, wireless technology
  • Z-Wave designed to provide, reliable, low-latency transmission of small data packets at data rates up to 100kbit/s
  • ZigBee standards-based protocol based on IEEE 802.15.4.
  • LoRaWAN allows low bit rate communication from and to connected objects, thus participating to Internet of Things, machine-to-machine M2M, and smart city.
  • Thread (network protocol) standard suggested by Nest Labs based on IEEE 802.15.4 and 6LoWPAN.

References

External links

JSN Mini template designed by JoomlaShine.com