Engine/Network Protocol

From Minetest Developer Wiki
< Engine
Revision as of 07:57, 15 February 2013 by Celeron55 (talk | contribs)
Jump to navigation Jump to search

The Minetest protocol is a small recursive layer on top of UDP. There is a header and four packet types:

A packet is sent through a channel to a peer with a basic header:
    Header (7 bytes):
    [0] u32 protocol_id
    [4] u16 sender_peer_id
    [6] u8 channel
sender_peer_id:
    Unique to each peer.
    value 0 is reserved for making new connections
    value 1 is reserved for server
channel:
    The lower the number, the higher the priority is.
    Only channels 0, 1 and 2 exist.
*/
#define BASE_HEADER_SIZE 7
#define PEER_ID_INEXISTENT 0
#define PEER_ID_SERVER 1
#define CHANNEL_COUNT 3

/*
Packet types:

CONTROL: This is a packet used by the protocol.
- When this is processed, nothing is handed to the user.
    Header (2 byte):
    [0] u8 type
    [1] u8 controltype
controltype and data description:
    CONTROLTYPE_ACK
        [2] u16 seqnum
    CONTROLTYPE_SET_PEER_ID
        [2] u16 peer_id_new
    CONTROLTYPE_PING
    - There is no actual reply, but this can be sent in a reliable
      packet to get a reply
    CONTROLTYPE_DISCO
*/
#define TYPE_CONTROL 0
#define CONTROLTYPE_ACK 0
#define CONTROLTYPE_SET_PEER_ID 1
#define CONTROLTYPE_PING 2
#define CONTROLTYPE_DISCO 3

/*
ORIGINAL: This is a plain packet with no control and no error
checking at all.
- When this is processed, it is directly handed to the user.
    Header (1 byte):
    [0] u8 type
*/
#define TYPE_ORIGINAL 1
#define ORIGINAL_HEADER_SIZE 1

/*
SPLIT: These are sequences of packets forming one bigger piece of
data.
- When processed and all the packet_nums 0...packet_count-1 are
  present (this should be buffered), the resulting data shall be
  directly handed to the user.
- If the data fails to come up in a reasonable time, the buffer shall
  be silently discarded.
- These can be sent as-is or atop of a RELIABLE packet stream.
    Header (7 bytes):
    [0] u8 type
    [1] u16 seqnum
    [3] u16 chunk_count
    [5] u16 chunk_num
*/
#define TYPE_SPLIT 2

/*
RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs,
and they shall be delivered in the same order as sent. This is done
with a buffer in the receiving and transmitting end.
- When this is processed, the contents of each packet is recursively
  processed as packets.
    Header (3 bytes):
    [0] u8 type
    [1] u16 seqnum

*/
#define TYPE_RELIABLE 3
#define RELIABLE_HEADER_SIZE 3

#define SEQNUM_INITIAL 65500

The RELIABLE packet wraps any other packet inside it, and once it is received, an ACK/CONTROL is sent back.

A peer should send PING/CONTROL packets every 5 seconds if it has not sent any other packets.

These packet types are used in practice:

  • CONTROL(data) - unreliable control packet
  • ORIGINAL(data) - unreliable small data
  • SPLIT(piece of data) - unreliable piece of large data
  • RELIABLE(CONTROL(data)) - reliable control packet
  • RELIABLE(ORIGINAL(DATA)) - reliable small data
  • RELIABLE(SPLIT(piece of data)) - reliable piece of large data

The SPLIT packet means data is split into multiple packets (because the internet doesn't transfer UDP packets larger than ~500 bytes); once all pieces of a SPLIT packet are received (identified as having the same seqnum and accumulating all the pieces 0...chunk_count-1), the insides is returned to the user of the network stack like data of an ORIGINAL packet.