Skip to content

EC protocol

Simone Di Mambro edited this page Sep 8, 2026 · 1 revision

EC protocol (technical details)

aMule Remote implements aMule's EC (External Connections) protocol from scratch, version 0x0204, compatible with aMule 2.3.x. Below are the main details of the implementation (useful if you want to contribute).

Wire framing

Every packet is preceded by an 8-byte header (all numbers big-endian):

u32 flags
u32 payload_length

The payload contains: u8 opcode, u16 tag_count, followed by the tags.

Base flags are 0x20. They may include EC_FLAG_ZLIB (zlib-compressed payload) and EC_FLAG_UTF8_NUMBERS. The app always sends uncompressed (no zlib / utf8-numbers) and can decompress the server's zlib responses.

Tag format

Each tag on the wire (normal mode):

u16  (name << 1) | has_children
u8   type
u32  tag_length
[ u16 child_count + children... ]   (if has_children)
value bytes

tag_length = length of the value + serialized size of all children (7-byte header per child, +2 bytes if that child has children itself, recursively).

Supported types: uint8/16/32/64, string (NUL-terminated — the terminator must be kept, amuled reads them as C strings), double (ASCII), ipv4, hash16, custom.

Authentication (handshake)

  1. The client sends EC_OP_AUTH_REQ with client name, version and EC_TAG_PROTOCOL_VERSION.

  2. The server answers with EC_OP_AUTH_SALT containing a salt.

  3. The client computes:

    passHex   = md5_hex(password)
    saltHex   = md5_hex( sprintf("%llX", salt) )      // uppercase hex salt
    finalHash = MD5( passHex.lowercased() + saltHex )
    
  4. The client sends EC_OP_AUTH_PASSWD with EC_TAG_PASSWD_HASH = finalHash.

  5. The server answers EC_OP_AUTH_OK (or EC_OP_AUTH_FAIL).

Request serialization

Operations use the opcodes and tags documented in ECCodes.abstract / ECTagTypes.abstract of the aMule project. Examples implemented:

Operation OpCode
Statistics EC_OP_STAT_REQ
Connection state EC_OP_GET_CONNSTATE
Download queue EC_OP_GET_DLOAD_QUEUE
Pause/resume/priority/delete EC_OP_PARTFILE_*
Search EC_OP_SEARCH_START/STOP/PROGRESS/RESULTS
Download a result EC_OP_DOWNLOAD_SEARCH_RESULT
Server list / management EC_OP_GET_SERVER_LIST, EC_OP_SERVER_*
Preferences EC_OP_GET/SET_PREFERENCES

Before starting a new search the app sends EC_OP_SEARCH_STOP: a stale search left on the daemon would otherwise make the new one silently fail to start.

A note on concurrency

The EC protocol has no request IDs: responses are matched to requests only by order. The client therefore serializes requests through a FIFO queue: only one request/response pair is on the wire at any time, otherwise reads from the socket would get mixed up. Every request consumes its response — even EC_OP_SET_PREFERENCES answers (with a NOOP) — so there is no fire-and-forget.

Verification

The implementation was verified end-to-end against a real amuled 2.3.x (in Docker): authentication, statistics, server management, eD2k links, download queue, pause/priority/delete, search, reading and writing preferences, log, and wrong-password rejection.

Clone this wiki locally