Information Security Stack Exchange is a question and answer site for information security professionals. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am working on a multiplayer game. I intended for all data to be exchanged over HTTPS, but it is way too slow. High latency networks take over a second for SSL handshake. While the game is turn-based and does not require blazing-fast data transfer, 1000-2000 ms ping is still unacceptable.

What protocols/approaches can I use to transfer data securely, with as low latency as possible?


Edit: Just to respond to your enquiries about the payload, here is what the result of a unit attacking an enemy building (obviously I'm not sending a string of ones and zeros, this is just a binary representation):

00000000 10010011 01010001 00100011 01011100 01010001 01010000

Message breakdown:

00000000  client's request executed with status "OK", other values correspond to specific error messages.

10        Object is owned by Player 2
010       Object is a building
0110      Object is located at x=6  (always 0<=x<=14)
101       Object is located at y=5  (always 0<=y<=6), owner and location is sufficient to describe any object uniquely
0001      1 byte-worth of modified attributes follows
0010 0011 Object's health is now 3

01        Object is owned by Player 1
011       Object is a unit
1000      Object is located at x=8
101       Object is located at y=5
0001      1 byte-worth of modified attributes follows
0101 0000 This object can no longer move/attack this turn

I don't think that I can get any more data density without making it expensive on the CPU.

share|improve this question
10  
HTTPS needs 2 round trips for a full handshake. And 1 round trip for resumption. Both should be well below half a second in most settings. I don't think this should get you into 2 second territory. Further reading: istlsfastyet.com – StackzOfZtuff Jan 15 at 13:00
2  
@StackzOfZtuff Networks like mobile Edge (which I am currently on) can take well over 2 seconds to handle a single GET request. – Mirac7 Jan 15 at 13:20
3  
Don't know much about it, but maybe websockets? You can use websockets over ssl – chue x Jan 15 at 17:02
24  
And, as both Phillip and Steffan point out, you shouldn't need to do a handshake on each exchange. If that's what is happening, you are probably closing the session after each exchange. If so, you should consider fixing that before moving to something else as well as consider how your payloads are encoded (see comment above.) – JimmyJames Jan 15 at 17:43
2  
@StackzOfZtuff HTTPS uses TCP connection coterminous with TLS connection (vs e.g. IMAP STARTTLS or FTP AUTH TLS) so it's 1 RT for TCP-SYN plus 1 for TLS-abbreviated or at least 2 for TLS-full: more than 2 if server first flight (mostly cert chain) exceeds the initial congestion window and it usually does. – dave_thompson_085 Jan 15 at 23:37
up vote 45 down vote accepted

HTTPS is HTTP over TLS.

If you implement a game, using HTTP is usually not a good idea. The HTTP protocol is designed for requesting documents, not for real-time games. A better idea would be to develop your own protocol directly based on TCP or UDP (UDP is faster while TCP is easier to use, but that's a topic for game development stackexchange) and tunnel it through TLS.

The time-consuming key exchange process only needs to happen once when establishing the connection. When you keep the same connection open during the game, the only latency overhead is caused by encryption and decryption. TLS supports multiple cipher suites (sets of cryptographic algorithms which are used). The choice of cipher suite can be used to find a compromise between performance and security.  

share|improve this answer
24  
Or just use WebSockets, over a wss:// URL. StackOverflow's chat uses this to communicate. – Ismael Miguel Jan 15 at 17:04
1  
The nice thing about rolling your own protocol (other than that it's not insanely slow) is that you don't have to restrict yourself to one option. If you want to accept a direct TCP connection, or a websocket, both with and without TLS, you can do that, and some games (eg Furcadia) do that. This has the disadvantage that a MitM attack could downgrade the connection, but the upside that legacy clients can still connect on the same ports, for now, and the ability to connect unencrypted can be deprecated and eventually phased out, without any players having to change what port they allow out. – Dewi Morgan Jan 16 at 1:42
2  
You can also explicitly permit downgraded clients for 3rd party apps, bots and proxies, but in return add extra security constraints ingame. This allows players to easily script 3rd party utils, and makes the downgrade a conscious and visible choice. – Dewi Morgan Jan 16 at 1:48
2  
It is not always true that UDP is faster. If you have specific needs that TCP cannot satisfy, and you know what you are doing, then UDP may be faster. With UDP it is easy to introduce amplification vulnerabilities. Those can be very hard to fix after the fact and once attackers find them you can quickly lose any performance benefit you may have gained from using UDP in the first place. – kasperd Jan 16 at 19:37
1  
"A better idea would be to develop your own protocol" -- and that on this site! No, there's probably a library in whatever language they are using for socket communication, and all levels of abstraction upwards. – Raphael Jan 17 at 13:43

High latency networks take over a second for SSL handshake

There should be no need to do a full handshake for each message exchange. The handshake is only needed at start of the TCP connection, thus just leave the connection open. Then the latency is what you have with any other established TCP connection. If you need even less latency at the cost of possible packet loss or duplication use DTLS, i.e. TLS with datagrams (UDP).

Apart from that HTTP(s) might not be the optimal protocol for use on high latency and low bandwidth connections. The encapsulation of the payload in HTTP request and response alone has a non-trivial overhead (depending on the amount of payload) and if you the often used text based payload (i.e. JSON, XML or similar) only adds more overhead. Binary based data exchange (like protobuf or similar) makes much better use of the available resources.

share|improve this answer
1  
+1. I would add that slow TLS (e.g. HTTPS) connection times are often due to one end or the other being out of entropy, which is a limited resource in many environments. This is another reason to prefer long lived connections as Steffen suggests, and remember WSS a viable alternative if you need to asynchronously send data to the client (as opposed to work on a strictly request/reply model). – abligh Jan 17 at 17:29

If you want a connection based on TCP, use TLS. Set up the connection in advance, so you pay the 2 RTT latency once and then never need pay it again. You can use the SPDY extension if you want to reduce the one-time up-front latency cost of initially establishing the connection.

If you want a connection based on UDP, use DTLS. This may reduce even more latency, by eliminating TCP's re-transmissions and other things TCP does that can introduce latency in certain circumstances. Once again, set up the connection in advance, so you pay the 2 RTT latency once and then never need pay it again.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.