Transport & connections¶
Connections¶
Environments¶
The Meta-Lobby exists in two separate environments:
staging
production
The staging environment allows to test multiple room integration. Note that the staging environment is sharing the user datastore with the production environment.
All developers are sharing the same environments. Hopefully all staging application will use the staging instance and all production application will use the production instance. The idea is that all game will use the same instance in order for all players to share and chat together.
Connecting to an Environment¶
The Client connects to the Meta-Lobby with a TLS (1.0+) TCP connection (preferably TLSv1.2 or better).
The client doesn’t authenticate to the server with a certificate (it is an anonymous client), but the player authenticates herself to the server (see authentication).
The client might choose to keep the connection open as much as possible, in this case it should send Ping requests so that the server can detect connection issues (in return the Client receives Ping responses, which also can help detect connection issues), and compute presence information for the given player.
In the event a player is not connected and the Meta-Lobby needs to inform her of an important event, no push notification is intended, only live chat enabler.
A connection is valid for a Player.
TLS Public Key Pinning¶
To be noted that the production and staging Meta-Lobby present a self-signed certificate to the Client. Clients are supposed to validate the server certificate public key with a procedure called Public Key Pinning.
This is a counter-cheating measure that prevents Man in the Middle attacks where the attacker puts a proxy between the client and the server and is able to decrypt/modify the traffic because the client might not check the server is whom it pretends to be.
To prevent this, the client must check that the server offered certificate public key is the correct one. It should also check that the CN
part of the certificate DN
is the one that it connected to (each developer have a different one).
To check that the public key is correct, the client extracts the public key of the certificate presented by the server, and computes a SHA256 hash of it.
The hash should match one of this checksum (valid for the staging environment, the production one will be given to the developer):
Primary:
//TODO
Backup:
//TODO
If the presented public key checksum doesn’t match any of those hash, the client must drop the connection and possibly inform the user that something went wrong.
TLS Troubleshooting¶
The Meta-Lobby listens on the TCP port 2445. You can check that your own network allows to connect to our staging Meta-Lobby with the following command:
openssl s_client -host metalobby-staging.games.asmodee.net -port 2445
This should print the certificate chain and the various TLS parameters that were used.
If you want to check your client code can connect to a TLS server, you can emulate the Meta-Lobby with the following command:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -nodes -days 3650
openssl s_server -no_ssl3 -accept 2445 -key key.pem -cert cert.pem
Then point your client to this fake server to be able to troubleshoot the TLS connection.
On the wire transport protocol¶
Both the client to server and server to client communications use the same transport protocol.
The Meta-Lobby transport protocol is a message based protocol, where client and server exchange messages. Most of the time, the message flow obey a request/response kind of protocol. Sometimes the server might send messages to a client on its own.
The messages are described and serialized/deserialized on the wire with Protocol Buffers (v3) which is an efficient, cross-platform, maintainable system.
Length Delimited Packets¶
The messages are sent over the TLS connection as size-delimited fragments.
The size of the fragment is serialized in RFC1700 network order also called Big Endian, that is the most significant bits will be serialized first, and the last significant bit will be serialized last.
For example, if the payload size is 498 bytes, the size will be serialized to the following byte string:
00 00 01 f2
After this size, we’ll find the serialized payload.
Protobuf matriochkas¶
The Protocol defines several Protobuf messages, but those are not sent verbatim on the wire. They are encapsulated in two different more generic protobuf structures.
Message¶
Each request is encapsulated into a Protobuf oneof field of Message
message Message {
int32 request_number = 1; /// id of the underlying request
oneof request {
PingRequest ping_request = 777; /// 777
com.daysofwonder.metalobby.AsyncAuthRequest async_auth_request = 400; /// 400
[...]
com.daysofwonder.metalobby.RoomCreatedRequest room_created_request = 2001; /// 2001
[...]
}
}
Let’s imagine we’re serializing a Ping
request which is defined as this:
message PingRequest {
int64 timestamp = 1;
}
Then the request_number
will be 777
. When serializing, we’ll get the following (shown as Protobuf decoded text):
{
request_number: 777
ping_request {
timestamp: 12343344456
}
}
The complete definition of the syntax is available on the Protobuf proto3 page.
Note
The wire format is compatible between Protobuf 2 and Protobuf 3. Any client serializing/deserializing the protocol with Protobuf 2.x can successfully connect to the server which uses Protobuf 3.
Packet¶
Before being sent over the wire the Message
needs to be encapsulated into a Packet
structure:
message MetaPacket {
int64 id = 1;
com.daysofwonder.mm.MetaMessage payload = 3;
}
The id
field is filled by the Client with any arbitrary value. If this request allows a response from the server, the Meta-Lobby will do its best to put the same id
in the response to allow the client to match a response to a sent request. Requests sent by the server without any prior request, or requests sent to another client in response of an incoming request will the id
field set at 0 or unset.