Source: http://hydranode.com/docs/ed2ked2kproto.htmledonkey2000 Protocol
AbstractThis Document Describes the Edonkey2000 (
ED2K) P2P Protocol and emule Extended Protocol (EMEP).
Table of contents
INTRODUCTION
Definitions
2. HEADER Specification
3. Client-Server Communication
3.1 Logging Into a Server 3.2 Updating Server List and Information (Optional) 3.2 Publishing Shared Files 3.3 Performing A Search
4. Client <-> Client Communication
4.1 Get-to-Know-You Chit-Chat 4.2 Reqesting A File 4.3 Uploading File Data
5 Lowid Clients
5.1 Connecting to Lowid Clients
6 Source Exchange
7 Miscellaneous TCP Packets
8 EMULE Extended Protocol: UDP REASKS
INTRODUCTION
ED2K protocol is used for communication between compatible clients to form a server-based peer-to-peer file-sharing network. EMEP is only used between eMule (and compatible) clients, but not by official eDonkey2000 clients.
Few Words on The Packet Format Strings Used Here:
U8 unsigned 8-bit integer
U16 unsigned 16-bit integer
U32 unsigned 32-bit integer
Hash 16-Bytes MD4 Checksum
String 16-Bit Integer (Specifying String Length) Followed by the String
Taglist 32-bit integer (Specifying Number of tags) Followed by the tags
Definitions
Part IS A Region of A File of (Up) 9500kb in Length, for Which There Is A Corresponding MD4 Parthash. Chunk is a region of a file of (up to) 180KB in Length, Which Can Be Requested from A Remote Client. Block is a region of a chunk Which is Sent AS Single Packet Database. Chunks Are Split Into Block Packets for Transmitting.
See Also:
Edonkey2000 Tag System overview
2. HEADER Specification
------ -------- -------- -------- ------ ---- ---- -------- ------ ---- | Protocol | Packet Length | Packet Data (Length Bytes)
------ -------- -------- -------- ------ ---- ---- -------- ------ ----
Each Edonkey2000 Packet Begins with protocol opcode, FOLLOWED by 32-bit unsigned integer, three protocol opcodes are in users:
PR_ED2K = 0xE3, //! PR_EMULE = 0xc5, //! Pr_zlib = 0xd4 //! Packed Data Always Begins with 8-bit Opcode, Which Idicates The Packet Content .hen SENDING PACKETS Using Pr_zlib Protocol, The Packet Data (Excluding The Opcode) is compressed. 3. Client-Server Communication 3.1 Logging Into a Serverin Order to Connect To An Edonkey2000 Server, Client Sends op_loginRequest to Server. Op_loginRequest = 0x01, //! < The Packet May Contain The Following Tags: CT_NICK = 0x01, //! CT_VERSION = 0x11, //! CT_Port = 0x0f, //! < CT_Muleversion = 0xfb, //! CT_FLAGS = 0x20, //! < Flags Is A Bitfield Containing The Following Information: Fl_zlib = 0x01, //! FL_IPINLOGIN = 0x02, //! FL_AUXPORT = 0x04, //! ?? FL_Newtags = 0x08, //! FL_UNICODE = 0x10 //! See Also: 5 Lowid Clients The Following Packets Are Sent by The Server To Inform The Client That The Connection Has Been Established, As Well As To Provide Up2date Information About The Server: OP_SERVERMESSAGE = 0x38, //! < OP_SERVERSTATUS = 0x34, //! Op_idchange = 0x40 //! Note: Lugdunum 16.44 Servers Send Additional U32 In ID_Change Packet Containing Bitfield of Supported Features. Those Include: Fl_zlib = 0x01, //! FL_Newtags = 0x08, //! FL_UNICODE = 0x10 //! 3.2 Updating Server List and Information (optional) After Establishing Connection With The Server, The Clom The Server, AS Well as Known Servers List. Op_getserverlist = 0x14, //! <(No payload) The Server Answers with The Following Packets: OP_SERVERLIST = 0x32, //! Op_serverident = 0x41, //! < The Latter Contains The Following Tags: CT_SERVERNAME = 0x01, //! < CT_SERVERDESC = 0x0b //! < //! Op_offerfiles = 0x15, The Packet May Contain The Following Tags: CT_FileName = 0x01, //! < CT_FILESIZE = 0x02, //! < CT_FileType = 0x03, //! Note: File Type is Sent In Ed2k Network As String. The Following Strings Are Recognized: #define ft_ed2k_audio "Audio" //! #define ft_ed2k_video "Video" //! #define ft_ed2k_image "image" //! #define ft_ed2k_document "DOC" //! #define ft_ed2k_program "pro" //! This Packet Should Be Sent on The Following Occasions: With full shared files list when connecting to server With single file whenever new shared file is added As empty packet, as server keep-alive packet at regular intervals Additionally, it is possible to indicate whether the file being shared is partial or complete using two special IP / Port VALUES: FL_complete_id = 0xfcfcfcfc, //! FL_complete_port = 0xfcfc, //! FL_PARTIAL_ID = 0xfbfbfbfb, //! FL_PARTIAL_PORT = 0xfbfb //! ONLY Uses Zlib-Support to Detect WHether The Server Supports these ID's TOO. 3.3 Performing a searchsearch in edonkey2000 network is server-based. Client sends SEARCHR packet to server, which in turn returns one (or more) SEARCHRESULT packets. This is done over TCP, and with currently connected server only. However, optionally, the client may also send the same search request packet over UDP sockets to All Known Servers Using Globsearch Opcode, Which in Turn Reply (over UDP) with globsearchres packets. Ed2kpacket :: SEARCH IMPLEMENTATION for More Information Packets.cpp) Op_search = 0x16, //! //! Op_searchresult = 0x33, SearchResult May Contain The Following Tags: CT_FileName = 0x01, //! < CT_FILESIZE = 0x02, //! < CT_FileType = 0x03, //! CT_Sources = 0x15, //! CT_COMPLSRC = 0x30, //! 4. Client <-> Client Communication 4.1 Get-to-Know-You Chit-Chatin Order To Initialize A Connection To a Remote Client, First The Client Sends Hello Packet. Op_hello = 0x01, //! < Hello Packet May Contain The Following Tags: CT_NICK = 0x01, //! CT_PORT = 0x0f, //! CT_MODSTR = 0x55, //! CT_UDPPORTS = 0xf9, //! < CT_MISCFEATURES = 0xfa, //! < The correct answer to OP_HELLO is OP_HELLOANSWER. The HelloAnswer packet format is identical to OP_HELLO, except that HelloAnswer also includes 8-bit hash length before hash. The value of the field must be 0x0f. CT_Muleversion Contains a 32-bit value with the folowing bits (and meanings) 1 2 3 4 5 [Bytes] 1111111122222223333334444555555 [bits] 00000000000000101010101100000000 EMULE 42G VERSION INFO | | | | | - Build Version (unused by emule) | | | --------- Update Version 6 (a = 0, g = 6) | | -------------- MINOR VERSION 42 | --------------------- Major Version (unused by emule) ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- IF Both of The Clients Are Emule-Compatible, They Also Exchange MuleInfo Packets. Op_muleinfo = 0x01, //! OP_MULEINFOANSWER = 0x02 //! < Note: Both of these Packets Are Sent Using PR_EMULE. Tags contained in muleinfo packets: CT_compression = 0x20, //! CT_UDPPORT = 0x21, //! CT_UDPVER = 0x22, //! CT_SourceExch = 0x23, //! CT_Comments = 0x24, //! CT_compatclient = 0x26, //! CT_FEATURES = 0x27, //! CT_MODVERSION = 0x55, //! CT_MODPLUS = 0x99, //! CT_L2HAC = 0x3e, //! Feature Set Bitfield IS 32-Bit Value with Following Bits and Meanings: 12345678123456781234567812345678 0000100000100110011001000011110 EMULE 43B 00110100000100110011001000011110 EMULE 44B 11123333444455556666777788889ABC | | | | | | | | ||| - Preview | | | | | | | | || --- MultiPacket | | | | | | | | | | -- No `View Shared Files' Supported | | | | | | | | ----- Peerca | | | | | | | -------- Comments | | | | | | --------- Extended Requests | | | | | ---------------- Source Exchange | | | | | -------------------- Secure Ident | | | ---------------------- Data Compression Version | | -------------------------- UDP VERSION | ------------------------------ Unicode ------------------------------ Aich Version (0 - not supported) 4.2 Reqesting a FileAfter Completing The Handshaking Described in Section 4.1, The Client May Now Request A File. This is done using reqfile packet. Op_reqfile = 0x58, //! < Note: EMULE EXTREQV1 Adds EMULE EXTREQV2 Adds ReqFile is replied by op_filename and op_fileDescop_filename = 0x59, //! < OP_FILEDESC = 0x61, //! After Receiving The Above Packets, The Download CLIENT Sends SetReqfileid to Bind The Reqested File to the Hash. This Requested Hash, UnTil IT Receives It. FileDesc packet is sent using PR_EMULE, and does NOT contain the file hash the description belongs to, however, since it is always sent along with OP_FILENAME, in response to OP_REQFILE packet, client can thus assume the FileDesc packet belongs to the most recently requested file . Note: . Op_setReqFileID = 0x4f, //! < The Expected Response to this packet is op_filestatus OP_REQFILE_STATUS = 0x50, //! < If at any point during the above packets the uploading client realizes it does not share the file requested, it may send OP_REQFILE_NOFILE. File status packet contains a part map of the available parts. This is defined as a bitfield, one bit per each ED2K part (defined by ED2K_PARTSIZE) Extra bits needed to fill up the byte are padded with zeros The count prior to the bitset indicates the number of total parts, and thus also the number of total bits in the bitset (note:.. NOT the Number of Bytes Following!). Also Note That Sending Partmap IS Completely Optional, and Should Only Be tention. The partmap shall be omitted. OP_REQFILE_NOFILE = 0x48, //! Op_reqhashset = 0x51, //! < Op_hashset = 0x52, //! < After that, the requesting client sends OP_STARTUPLOADREQ, which must be replied either by OP_ACCEPTUPLOADREQ (if we can start uploading right away), or OP_QUEUERANKING, in case the client has been inserted into our upload queue. Op_startuploadReq = 0x54, //! OP_ACCEPTUPLOADREQ = 0x55, //! Op_queuereamanking = 0x5c, //! < ................. .. OP_MuleQueueRank = 0x60 //! < This packet contains 16-bit value as queue rank, and 10 empty bytes, such as the full packet size must be 12 bytes. This size requirement is enforced by eMule packet parser, and the sender will be disconnected if those extra bytes are not sent . Why are there those 10 extra empty bytes, and why is it enforced so strongly remains unclear. This packet is also sent using PR_EMULE protocol opcode. Note that if you'r thinking to skip over this packet and not use it, you'r So Out of Luck, Since Emule Considers Clients WHO Send Op_QueueRanking Simply The Packet. So if You Want Emule Compatibility, You NEED To Use this Half-Empty Packet. 4.3 Uploading file dataAfter receiving OP_ACCEPTUPLOADREQ, the remote client will proceed to request chunks from us In eDonkey2000 network, a chunk size is 180k (notice the difference from partsize) The chunks are requested using OP_REQCHUNKS packet:.. OP_REQCHUNKS = 0x47, //! The Packet Contains Three Begin Offsets and Three End Offsets of the Requested Chunks. Ed2k Data Ranges Logic Defines That The end offset is exclusive, thus range (0, 0) IS considered AS INVALIDRANGE. IF The Client Wishes Less Than Three Chunks, It May Set The Remaining Ranges To (0) TO INDICATE THAT. Note: This Is Slightly Different from Hydranode Range API, WHERE End Offset is considered inclusive. After receiving OP_REQCHUNKS, the uploading clients starts sending data. The requested chunks are split into (up to) 10kb blocks, each transmitted as a separate packet, using OP_SENDINGCHUNK opcode. Optionally, clients supporting eMule extended protocol may use OP_PACKEDCHUNK packet (which is sent . using PR_EMULE) in compressed packet, the data part of the packet is compressed using zlib (but not the packet header - this is different from OfferFiles packet, where everything after the opcode is compressed) Also, in case of a compressed packet,. . the end offset bytes in the packet header indicate the length of the compressed data, not the end offset of the uncompressed data Note that compression is not required - if data compression results in larger amount of data, data should be sent uncompressed instead, using Op_sendingchunk packet. Op_sendingchunk = 0x46, //! < OP_PACKEDCHUNK = 0x40, //! < Op_canceltransfer = 0x56 //! In Case of Compressed Data Transfer, The Entire Requested Chunk is first compressed, and then transmitted in 10kb chunks over time. 5 LowID ClientsLowID client is defined in ed2k network as a client who can not receive external connection. The client can only make external connections itself. The only way to connect to a client is through a server callback, since the client is connected to a server. It is only possible to contact LowID clients that are on same server as the connecter is. LowID client's are identifier in the network using client ID less than 0x00ffffff. This is also the reason why everywhere where there should be client IP we say it is ID For clients with id> 0x00ffffff, the ID indeicates the ip of the remote client (in network byte order), for lower id's, it has indeicates the client callback ID, as assigned by the server. 5.1 Connecting to Lowid Clientsconnecting to Lowid Client Is Done by sending op_reqcallback to currently connected server, incruding theid of the remote client we wish to connect. OP_REQCALLBACK = 0x1c, //! < If The Client with The Specified ID IS Connected To The Server, The Server Sends Op_cbrequested Packet To The Client, After Which The Client Will Attempt To Contact The Requester. OP_cbrequested = 0x35, //! IF The Client In Questions IS Not Connected To this Server, The Server Will Respond with op_callbackfail. Op_callbackfail = 0x36 //! Source Exchange Allows Clients to Share Their Known Sources for Files. Op_reqsources = 0x81, //! < Op_answersources = 0x82 Note: SRCEXCHV2 Adds 16-byte User-Hash To Each Source. Srcexchv3 Sends ID's in the "Hybrid" format so hardid clients with *. *. *. 0 Won't be falsely given lowid. References: EMULE / SRCHYBRID / PARTFILE.CPP: 3529: cpartfile :: createSrcinfopacket () emule / srchybrid / partfile.cpp: 3608: cpartfile :: addclientSource () 7 Miscellaneous TCP Packets Op_message = 0x4e, //! Message Packets Can Be Used to Perform Simple Chatting Between Clients. Op_porttest = 0xfe //! NOT Actually Part of Ed2k Protocol, Op_PortTest Can Be Used (by a Website, for Example) To Verify Correct FireWall Configuration. Note That Op_Porttest May Be Sent Both Via TCP AND UDP. 8 eMule extended protocol: UDP reasksAs an eMule extended feature, UDP packets are used to "ping" sources every now and then to verify queue status, reask queue rankings and so on In current implementation, eMule (and compatible) clients seem to drop. Clients from their queues if The Haven't Pinged At Least ONCE PER HOUR. The Following Packets Are Currently in Use: Op_reaskfileping = 0x90, //! < By Default, this packet Only Contains Filehash The Source Was INTERESTED IN. Note: UDPV3 Adds 2-bytes Complete-Source-Count. UDPV4 AVAILABILITY PartMap, AS in ReqFile Packet. WHEN UDPV4 IS USED, The Partmap is Placed Before The Complete Source Count. Op_reaskack = 0x91, //! Note: UDPv4 Adds Availability Partmap, AS in Reqfile Packet SIMILARLY TO OP_REASKFILEPING PACKET, WHEN UDPV4 IS Used, The Partmap Is Placed Before The Queue Ranking In The Packet. Op_filenotfound = 0x92, //! Sent As Response To op_reaskfileping, INDICATES That The Remote Client Is Not Sharing The Requested File (ANYMORE AT Least). Op_queuefull = 0x93, //! Sent As Response To op_reaskfileping, INDICATES That The Remote Queue Is Full.