Appendix A. Network Layer

Table of Contents

A.1. Locking And Unlocking Buffers
A.2. Managing Connections
A.3. Connection Creation Process
A.4. Configuration And Statistics

A.1. Locking And Unlocking Buffers

The Network subsystem uses both TCP and UDP protocol for communication. More reliable TCP is used in the connection creation process, sending control messages specific for the lower network layer (e.g. PING, DISCONNECT REQUEST, etc.) and for the migration. The unreliable UDP protocol is used mainly in the object replication process (although if the replication data is large, the replication may use TCP as well). Every time a higher Massiv layer wants to send something to another node, the Network is asked to lock a reliable or unreliable buffer.

Network      net;
NodeId       nodeid = ...;
Netobuffer * buffer_tcp = net.lock( nodeid, STREAM_RELIABLE, 
                                    NET_MIN_USER_MESSAGE, true );
  // This locks a TCP buffer for node nodeid.
  // Then a user message is written into the buffer using the standard <<
  // operator. The resulting buffer can be scheduled to be sent using the unlock()
  // method. The message may be sent either immediately or in the next network 
  // tick, according the last lock parameter. In this specific case,
  // the buffer would be sent immediately, because the last parameter is 
  // true.

Netobuffer * buffer_udp = net.lock( node, STREAM_UNRELIABLE, NET_MIN_USER_MESSAGE );
  // This locks a UDP send buffer for node nodeid.
  // The buffer will contain an user message (due to the NET_MIN_USER_MESSAGE).

There are some permanent buffers (the number of permanent buffers is configurable via settings), which can be used in case they are ready to be locked. In case there is no available permanent buffer, the Network automatically creates a dynamic one. When data is written into a buffer, the higher Network layer must unlock the buffer to inform the lower layer that it is ready to be sent.

Network      net;
Netobuffer * locked_tcp = ...;
net.unlock( locked_tcp );
  // This unlocks an already locked TCP buffer.

Netobuffer * locked_udp;
net.unlock( locked_udp );
  // This unlocks an already locked UDP buffer.
  // UDP buffer can be also unlocked using the method
  // unlock_unreliable( locked_udp, false ).
  // The false parameter indicates that the buffer is not completely ready 
  // to be sent. It's going to wait for an explicit flushing with
  // flush( unlocked_udp ) or for being locked again.

The main difference between the TCP and UDP buffers is that in the case of UDP more messages can be added into the buffer, even if it is already prepared to be sent (of course the destination of all the messages must be the same network node). This feature helps to increase the network throughput.

After being unlocked the message body is encrypted using the blowfish ciphre (see Section A.2, “Managing Connections”) and placed into a list of outgoing messages, which will be sent at the end of the network tick. UDP messages also contain the additional CRC checksum of the encrypted message body, to ensure integrity of the data received by the target node.