3 - follow the white rabbit -
14 EC is under heavy construction, however the protocol itself is considered
15 stable and you can rely on. The opcodes and tagnames, tag content formats
16 and values are still changing, so if you decide to implement an application
17 using aMule EC, you'd better include our ECcodes.h for the values, and
18 check the documentations often, or even the code itself (ExternalConn.cpp
23 Section 1: Protocol definition
24 ------------------------------
28 EC protocol consist of two layers: a low-level transmission layer, and
29 a high level application layer.
32 Section 1.1: Transmission layer
33 -------------------------------
35 The transmission layer is completely independent of the application layer,
36 and holds only transport-related information.
38 The transmission layer actually consists of an uint32 number, referenced
39 below as flags, which describes flags for the current transmission session
40 (send/receive operation).
42 This four-byte value is the only one in the whole protocol, that is
43 transmitted LSB first, and zero bytes omitted (therefore an empty
44 transmission flags value is sent as 0x20, not 0x20 0x0 0x0 0x0).
48 bit 0: Compression flag. When set, zlib compression is applied to
49 the application layer's data.
51 bit 1: Compressed numbers. When set (presumably on small packets
52 that doesn't worth compressing by zlib), all the numbers used
53 in the protocol are encoded as a wide char converted to utf-8
54 to let some zero bytes not to be sent over the network.
56 bit 2: Has ID. When this flag is set, an uint32 number follows the
57 flags, which is the ID of this packet. The response to this
58 packet also has to have this ID. The only requirement for the
59 ID value is that they should be unique in one session (or at
60 least do not repeat for a reasonably long time.)
62 bit 3: Reserved for later use.
64 bit 4: Accepts value present. A client sets this flag and sends
65 another uint32 value (encoded as above, LSB first, zero
66 bytes omitted), which is a fully constructed flags value,
67 bits set meaning that the client can accept those extensions.
68 No extensions can be used, until the other side sends an
69 accept value for them. It is not defined when this value
70 should be send, best is on first transfer, but can be sent
71 any time later, even changing the previously announced
74 bit 5: Always set to 1, to distinguish from older (pre-rc8) clients.
76 bit 6: Always set to 0, to distinguish from older (pre-rc8) clients.
78 bits 7,15,23: Extension flag, means that the next byte of the flags is
81 bits 8-14,16-22,24-32: Reserved for later use.
84 Transmission layer example:
85 0x30 0x23 <appdata> - Client uses no extensions on this packet,
86 and indicates that it can accept zlib compression and
90 Note 1: On the "accepts" value, the predefined flags must be set to
91 their predefined values, because this can be used as a sort
94 Note 2: Bits marked as "reserved" should always be set to 0.
98 Section 1.2: Application layer
99 ------------------------------
101 Data transmission is done in packets. A packet can be considered as a
102 special tag - with no data, no tagLen field, and with the tagCount
103 field always present. All numbers part of the application layer are
104 transmitted in network byte order, i.e. MSB first.
105 A packet contains the following:
110 In detail: The opcode means what to to or what the data fields contain.
111 Its type is set as ec_opcode_t, which currently is an uint8.
112 TagCount is the number of first level tags this packet has. Then are the
116 [ec_tagname_t] TAGNAME
117 [ec_tagtype_t] TAGTYPE
123 The ec_tagname_t is defined as an uint16, ec_taglen_t as an uint32 value
124 at the moment. ec_tagtype_t is an uint8.
125 TagName tells what it contains (see ECcodes.h for details).
126 TagType sends the type of this tag (see ECPacket.h for types)
127 TagLen contains the whole length of the tag, including the lengths of the
128 possible sub-tags, but without the size of the tagName, tagType and
129 tagLen fields. Actually the lowest bit of the tagname doesn't belong to the
130 tagName itself, so it has to be cleared before checking the name.
132 Tags may contain sub-tags to store the information, and a tagCount field
133 is present only for these tags. The presence of the tagCount field can
134 be tested by checking the lowest bit of the tagName field, when it is
135 set, tagCount field present.
137 When a tag contains sub-tags, the sub-tags are sent before the tag's own
138 data. So, tag data length can be calculated by substracting all sub-tags'
139 length from the tagLen value, and the remainder is the data length, if
143 Section 2: Data Types
144 ---------------------
149 Integer types (such as uint8, uint16, uint32) are always transmitted in
150 network byte order (MSB first).
156 Strings are always UTF-8 strings, with the trailing zero byte included.
157 All strings coming from the server are untranslated, but their translations
158 are included in amule's translation database (amule.mo).
164 This one is tricky. When reading, the tag's presence means true, and
165 false when omitted. When writing, they should always be present -
166 if not, it's considered 'unchanged' - and should hold an uint8 value.
167 This value determines the boolean value in the standard way, i.e.
168 zero means false and non-zero means true.
170 Boolean values are mostly used in reading/writing preferences.
176 They are always MSB first.
179 Floating point numbers
180 ----------------------
182 Floating point numbers such as 'float' or 'double' types are converted
183 to their string representation, and are sent as string. Note, that the
184 decimal point is always the '.' (dot) character, independent from the
188 Section 3: Clarifying things
189 ----------------------------
191 If all the above seemed too much technical, just keep on reading. If you
192 understood the above at first, you can safely skip this section.
194 Have you ever seen an xml file? Do you know how it looks like? Then you
195 can safely think of an EC packet as binary xml. Otherwise (hmm, you
196 don't know what xml is?) think of it as a tree, it has exactly one root,
197 may have many branches and leaves. We'll use the tree example below.
199 But before we get to the examples, just some words about the flags (which
200 are part of the transmission layer, you remember?): When developing your
201 EC application (frontend to aMule, etc), this might be the last thing you
202 want to care about, and it's ok. Just keep sending a byte of 0x20 as flags,
203 and aMule will never want to use any of the features described in
204 Section 1.1. You just have to take of the "accepts" value aMule will send
207 An now, to the examples. The example packets are real-life EC packets,
208 transscripted to textual form for your pleasure :)
210 First, let's see a simple but very important packet: authentication to
211 aMule. This must be the very first one, otherwise aMule might drop the
214 EC_OP_AUTH_REQ (0x02)
215 +----EC_TAG_CLIENT_NAME (0x06) (optional)
216 +----EC_TAG_PASSWD_HASH (0x04)
217 +----EC_TAG_PROTOCOL_VERSION (0x0c)
218 +----EC_TAG_CLIENT_VERSION (0x08) (optional)
219 +----EC_TAG_VERSION_ID (0x0e) (required for cvs versions, must not be present for release versions)
221 Now, what exactly gets transmitted? Here it comes, with comments (all
222 numbers are hexadecimal, I omitted the 0x prefix for redability):
224 20 FLAGS, just stating that we use ECv2
226 00 05 Number of children (tags) this packet has
227 00 06 EC_TAG_CLIENT_NAME
229 00 00 00 09 Length of this tag (9)
230 61 4d 75 6c 65 63 6d 64 00 Contents of the tag: "aMulecmd", with trailing zero included (see String types in Section 2)
231 00 08 EC_TAG_CLIENT_VERSION
233 00 00 00 04 Length of this tag (4)
234 43 56 53 00 Content: "CVS"
235 00 0c EC_TAG_PROTOCOL_VERSION
237 00 00 00 02/4/8 Length: 2/4/8 (16/32/64 value follows)
238 00? 00? 01 f2 Content: 0x0200 (current protocol version number for cvs)
239 00 04 EC_TAG_PASSWD_HASH
241 00 00 00 10 Length (16)
242 5d 41 40 2a bc 4b 2a 76 Content: 16 bytes md5sum of EC password
243 b9 71 9d 91 10 17 c5 92
244 00 0e EC_TAG_VERSION_ID
246 00 00 00 21 Length: 33
247 62 66 39 64 64 32 36 35 Content 33 bytes of the unique EC CVS version ID
248 32 36 34 35 31 36 63 39 Remember: this is only for CVS versions, and its
249 34 35 38 36 38 66 61 39 size, content-type, anything might change without
250 30 38 66 62 37 64 39 38 notice. For release versions this tag MUST NOT be
253 Now, that we constructed a packet, stating that we are "aMulecmd CVS", send
254 it to the server and see what it replies. Hopefully the following:
256 30 FLAGS, stating that the server sends us an 'accepts' flags
257 23 the 'accepts' flag. Just take care that your program can
258 handle when it is present, and we can forget about it for now.
260 00 01 Number of children (tags) in this packet
261 00 76 EC_TAG_SERVER_VERSION
263 00 00 00 04 Length of this tag (4)
264 43 56 53 00 And the contents: "CVS"
266 That was easy. Heading for a more complex example: now that we're connected
267 to aMule, ask simple stats from core.
272 +----EC_TAG_DETAIL_LEVEL (with EC_DETAIL_CMD value)
277 00 10 EC_TAG_DETAIL_LEVEL
279 00 00 00 01 Length: 1
282 The reply (assuming core is connected to a server):
285 +----EC_TAG_STATS_UL_SPEED
286 +----EC_TAG_STATS_DL_SPEED
287 +----EC_TAG_STATS_UL_SPEED_LIMIT
288 +----EC_TAG_STATS_DL_SPEED_LIMIT
289 +----EC_TAG_STATS_CURR_UL_COUNT
290 +----EC_TAG_STATS_TOTAL_SRC_COUNT
291 +----EC_TAG_STATS_CURR_DL_COUNT
292 +----EC_TAG_STATS_TOTAL_DL_COUNT
293 +----EC_TAG_STATS_UL_QUEUE_LEN
294 +----EC_TAG_STATS_BANNED_COUNT
295 +----EC_TAG_CONNSTATE
297 +----EC_TAG_SERVER_NAME
299 I won't copy here the whole reply packet, only the interesting part:
303 00 0b Number of (first-level) tags in this packet: 11 (direct children of the packet root)
304 00 14 [...] EC_TAG_STATS_UL_SPEED
305 00 16 [...] EC_TAG_STATS_DL_SPEED
306 00 18 [...] EC_TAG_STATS_UL_SPEED_LIMIT
307 00 1a [...] EC_TAG_STATS_DL_SPEED_LIMIT
308 00 1c [...] EC_TAG_STATS_CURR_UL_COUNT
309 00 22 [...] EC_TAG_STATS_TOTAL_SRC_COUNT
310 00 1e [...] EC_TAG_STATS_CURR_DL_COUNT
311 00 20 [...] EC_TAG_STATS_TOTAL_DL_COUNT
312 00 26 [...] EC_TAG_STATS_UL_QUEUE_LEN
313 00 24 [...] EC_TAG_STATS_BANNED_COUNT
314 And now the interesing part:
315 00 13 EC_TAG_CONNSTATE. Note, that all tagnames are even numbers, so when
316 we find an odd number, the true tag name is <found>-1. EC_TAG_CONNSTATE = 0x0012,
317 and 0x0013 - 1 = 0x0012, so it is really this one. The tagname being an odd number
318 means that this tag has child(ren) tags (see tree above), and also that it has a
321 00 00 00 26 TagLen: 38 (own content length + length of children (with headers))
322 00 01 TagCount: 1 (one child tag exists, that is a direct child of this tag)
323 00 61 EC_TAG_SERVER (has children)
325 00 00 00 1a TagLen: 27 (own content (6) + length of child (content: 14 + header: 7))
327 00 62 EC_TAG_SERVER_NAME
329 00 00 00 0e TagLen: 14
330 52 61 7a 6f 72 62 61 63 Content of the EC_TAG_SERVER_NAME tag: "Razorback 2.0"
332 c3 f5 f4 f3 12 35 Content of the EC_TAG_SERVER tag: Server IP:Port (195.245.244.243:4661)
333 90 cc 83 52 Content of the EC_TAG_CONNSTATE tag: Current UserID
335 Hopefully these examples helped enlightening the nature of OpCodes, Tags,