-
-
Notifications
You must be signed in to change notification settings - Fork 386
Network architecture design
This document contains concepts and ideas of network support architecture design for Free Heroes of Might and Magic II project (fheroes2). fheroes2 is a game engine for turn-based strategy called Heroes of Might and Magic 2. This game genre is based on a fact that only one player can execute an action at the time. In other words, it is not a real time game which requires instant updates of player statuses.
Network support is an important but at the same time complicated part of the project which requires detailed logic explanation. That is why this document exists. The complexity of network implementation leads to dividing it into separate stages.
Integrate a third party library into fheroes2 project responsible for TCP/IP connection between clients (fheroes2 application) and between a client and server (to be developed separately). The library must be OS-independent and lightweight.
asio library was chosen for this stage. network
branch in the main repository was created with automated setup of the library.
Implemented basic handshaking between clients and initial messaging system integration.
- as any network implementation the smallest item in the messaging is a message. NetworkMessage is a base class for any kind of messaging. It is responsible for adding message header and message size which are not encrypted. The header for each message is
fh2
which is 3 bytes. The size of the message is 4 bytes. The pseudo code is shown below:
namespace fheroes2
{
class NetworkMessage
{
public:
NetworkMessage( Data ); // ideally std::vector<uint8_t>
const std::vector<uint8_t> data();
protected:
std::vector<uint8_t> _data;
};
}
All data is stored using big endianess.
- handshaking implementation includes a separate class which is responsible for generation of handshake messages and their validation. Handshake messages are used for verification of connecting applications and subsequent establishment of a secured connection between host and client. The handshake message must not be dependent on network library. The pseudo code of the class should look like this:
namespace fheroes2
{
class NetworkHandshake
{
public:
enum ReturnCode : uint8_t
{
NO_ERROR = 0,
INVALID_MESSAGE = 1,
INCOMPATBILE_VERSIONS = 2,
NOT_A_HOST = 3 // client cannot connect to another application which is not marked as a host
};
Message createRequestMessage( HostInfo );
Message createReplyMessage( ClientInfo, clientHandshakeMessage, NetworkEncryption ); // NetworkEncryption is covered below
ReturnCode verifyRequestMessage() const;
ReturnCode verifyResponseMessage() const;
};
}
Handshake messaging works as a filter for invalid and spamming connections. Both handshake messages from client and from host are no encrypted. The handshake message from a client must include the following information:
- Version of the game. 1 byte for major version, 1 byte for minor version and 1 byte for intermediate version. For example, 0x00090B corresponds to 0.9.11 version of the game. (3 bytes)
Once the host receives the first handshake message it generates private and public keys. The reply message consists of:
- Reply code: 0x0 means that the original message from the client is valid. (1 byte)
- Public encryption key from the host. For stage 2 it can be all zeroes (16 bytes)
- encryption setup stage is mandatory for security reasons and to avoid cheating. Encryption is not network library dependent code. A pseudo code for this should look like:
namespace fheroes2
{
class NetworkEncryption
{
public:
PublicKey addClient( ClientInfo );
bool addHost( Message );
bool encrypt();
bool decrypt( ServerInfo ); // server corresponds to client or host
void removeConnection( ServerInfo );
};
}