1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
sbus is simple message bus based on unix domain, sequenced-packet sockets.
Features:
Support for multi-user buses.
No support state-keeping in clients.
Supports all send(2)/recv(2) flags.
Almost full setsockopt(2)/getsockopt(2)/fcntl(2)/ioctl(2) support:
No send-time timestamps
Increasing message size limit may cause problems
Support for routing keys with wildcards.
Support for secret communication.
Reliable and ordered communication.
Non-features:
No IP or cluster support, should be implemented as a separate service.
No support for overly larged messages, should be implemented at application level.
No persistence support, should be implemented as a separate service.
No support for automatic unsubscriptions.
No support for reply-to keys, should be implemented at application level.
No support for shared queues, should be implemented as a separate service.
No file descriptor passing support, not network-compatible, should be
implemented as a separate service or at application level.
No support for server-verified credentials, can be implemented at
application level by using '!.cred.' routing keys.
No acknowledgement of when messages have been processes, can be
implemented at application level by sending yourself a message
and wait for it to return.
Routing keys:
Routing keys are used to filter received messages. A routing key
may contain any byte, whoever there are three bytes with special
meaning: '*', '.', and '!'. '*' should not be used in routing keys,
but only in routing key patterns, it matches until the next '.' or
end if there are not more '.'s. Additionally if a routing key
pattern ends with '.' that '.' will match to a '.' and any
subsequent byte. For example 'a.*.c.' will match 'a.b.c.' and
'a.b.c.d.e' but not 'a.b.c' or 'a.c.d'. And empty routing key
pattern shall match everything. The token '!' is reserved, a client
should never use '!' for any other purpose than specified in the
protocol, unless it has an other byte than a '.' next to it. The
server may choose to disconnect a client using '!' in an invalid
way or simply ignore such messages.
Protocol:
Communication is done over unix domain, sequenced-packet sockets.
Each packet is interpreted as a complete message. A packet cannot
contain multiple message, and a message cannot be split over
multiple packets. There are 4 types of messages:
Subscribe:
Send a routing key pattern to the server for the client.
The server shall send all messages with matching routing
keys to this client. The server shall store the key even
if there is already an identical routing key pattern
registered for the client.
Messages of this type shall match the regular expression
^SUB \([^\x00]*\)\(\x00.*\)\?$
where \1 is the routing key pattern, \2 is ignored.
Unsubscribe:
Tell the server to remove a routing key pattern for the
client. The server may choose to disconnect the client
if it sends a routing key pattern that is not registered
for the client.
Messages of this type shall match the regular expression
^UNSUB \([^\x00]*\)\(\x00.*\)\?$
where \1 is the routing key pattern, \2 is ignored.
Publish:
Publish a message on the bus. The server shall send a
copy of packet to all clients with a matching routing
key pattern, including the client that sent the packet
if and only if that client has a matching routing key
pattern. The server may not send a copy of the packet
to any clients without a matching routing key pattern.
Messages of this type shall match the regular expression
^MSG \([^\x00]*\)\x00\(.*\)$
where \1 is the routing key for the message and \2
is the message payload.
Control message:
Send a control message to the server. The server may
also send control message to clients. The server will
never forward control message it receives, and no
subscriptions are required to receive the messages.
Messages of this type shall match the regular expression
^CMSG \([^\x00]*\)\(\x00\(.*\)\)$
where \1 is the routing key for the message and \3
is the message payload. \2 may be om be omitted if
sent by the client.
Secret messages:
Routing keys starting with '!.cred.' can only be subscribed to
by clients with matching credentials. These routing keys look
match this regular expression
^!\.cred\.\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\.\(.*\)$
where \1 is the group ID, \2 is the user ID, \3 is the process
ID, and \4 the rest of routing key which may also use this
pattern a process it communicates. Client can only subscribe
to the routing key \1, \2, and \3 match it's credentials.
If \1, \2, or \3 are empty, they will match the clients it's
credentials when subscribing. However, the server will not
accept '*' for \1, \2, or \3, or truncated routing key.s
However, due to network support, these routing keys may need
to be prefixed with the credentials for the servers the message
goes through. This prefix can be retrieved by simply sending an
empty control message (CMSG) with the routing key '!.cred.prefix'
and the server will reply with a control message containing prefix
using this routing key. Note, prefix is probably the empty string,
as the master server do not need to add its credentials to be
prefixed. Note, the server will never send control messages, so
received control message are guaranteed to come from the server.
Example of how two client can prove their identities to each oter:
A: Send A's credentials to B.
B: Send B's credentials with routing key private to A.
A: Send a random message with routing key private to B.
B: Send back the message with routing key private to A.
|