@gafferongames gafferongames released this Aug 16, 2017 · 17 commits to master since this release

Assets 2

New features in this release:

  1. You can now set the timeout value in ClientServerConfig
  2. Negative timeout values disable timeouts (useful for debugging)
  3. Client::GetAddress and Server::GetAddress now return the correct port when you bind to port 0
  4. Added callbacks in adapter when clients connect and disconnect to the server (see Adapter::OnServerClientConnected and Adapter::OnServerClientDisconnected)

In order to implement the timeouts, this release updates to NETCODE 1.01 spec.

@gafferongames gafferongames released this Jul 26, 2017 · 57 commits to master since this release

Assets 2

Yojimbo is now ready for production use.

@gafferongames gafferongames released this Jul 16, 2017 · 96 commits to master since this release

Assets 2

New features:

  • Client/server completely rebuilt on top of netcode.io and reliable.io
  • Added support for packet fragmentation and reassembly
  • Added detailed logging support with log levels (none, error, info, debug)
  • Users can now override logging printf function and assert payload function
  • matcher.go now uses netcode.io golang implementation to generate connect tokens
  • Updated yojimbo.lib to use multithreaded DLL CRT on Windows so it works with UE4
  • You can now disable mbedtls use with #define YOJIMBO_WITH_MBEDTLS 0

@gafferongames gafferongames released this Jun 1, 2017 · 320 commits to master since this release

Assets 4

This release incorporates all bugfixes since 0.4.0

@gafferongames gafferongames released this Jan 5, 2017 · 383 commits to master since this release

Assets 4

This release adds doxygen documentation for yojimbo.

To build and view the documentation, install doxygen then run:

premake5 docs

It also fixes two critical security issues:

  1. The challenge token sent back to clients on connection request was encrypted with an AEAD primititive, but the code neglected to increase the nonce each time a new challenge was generated. This made it theoretically possible for an attacker to recover the private key shared between the matcher and dedicated servers.
  2. When multiple dedicated server instances are running they reuse the same nonce values, starting at 0 and increasing with each challenge token generated, again risking the private key. To fix this issue the challenge token is now encrypted with a random key rolled in Server::Start instead of the private key shared between matcher and dedicated servers.

Please upgrade immediately or you risk an attacker being able to discover your private key.

@gafferongames gafferongames released this Nov 15, 2016 · 556 commits to master since this release

Assets 4

This is a significant new release and contains major new features and bugfixes. I recommend everybody using libyojimbo update to this release right away. Please be aware that the API is slightly changed in this release.

New features:

  1. Per-client allocator, packet and message factories on the server. This is a security measure to make sure that clients cannot spoil or exhaust a resource shared with other clients, but can only exhaust their own resources. When a client's resources are exhausted on the server, that client is disconnected.
  2. Security fix so that replay attacks with stale connect tokens can be quickly discarded with AEAD signature check vs. having to decrypt the whole connect token just to find out the timestamp is old. This is a much faster reject because signature check is significantly faster than decrypt.
  3. Replay packet attack fix. Malicious clients can no longer sniff your connection packets and replay them to try to corrupt your internal connection state (eg. reliable messages, uint16_t sequence # after wrapping). This would have been a hard attack to pull off due to timing, but it was possible. Now it's impossible.
  4. Client can now pass multiple servers in to secure and insecure connects. Client tries each server in turn, up to MaxServersPerConnect in an array, until the first connect succeeds. This is the intended behavior for connecting via connect token returned from the matcher, and now it's as simple as passing an array of server addresses to the connect function.
  5. Expanded test coverage and bugfixes. I've added test coverage for client reconnecting, switching between insecure connect to secure connect and back to insecure, plus a bunch more stuff. In doing so I found many issues, mostly caused by rare situations or use cases like reconnecting that weren't picked up by previous test coverage.

The nature of these new features and bugfixes required changes to the API. Please refer to shared.h and client.cpp, connect.cpp and server.cpp for examples showing how to setup yojimbo client and server classes with the new API.

@gafferongames gafferongames released this Oct 21, 2016 · 676 commits to master since this release

Assets 5

This release fixes an issue where client connect via matcher failed with this error on Windows:

error: request match failed. is the matcher running?

Which seemed to be caused by the matcher.go HTTPS response getting MTU split somewhere in the networking stack from a recent version of Docker on Windows, whereas in previous versions of Docker on Windows it was not.

The fix was to extend the mbedtls example code I derived from in yojimbo_matcher.cpp so it properly handles responses that require multiple calls to mbedtls_ssl_read. This bug seem did not affect MacOS or Linux platforms, but if for some reason the HTTPS response was MTU split, it would have broken there too.

I also added a workaround on MacOS for the clock getting out of sync in the docker VM instance, which was causing client connects through matcher.go running in docker to fail to connect when pointed to a server instance outside of docker:

For example, the following sequence of commands worked:

premake5 matcher
premake5 docker           // run server on port 40000 inside docker
premake5 connect

Because both matcher and server were running inside docker with the same skewed clock, but the following sequence failed:

premake5 matcher
premake5 server           // run server on port 40000 *outside* docker
premake5 connect

because matcher.go generated connect tokens wrt. skewed time, which were then passed to a server running outside of docker (with correct, unskewed time), causing the server to deny these connection requests because they were stale (connect tokens are only valid for a short 30 second window...). I'm not 100% sure, but I suspect these issues are new with the latest MacOS Sierra release. I recently upgraded, and didn't notice any clock skew before this.

The solution in production environments is of course to always make sure your matcher and dedicated server instances are synced to the same time via NTP. For development on MacOS, I added the following workaround to sync up the docker VM clock to local time:

docker run --rm --privileged alpine hwclock -s

Which is described here:


Docker... sigh :)

@gafferongames gafferongames released this Aug 3, 2016 · 727 commits to master since this release

Assets 2

This release adds per-client silos for allocators, packet factories and message factories on the server. This is a security measure so a malicious client can exhaust only their own resources (leading to disconnection) and cannot affect resources for other clients. Previously, allocators and factories were shared by all clients on the server. This release also includes a bunch of fixes to get libyojimbo passing Coverity with zero defects. See this page for details.

@gafferongames gafferongames released this Jul 21, 2016 · 843 commits to master since this release

Assets 4

This release adds an example showing how to shim libyojimbo to your existing message format, use a connection without the client/server framework, and read write connection packets directly to memory buffers so you can handle sending and receiving packets yourself. See "simple_messages.cpp" for more details.

@gafferongames gafferongames released this Jul 18, 2016 · 865 commits to master since this release

Assets 4

This release fixes an issue where profile.cpp sometimes would not connect all clients. What was going on was that on some OS's (windows...) the default socket send and receive buffer sizes were so small that only packets from the first n clients would actually get through. Now SO_RCVBUF and SO_SNDBUF are each set to 1mb on socket create so this doesn't happen anymore. If you would like larger or smaller buffers, pass the value you want into the "bufferSize" parameter of the socket or socket transport constructor.