Minecraft:RakNet: Difference between revisions
More actions
Sync: updated from Minecraft |
Sync: updated from Minecraft |
||
| Line 1: | Line 1: | ||
{{Exclusive|bedrock}} | {{Exclusive|bedrock}} | ||
'''RakNet'''<ref>http://www.jenkinssoftware.com/</ref> is a networking library | |||
The source code for the | '''RakNet'''<ref>http://www.jenkinssoftware.com/</ref> is a networking library and protocol for multiplayer games. It runs over UDP and provides connection management, configurable reliability and ordering, sequencing, and fragmentation. | ||
UDP does not guarantee delivery or ordering. RakNet supports different delivery modes, so applications can request reliability or ordering when needed. | |||
The source code for RakNet is available in the [https://github.com/OculusVR/RakNet/ OculusVR archive]. | |||
== Use in Bedrock Edition == | |||
In [[Minecraft:Bedrock Edition]], [[Minecraft:NetherNet]] became the default transport for dedicated servers in [[Minecraft:26.50]]. RakNet is deprecated in the [[Minecraft:26.60.22]] Preview. | |||
== Libraries == | == Libraries == | ||
Here is an incomplete list of RakNet libraries. Their supported features and protocol versions may differ, so check each project's documentation for compatibility. | |||
Here is an incomplete list | |||
{| class="wikitable sortable" style="width: auto; text-align: center;" | {| class="wikitable sortable" style="width: auto; text-align: center;" | ||
| Line 15: | Line 21: | ||
! Language | ! Language | ||
! License | ! License | ||
|- | |- | ||
! [https://github.com/sandertv/go-raknet go-raknet] | ! [https://github.com/sandertv/go-raknet go-raknet] | ||
| | | RakNet implementation used by [https://github.com/df-mc/dragonfly Dragonfly]. | ||
| | | Go | ||
| MIT | | MIT | ||
|- | |- | ||
! [https://github.com/ | ! [https://github.com/NetrexMC/RakNet RakNet] | ||
| RakNet implementation written in Rust. | | Asynchronous RakNet implementation written in Rust. | ||
| Rust | | Rust | ||
| Apache | | Apache-2.0 | ||
|- | |- | ||
! [https://github.com/PieMC-Dev/PieRakNet PieRakNet] | ! [https://github.com/PieMC-Dev/PieRakNet PieRakNet] | ||
| | | RakNet implementation written in Python for [https://github.com/PieMC-Dev/PieMC PieMC]. | ||
| Python | | Python | ||
| GPL-3 | | GPL-3.0 | ||
|- | |- | ||
! [https://github.com/ | ! [https://github.com/CloudburstMC/Network Cloudburst Network] | ||
| Network components used | | Network components used by CloudburstMC projects. | ||
| Java | | Java | ||
| Apache | | Apache-2.0 | ||
|- | |- | ||
! [https://github.com/Podrum/rak_net rak-net] | ! [https://github.com/Podrum/rak_net rak-net] | ||
| | | Python RakNet implementation originally developed for Podrum. | ||
| Python | | Python | ||
| GPL | | GPL-2.0 | ||
|- | |- | ||
! [https://github.com/ | ! [https://github.com/whirvis/JRakNet JRakNet] | ||
| | | Java implementation of the RakNet protocol. | ||
| Java | | Java | ||
| MIT | | MIT | ||
|- | |- | ||
! [https://github.com/yesdog/netty-raknet netty-raknet] | ! [https://github.com/yesdog/netty-raknet netty-raknet] | ||
| | | RakNet implementation for Netty. | ||
| Java | | Java | ||
| MIT | | MIT | ||
|- | |- | ||
! [https://github.com/ | ! [https://github.com/alejzeis/JRakLibPlus JRakLibPlus] | ||
| | | RakNet server library based on RakLib and JRakLib. | ||
| Java | | Java | ||
| LGPL | | LGPL | ||
|- | |||
|- | |||
! [https://github.com/pmmp/RakLib RakLib] | ! [https://github.com/pmmp/RakLib RakLib] | ||
| RakNet server implementation | | Lightweight PHP RakNet server implementation. | ||
| PHP | | PHP | ||
| GPL | | GPL-3.0 | ||
|- | |||
|- | |||
! [https://www.npmjs.com/package/raknet/ raknet] | ! [https://www.npmjs.com/package/raknet/ raknet] | ||
| UDP | | UDP networking library for Node.js that follows the RakNet protocol. | ||
| | | JavaScript | ||
| MIT | | MIT | ||
|- | |- | ||
! [https://pypi.org/project/PyRakLib/ PyRakLib] | ! [https://pypi.org/project/PyRakLib/ PyRakLib] | ||
| | | Python port of RakLib that follows the RakNet protocol. | ||
| Python | | Python | ||
| GPL | | GPL | ||
|- | |||
|- | |||
! [https://github.com/b23r0/rust-raknet rust-raknet] | ! [https://github.com/b23r0/rust-raknet rust-raknet] | ||
| RakNet | | RakNet implementation written in Rust. | ||
| Rust | | Rust | ||
| MIT | | MIT | ||
|- | |- | ||
! [https://github.com/SerenityJS/Baltica Baltica] | |||
| | | Bedrock toolkit that includes a RakNet implementation. | ||
|TypeScript | | TypeScript | ||
| | | See repository | ||
|- | |||
|- | |||
! [https://github.com/mfdgaming/raknet.py RakNet.Py] | ! [https://github.com/mfdgaming/raknet.py RakNet.Py] | ||
| | | RakNet protocol version 5 implementation for older MCPE versions. | ||
| Python | | Python | ||
| GPL | | GPL | ||
|- | |- | ||
![https://github.com/LavishMC/ | ! [https://github.com/LavishMC/RakNet LavishMC RakNet] | ||
| C++ fork of the original RakNet implementation. | |||
|C++ | |||
| C++ | | C++ | ||
| BSD | | BSD | ||
| | |- | ||
! [https://github.com/facebookarchive/RakNet RakNet (original)] | |||
| Original C++ RakNet implementation. | |||
| C++ | |||
| BSD-2-Clause | |||
|} | |} | ||
== Data types == | == Data types == | ||
RakNet packet fields use fixed-width integers and a few protocol-specific types. Byte order depends on the field; use the packet definition when encoding or decoding multi-byte values.<ref>[https://github.com/facebookarchive/RakNet/blob/master/Source/BitStream.h RakNet: BitStream] [https://github.com/GolemOrg/RakNet/blob/master/PROTOCOL.md GolemOrg: RakNet protocol notes]</ref> | |||
{| class="wikitable" | {| class="wikitable" | ||
! Type !! Size !! Description | |||
! | |||
! | |||
|- | |- | ||
! Byte | |||
|byte | | 1 byte | ||
| | | Unsigned 8-bit value. | ||
|- | |- | ||
! Boolean | |||
|byte | | 1 byte | ||
| <code>0x00</code> is false; <code>0x01</code> is true. | |||
| | |||
|- | |- | ||
! Short | |||
| | | 2 bytes | ||
| | | Signed 16-bit integer. | ||
|- | |- | ||
! Unsigned Short | |||
| | | 2 bytes | ||
| | | Unsigned 16-bit integer. | ||
|- | |- | ||
! Int | |||
| | | 4 bytes | ||
| | | Signed 32-bit integer. | ||
|- | |- | ||
! Long | |||
| | | 8 bytes | ||
| | | 64-bit integer. Whether it represents a signed value depends on the field. | ||
|- | |- | ||
! uint24le | |||
| | | 3 bytes | ||
| | | Unsigned 24-bit little-endian integer, used for frame sequence numbers. | ||
|- | |- | ||
| | ! String | ||
| | | Variable | ||
| In RakNet string fields, an unsigned 16-bit length precedes the string bytes. | |||
|- | |- | ||
! Magic | |||
| | | 16 bytes | ||
| | | The fixed <code>00ffff00fefefefefdfdfdfd12345678</code> value used in offline packets.<ref>[https://github.com/facebookarchive/RakNet/blob/master/Source/RakPeer.cpp RakNet: RakPeer.cpp]</ref> | ||
|- | |- | ||
! | ! Address | ||
| | | 7 bytes (IPv4); 29 bytes (IPv6) | ||
| | | Encodes the address family, address and port. IPv4 address bytes are inverted; the port is big-endian. IPv6 also includes address-family, flow-info and scope fields.<ref name="address-format">[https://github.com/GolemOrg/RakNet/blob/master/PROTOCOL.md GolemOrg: RakNet address format]</ref> | ||
|} | |} | ||
== Handshake sequence == | == Handshake sequence == | ||
RakNet establishes a peer connection first, then completes the connection with the application.<ref>[https://github.com/facebookarchive/RakNet/blob/master/Source/RakPeer.cpp RakNet: RakPeer.cpp] [https://github.com/GolemOrg/RakNet/blob/master/PROTOCOL.md GolemOrg: RakNet connection sequence]</ref> | |||
# C→S: [[#Open Connection Request 1|Open Connection Request 1]] | # C→S: [[#Open Connection Request 1|Open Connection Request 1]] | ||
# S→C: [[#Open Connection Reply 1|Open Connection Reply 1]] | # S→C: [[#Open Connection Reply 1|Open Connection Reply 1]] (or [[#Incompatible Protocol|Incompatible Protocol]]) | ||
# C→S: [[#Open Connection Request 2|Open Connection Request 2]] | # C→S: [[#Open Connection Request 2|Open Connection Request 2]] | ||
# S→C: [[#Open Connection Reply 2|Open Connection Reply 2]] | # S→C: [[#Open Connection Reply 2|Open Connection Reply 2]]. The RakNet peer connection is established. | ||
# C→S: [[#Connection Request|Connection Request]] | # C→S: [[#Connection Request|Connection Request]] | ||
# S→C: [[#Connection Request Accepted|Connection Request Accepted]] | # S→C: [[#Connection Request Accepted|Connection Request Accepted]] | ||
# C→S: [[#New Incoming Connection|New Incoming Connection]] | # C→S: [[#New Incoming Connection|New Incoming Connection]] | ||
After this exchange, peers can send connected packets. In Bedrock Edition, game packets are carried in RakNet frames as described at [[#Game Packet|Game Packet]]. | |||
== Packets == | == Packets == | ||
Packet identifiers below follow the standard RakNet packet IDs. Some field details vary by implementation.<ref>[https://github.com/facebookarchive/RakNet/blob/master/Source/MessageIdentifiers.h RakNet: Message identifiers] [https://github.com/GolemOrg/RakNet/blob/master/PROTOCOL.md GolemOrg: RakNet protocol notes]</ref> | |||
=== Unconnected Ping === | === Unconnected Ping === | ||
{| class="wikitable" | {| class="wikitable" | ||
! Packet ID | ! Packet ID | ||
| Line 276: | Line 191: | ||
|} | |} | ||
The client sends this packet to discover a server. ID <code>0x01</code> is a regular unconnected ping; <code>0x02</code> asks for a response only when the server has open connections. The server replies with [[#Unconnected Pong|Unconnected Pong]]. | |||
<code>0x02</code> | |||
=== Unconnected Pong === | === Unconnected Pong === | ||
{| class="wikitable" | {| class="wikitable" | ||
! Packet ID | ! Packet ID | ||
| Line 302: | Line 216: | ||
| Server ID String | | Server ID String | ||
| string | | string | ||
| | | Carries server-list information. | ||
|} | |} | ||
The server sends this in response to an unconnected ping. It echoes the ping time and includes its GUID and a server ID string. In [[Minecraft:Bedrock Edition]], that string contains server-list information in a semicolon-delimited format; its fields can vary by game version. | |||
=== Connected Ping === | === Connected Ping === | ||
| Line 332: | Line 235: | ||
|} | |} | ||
This | This packet measures latency on an established connection. It is commonly sent unreliably. | ||
=== Connected Pong === | === Connected Pong === | ||
{| class="wikitable" | {| class="wikitable" | ||
! Packet ID | ! Packet ID | ||
| Line 352: | Line 255: | ||
|} | |} | ||
The receiver replies with the original ping time and its own response time. It is commonly sent unreliably. | |||
=== Open Connection Request 1 === | === Open Connection Request 1 === | ||
The first packet in the handshake sequence, sent by the client to the server. | The first packet in the handshake sequence, sent by the client to the server. | ||
{| class="wikitable" | {| class="wikitable" | ||
! Packet ID | ! Packet ID | ||
| Line 369: | Line 274: | ||
| Protocol version | | Protocol version | ||
| byte | | byte | ||
| | | RakNet protocol version used by the client. | ||
|- | |- | ||
| MTU | | MTU | ||
| Zero padding | | Zero padding | ||
| | | Zero padding used to probe the path MTU. | ||
|} | |} | ||
The | The padding is used to probe the path MTU. The server replies with the selected MTU, or sends [[#Incompatible Protocol|Incompatible Protocol]] if it does not support the client's RakNet protocol version. | ||
=== Open Connection Reply 1 === | === Open Connection Reply 1 === | ||
The second packet in the handshake sequence, sent by the server to the client. | The second packet in the handshake sequence, sent by the server to the client. | ||
{| class="wikitable" | {| class="wikitable" | ||
! Packet ID | ! Packet ID | ||
| Line 398: | Line 304: | ||
| Use security | | Use security | ||
| boolean | | boolean | ||
| | | Indicates whether the server is using RakNet's security challenge. | ||
|- | |- | ||
| Cookie | | Cookie | ||
| Int | | Int | ||
| | | Present only when security is enabled; returned by the client in Open Connection Request 2. | ||
|- | |- | ||
| MTU | | MTU | ||
| Unsigned short | | Unsigned short | ||
| | | Selected MTU for the connection. | ||
|} | |} | ||
=== Open Connection Request 2 === | === Open Connection Request 2 === | ||
The third packet in the handshake sequence, sent by the client to the server. | The third packet in the handshake sequence, sent by the client to the server. | ||
{| class="wikitable" | {| class="wikitable" | ||
! Packet ID | ! Packet ID | ||
| Line 421: | Line 329: | ||
| MAGIC | | MAGIC | ||
| | | | ||
|- | |||
|- | |||
| Cookie | | Cookie | ||
| Int | | Int | ||
| | | Present only when the server provided a cookie. | ||
|- | |- | ||
| Has security challenge | | Has security challenge | ||
| boolean | | boolean | ||
| | | Sent with the cookie when security is enabled. | ||
|- | |- | ||
| Server Address | | Server Address | ||
| address | | address | ||
| | | | ||
|- | |||
|- | |||
| MTU | | MTU | ||
| | | Unsigned Short | ||
| | | | ||
|- | |||
|- | |||
| Client GUID | | Client GUID | ||
| Long | | Long | ||
| Line 447: | Line 352: | ||
=== Open Connection Reply 2 === | === Open Connection Reply 2 === | ||
The fourth packet in the handshake sequence, sent by the server to the client. | The fourth packet in the handshake sequence, sent by the server to the client. | ||
{| class="wikitable" | {| class="wikitable" | ||
! Packet ID | ! Packet ID | ||
| Line 468: | Line 375: | ||
|- | |- | ||
| MTU | | MTU | ||
| | | Unsigned Short | ||
| | | | ||
|- | |- | ||
| Line 477: | Line 384: | ||
=== Connection Request === | === Connection Request === | ||
The client sends this packet after the RakNet peer connection is established to request an application-level connection. | |||
{| class="wikitable" | {| class="wikitable" | ||
! Packet ID | ! Packet ID | ||
| Line 498: | Line 408: | ||
=== Connection Request Accepted === | === Connection Request Accepted === | ||
The server sends this packet to accept the client's connection request. | |||
{| class="wikitable" | {| class="wikitable" | ||
! Packet ID | ! Packet ID | ||
| Line 510: | Line 423: | ||
|- | |- | ||
| System index | | System index | ||
| | | Unsigned Short | ||
| | | System index assigned by the server. | ||
|- | |- | ||
| Internal | | Internal addresses | ||
| 10x address | | 10x address | ||
| | | Internal server addresses. | ||
|- | |- | ||
| Request time | | Request time | ||
| Line 523: | Line 436: | ||
| Time | | Time | ||
| Long | | Long | ||
| | | Server acceptance time. | ||
|} | |} | ||
=== New Incoming Connection === | === New Incoming Connection === | ||
The client sends this packet to confirm that it received the server's acceptance. | |||
{| class="wikitable" | {| class="wikitable" | ||
! Packet ID | ! Packet ID | ||
| Line 538: | Line 454: | ||
| | | | ||
|- | |- | ||
| Internal | | Internal addresses | ||
| 20x address | | 20x address | ||
| | | Internal client addresses. | ||
|- | |- | ||
| Incoming Timestamp | | Incoming Timestamp | ||
| Long | | Long | ||
| | | | ||
|- | |- | ||
| Server Timestamp | | Server Timestamp | ||
| Line 554: | Line 468: | ||
|} | |} | ||
=== | === Disconnection Notification === | ||
This packet notifies the other peer that the sender is disconnecting | |||
{| class="wikitable" | {| class="wikitable" | ||
! Packet ID !! Field Name !! Field Type !! Notes | |||
|- | |||
| 0x15 || colspan="2" | No payload || Signals that the sender is disconnecting. | |||
|} | |||
=== Incompatible Protocol === | === Incompatible Protocol === | ||
The server sends this packet when it does not support the RakNet protocol version used by the client. | |||
{| class="wikitable" | {| class="wikitable" | ||
! Packet ID | ! Packet ID | ||
| Line 584: | Line 503: | ||
|} | |} | ||
=== Frame Set Packet === | === Frame Set Packet === | ||
This packet carries one or more frames between connected peers. | |||
{| class="wikitable" | {| class="wikitable" | ||
! Packet ID | ! Packet ID | ||
| Line 641: | Line 547: | ||
|rowspan="3"| Fragment<br>(only if fragmented) | |rowspan="3"| Fragment<br>(only if fragmented) | ||
| Compound size | | Compound size | ||
| | | Unsigned Int | ||
| Total size of the compound | | Total size of the compound | ||
|- | |- | ||
| Compound ID | | Compound ID | ||
| | | Unsigned Short | ||
| Identifies which compound this fragment is part of | | Identifies which compound this fragment is part of | ||
|- | |- | ||
| Index | | Index | ||
| | | Unsigned Int | ||
| Index of this fragment in the compound | | Index of this fragment in the compound | ||
|- | |- | ||
| Line 659: | Line 565: | ||
'''Note 1: there can be multiple frames in each Frame Set Packet.'''<br> | '''Note 1: there can be multiple frames in each Frame Set Packet.'''<br> | ||
'''Note 2: A packet is a Frame Set Packet if <code>(packet_ID & 0x80) == 0x80</code> and <code>(packet_ID & 0x60) == 0</code>''' | '''Note 2: A packet is a Frame Set Packet if <code>(packet_ID & 0x80) == 0x80</code> and <code>(packet_ID & 0x60) == 0</code>''' | ||
The reliability types are as follows: | The reliability types are as follows: | ||
| Line 667: | Line 573: | ||
! style="font-weight: bold;" | Name | ! style="font-weight: bold;" | Name | ||
! style="text-align: center; font-weight: bold;" | Reliable | ! style="text-align: center; font-weight: bold;" | Reliable | ||
! style="text-align: center; font-weight: bold;" | Sequenced | |||
! style="text-align: center; font-weight: bold;" | Ordered | ! style="text-align: center; font-weight: bold;" | Ordered | ||
|- | |- | ||
| style="text-align: center;" | 0 | | style="text-align: center;" | 0 | ||
| Line 680: | Line 586: | ||
| style="text-align: center;" | | | style="text-align: center;" | | ||
| style="text-align: center;" | x | | style="text-align: center;" | x | ||
| style="text-align: center;" | | | style="text-align: center;" | | ||
|- | |- | ||
| style="text-align: center;" | 2 | | style="text-align: center;" | 2 | ||
| Line 691: | Line 597: | ||
| reliable ordered | | reliable ordered | ||
| style="text-align: center;" | x | | style="text-align: center;" | x | ||
| style="text-align: center;" | | |||
| style="text-align: center;" | x | | style="text-align: center;" | x | ||
|- | |- | ||
| style="text-align: center;" | 4 | | style="text-align: center;" | 4 | ||
| Line 698: | Line 604: | ||
| style="text-align: center;" | x | | style="text-align: center;" | x | ||
| style="text-align: center;" | x | | style="text-align: center;" | x | ||
| style="text-align: center;" | | | style="text-align: center;" | | ||
|- | |- | ||
| style="text-align: center;" | 5 | | style="text-align: center;" | 5 | ||
| Line 715: | Line 621: | ||
| reliable ordered (+ ACK receipt) | | reliable ordered (+ ACK receipt) | ||
| style="text-align: center;" | x | | style="text-align: center;" | x | ||
| style="text-align: center;" | | |||
| style="text-align: center;" | x | | style="text-align: center;" | x | ||
|} | |} | ||
Sequenced | Sequenced delivery discards older packets when a newer packet has arrived. Ordered delivery preserves the order of reliable packets within a channel. | ||
=== Game Packet === | === Game Packet === | ||
This packet carries game-protocol data. In [[Minecraft:Bedrock Edition]], its body contains a batch of game packets. | |||
{| class="wikitable" | {| class="wikitable" | ||
! Packet ID | ! Packet ID | ||
| Line 731: | Line 640: | ||
| Body | | Body | ||
| bytes | | bytes | ||
| | | In [[Minecraft:Bedrock Edition]], the body contains a batch of game packets. Framing and compression are described in [[Minecraft:Bedrock Edition protocol#Packet Format|Bedrock Edition protocol]]. | ||
|} | |} | ||
In [[Minecraft: | In [[Minecraft:Bedrock Edition]], the body carries a batch of game packets encoded according to the [[Minecraft:Bedrock Edition protocol]]. See [[Minecraft:Bedrock_Edition_protocol/Packets|Bedrock Edition protocol/Packets]] for their definitions. | ||
=== NACK === | === NACK === | ||
This packet reports [[Minecraft:wikipedia:User_Datagram_Protocol|datagrams]] that were not received so the sender can retransmit them when required. | |||
{| class="wikitable" | {| class="wikitable" | ||
! style="font-weight: bold;" | Packet ID | ! style="font-weight: bold;" | Packet ID | ||
| Line 744: | Line 656: | ||
| rowspan="5" | 0xa0 | | rowspan="5" | 0xa0 | ||
| colspan="3" | Record count | | colspan="3" | Record count | ||
| | | Unsigned Short | ||
| Number of records in the packet | | Number of records in the packet | ||
|- | |- | ||
| Line 755: | Line 667: | ||
| Sequence number | | Sequence number | ||
| uint24le | | uint24le | ||
| | | Datagram sequence number in this record. | ||
|- | |- | ||
| rowspan="2" | Range, if <code>is_single == false</code> | | rowspan="2" | Range, if <code>is_single == false</code> | ||
| Start Sequence number | | Start Sequence number | ||
| uint24le | | uint24le | ||
| | |First datagram sequence number in the range. | ||
|- | |- | ||
| End Sequence number | | End Sequence number | ||
| uint24le | | uint24le | ||
| | |Last datagram sequence number in the range. | ||
|} | |} | ||
A NACK | A NACK reports frame-set sequence numbers that were not received, prompting retransmission where required. | ||
=== ACK === | === ACK === | ||
This packet acknowledges [[Minecraft:wikipedia:User_Datagram_Protocol|datagrams]] received from the other peer. | |||
{| class="wikitable" | {| class="wikitable" | ||
! style="font-weight: bold;" | Packet ID | ! style="font-weight: bold;" | Packet ID | ||
| Line 777: | Line 692: | ||
| rowspan="5" | 0xc0 | | rowspan="5" | 0xc0 | ||
| colspan="3" | Record count | | colspan="3" | Record count | ||
| | | Unsigned Short | ||
| Number of records in the packet | | Number of records in the packet | ||
|- | |- | ||
| Line 788: | Line 703: | ||
| Sequence number | | Sequence number | ||
| uint24le | | uint24le | ||
| | | Datagram sequence number in this record. | ||
|- | |- | ||
| rowspan="2" | Range, if <code>is_single == false</code> | | rowspan="2" | Range, if <code>is_single == false</code> | ||
| Start Sequence number | | Start Sequence number | ||
| uint24le | | uint24le | ||
| | |First datagram sequence number in the range. | ||
|- | |- | ||
| End Sequence number | | End Sequence number | ||
| uint24le | | uint24le | ||
| | |Last datagram sequence number in the range. | ||
|} | |} | ||
An ACK | An ACK reports frame-set sequence numbers that were received. Both ACK and NACK packets can contain multiple records. | ||
== References == | == References == | ||
| Line 810: | Line 723: | ||
[[Category:Bedrock Edition]] | [[Category:Bedrock Edition]] | ||
Revision as of 11:21, 3 October 2026
RakNet<ref>http://www.jenkinssoftware.com/</ref> is a networking library and protocol for multiplayer games. It runs over UDP and provides connection management, configurable reliability and ordering, sequencing, and fragmentation.
UDP does not guarantee delivery or ordering. RakNet supports different delivery modes, so applications can request reliability or ordering when needed.
The source code for RakNet is available in the OculusVR archive.
Use in Bedrock Edition
In Minecraft:Bedrock Edition, Minecraft:NetherNet became the default transport for dedicated servers in Minecraft:26.50. RakNet is deprecated in the Minecraft:26.60.22 Preview.
Libraries
Here is an incomplete list of RakNet libraries. Their supported features and protocol versions may differ, so check each project's documentation for compatibility.
| Name | Description | Language | License |
|---|---|---|---|
| go-raknet | RakNet implementation used by Dragonfly. | Go | MIT |
| RakNet | Asynchronous RakNet implementation written in Rust. | Rust | Apache-2.0 |
| PieRakNet | RakNet implementation written in Python for PieMC. | Python | GPL-3.0 |
| Cloudburst Network | Network components used by CloudburstMC projects. | Java | Apache-2.0 |
| rak-net | Python RakNet implementation originally developed for Podrum. | Python | GPL-2.0 |
| JRakNet | Java implementation of the RakNet protocol. | Java | MIT |
| netty-raknet | RakNet implementation for Netty. | Java | MIT |
| JRakLibPlus | RakNet server library based on RakLib and JRakLib. | Java | LGPL |
| RakLib | Lightweight PHP RakNet server implementation. | PHP | GPL-3.0 |
| raknet | UDP networking library for Node.js that follows the RakNet protocol. | JavaScript | MIT |
| PyRakLib | Python port of RakLib that follows the RakNet protocol. | Python | GPL |
| rust-raknet | RakNet implementation written in Rust. | Rust | MIT |
| Baltica | Bedrock toolkit that includes a RakNet implementation. | TypeScript | See repository |
| RakNet.Py | RakNet protocol version 5 implementation for older MCPE versions. | Python | GPL |
| LavishMC RakNet | C++ fork of the original RakNet implementation. | C++ | BSD |
| RakNet (original) | Original C++ RakNet implementation. | C++ | BSD-2-Clause |
Data types
RakNet packet fields use fixed-width integers and a few protocol-specific types. Byte order depends on the field; use the packet definition when encoding or decoding multi-byte values.<ref>RakNet: BitStream GolemOrg: RakNet protocol notes</ref>
| Type | Size | Description |
|---|---|---|
| Byte | 1 byte | Unsigned 8-bit value. |
| Boolean | 1 byte | 0x00 is false; 0x01 is true.
|
| Short | 2 bytes | Signed 16-bit integer. |
| Unsigned Short | 2 bytes | Unsigned 16-bit integer. |
| Int | 4 bytes | Signed 32-bit integer. |
| Long | 8 bytes | 64-bit integer. Whether it represents a signed value depends on the field. |
| uint24le | 3 bytes | Unsigned 24-bit little-endian integer, used for frame sequence numbers. |
| String | Variable | In RakNet string fields, an unsigned 16-bit length precedes the string bytes. |
| Magic | 16 bytes | The fixed 00ffff00fefefefefdfdfdfd12345678 value used in offline packets.<ref>RakNet: RakPeer.cpp</ref>
|
| Address | 7 bytes (IPv4); 29 bytes (IPv6) | Encodes the address family, address and port. IPv4 address bytes are inverted; the port is big-endian. IPv6 also includes address-family, flow-info and scope fields.<ref name="address-format">GolemOrg: RakNet address format</ref> |
Handshake sequence
RakNet establishes a peer connection first, then completes the connection with the application.<ref>RakNet: RakPeer.cpp GolemOrg: RakNet connection sequence</ref>
- C→S: Open Connection Request 1
- S→C: Open Connection Reply 1 (or Incompatible Protocol)
- C→S: Open Connection Request 2
- S→C: Open Connection Reply 2. The RakNet peer connection is established.
- C→S: Connection Request
- S→C: Connection Request Accepted
- C→S: New Incoming Connection
After this exchange, peers can send connected packets. In Bedrock Edition, game packets are carried in RakNet frames as described at Game Packet.
Packets
Packet identifiers below follow the standard RakNet packet IDs. Some field details vary by implementation.<ref>RakNet: Message identifiers GolemOrg: RakNet protocol notes</ref>
Unconnected Ping
| Packet ID | Field Name | Field Type | Notes |
|---|---|---|---|
| 0x01, 0x02 | Time | Long | |
| MAGIC | magic | ||
| Client GUID | Long |
The client sends this packet to discover a server. ID 0x01 is a regular unconnected ping; 0x02 asks for a response only when the server has open connections. The server replies with Unconnected Pong.
Unconnected Pong
| Packet ID | Field Name | Field Type | Notes |
|---|---|---|---|
| 0x1c | Time | Long | |
| Server GUID | Long | ||
| MAGIC | magic | ||
| Server ID String | string | Carries server-list information. |
The server sends this in response to an unconnected ping. It echoes the ping time and includes its GUID and a server ID string. In Minecraft:Bedrock Edition, that string contains server-list information in a semicolon-delimited format; its fields can vary by game version.
Connected Ping
| Packet ID | Field Name | Field Type | Notes |
|---|---|---|---|
| 0x00 | Time | Long |
This packet measures latency on an established connection. It is commonly sent unreliably.
Connected Pong
| Packet ID | Field Name | Field Type | Notes |
|---|---|---|---|
| 0x03 | Ping Time | Long | |
| Pong Time | Long |
The receiver replies with the original ping time and its own response time. It is commonly sent unreliably.
Open Connection Request 1
The first packet in the handshake sequence, sent by the client to the server.
| Packet ID | Field Name | Field Type | Notes |
|---|---|---|---|
| 0x05 | Magic | MAGIC | |
| Protocol version | byte | RakNet protocol version used by the client. | |
| MTU | Zero padding | Zero padding used to probe the path MTU. |
The padding is used to probe the path MTU. The server replies with the selected MTU, or sends Incompatible Protocol if it does not support the client's RakNet protocol version.
Open Connection Reply 1
The second packet in the handshake sequence, sent by the server to the client.
| Packet ID | Field Name | Field Type | Notes |
|---|---|---|---|
| 0x06 | Magic | MAGIC | |
| Server GUID | Long | ||
| Use security | boolean | Indicates whether the server is using RakNet's security challenge. | |
| Cookie | Int | Present only when security is enabled; returned by the client in Open Connection Request 2. | |
| MTU | Unsigned short | Selected MTU for the connection. |
Open Connection Request 2
The third packet in the handshake sequence, sent by the client to the server.
| Packet ID | Field Name | Field Type | Notes |
|---|---|---|---|
| 0x07 | Magic | MAGIC | |
| Cookie | Int | Present only when the server provided a cookie. | |
| Has security challenge | boolean | Sent with the cookie when security is enabled. | |
| Server Address | address | ||
| MTU | Unsigned Short | ||
| Client GUID | Long |
Open Connection Reply 2
The fourth packet in the handshake sequence, sent by the server to the client.
| Packet ID | Field Name | Field Type | Notes |
|---|---|---|---|
| 0x08 | Magic | MAGIC | |
| Server GUID | Long | ||
| Client Address | address | ||
| MTU | Unsigned Short | ||
| Encryption enabled | boolean |
Connection Request
The client sends this packet after the RakNet peer connection is established to request an application-level connection.
| Packet ID | Field Name | Field Type | Notes |
|---|---|---|---|
| 0x09 | GUID | Long | |
| Time | Long | ||
| Use security | boolean |
Connection Request Accepted
The server sends this packet to accept the client's connection request.
| Packet ID | Field Name | Field Type | Notes |
|---|---|---|---|
| 0x10 | Client address | address | |
| System index | Unsigned Short | System index assigned by the server. | |
| Internal addresses | 10x address | Internal server addresses. | |
| Request time | Long | Shall be the corresponding timestamp of the Connection Request | |
| Time | Long | Server acceptance time. |
New Incoming Connection
The client sends this packet to confirm that it received the server's acceptance.
| Packet ID | Field Name | Field Type | Notes |
|---|---|---|---|
| 0x13 | Server address | address | |
| Internal addresses | 20x address | Internal client addresses. | |
| Incoming Timestamp | Long | ||
| Server Timestamp | Long |
Disconnection Notification
This packet notifies the other peer that the sender is disconnecting
| Packet ID | Field Name | Field Type | Notes |
|---|---|---|---|
| 0x15 | No payload | Signals that the sender is disconnecting. | |
Incompatible Protocol
The server sends this packet when it does not support the RakNet protocol version used by the client.
| Packet ID | Field Name | Field Type | Notes |
|---|---|---|---|
| 0x19 | Protocol | byte | |
| Magic | MAGIC | ||
| Server GUID | Long |
Frame Set Packet
This packet carries one or more frames between connected peers.
| Packet ID | Field Name | Field Type | Notes | ||
|---|---|---|---|---|---|
| 0x80..0x8d | Sequence number | uint24le | Used for building ACK and NACK ranges | ||
| Frames | Flags | byte | Top 3 bits give the reliability type, fourth bit is 1 when the frame is fragmented and part of a compound. | ||
| Length IN BITS | unsigned short | Length of the body in bits. Big-endian. | |||
| Reliable frame index | uint24le | Only if reliable, used for detecting frame level duplication | |||
| Sequenced frame index | uint24le | Only if sequenced, used for discarding out-of-date packets | |||
| Order (only if ordered, see below) |
Ordered frame index | uint24le | Tells the receiver the correct order in which to deliver frames to the application | ||
| Order channel | byte | Maximum of 32 channels | |||
| Fragment (only if fragmented) |
Compound size | Unsigned Int | Total size of the compound | ||
| Compound ID | Unsigned Short | Identifies which compound this fragment is part of | |||
| Index | Unsigned Int | Index of this fragment in the compound | |||
| Body | ceil(length/8) bytes | ||||
Note 1: there can be multiple frames in each Frame Set Packet.
Note 2: A packet is a Frame Set Packet if (packet_ID & 0x80) == 0x80 and (packet_ID & 0x60) == 0
The reliability types are as follows:
| ID | Name | Reliable | Sequenced | Ordered |
|---|---|---|---|---|
| 0 | unreliable | |||
| 1 | unreliable sequenced | x | ||
| 2 | reliable | x | ||
| 3 | reliable ordered | x | x | |
| 4 | reliable sequenced | x | x | |
| 5 | unreliable (+ ACK receipt) | |||
| 6 | reliable (+ ACK receipt) | x | ||
| 7 | reliable ordered (+ ACK receipt) | x | x |
Sequenced delivery discards older packets when a newer packet has arrived. Ordered delivery preserves the order of reliable packets within a channel.
Game Packet
This packet carries game-protocol data. In Minecraft:Bedrock Edition, its body contains a batch of game packets.
| Packet ID | Field Name | Field Type | Notes |
|---|---|---|---|
| 0xfe | Body | bytes | In Minecraft:Bedrock Edition, the body contains a batch of game packets. Framing and compression are described in Bedrock Edition protocol. |
In Minecraft:Bedrock Edition, the body carries a batch of game packets encoded according to the Minecraft:Bedrock Edition protocol. See Bedrock Edition protocol/Packets for their definitions.
NACK
This packet reports datagrams that were not received so the sender can retransmit them when required.
| Packet ID | Field Name | Field Type | Notes | ||
|---|---|---|---|---|---|
| 0xa0 | Record count | Unsigned Short | Number of records in the packet | ||
| Records | Is Single? | boolean | False for range, True for no range | ||
No Range, if is_single == true
|
Sequence number | uint24le | Datagram sequence number in this record. | ||
Range, if is_single == false
|
Start Sequence number | uint24le | First datagram sequence number in the range. | ||
| End Sequence number | uint24le | Last datagram sequence number in the range. | |||
A NACK reports frame-set sequence numbers that were not received, prompting retransmission where required.
ACK
This packet acknowledges datagrams received from the other peer.
| Packet ID | Field Name | Field Type | Notes | ||
|---|---|---|---|---|---|
| 0xc0 | Record count | Unsigned Short | Number of records in the packet | ||
| Records | Is Single? | boolean | False for range, True for no range | ||
No Range, if is_single == true
|
Sequence number | uint24le | Datagram sequence number in this record. | ||
Range, if is_single == false
|
Start Sequence number | uint24le | First datagram sequence number in the range. | ||
| End Sequence number | uint24le | Last datagram sequence number in the range. | |||
An ACK reports frame-set sequence numbers that were received. Both ACK and NACK packets can contain multiple records.