Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 03 Jun 2003
Online Last Active Today, 11:58 AM

#5194626 creating basic lobby services

Posted by hplus0603 on 25 November 2014 - 10:48 AM

Would you say this is not sufficient and you'd still go for TSL/HTTPS?

With TLS/HTTPS, the hacker can get the password of one user by exploiting faults in the protocols (which have been more common than previously thought.)

With challenge signature, the hacker can't get the password that way, but can get the password of many players if they break your server (which also seems to happen more than previously thought.)

Previously, I used to think that a competent operations team could keep an encrypted password database from falling in the wrong hands, but these days, I'm just not sure --- both problems have happened with alarming frequency the last few years.

#5194507 creating basic lobby services

Posted by hplus0603 on 24 November 2014 - 06:19 PM

client connects to login server
login server sends random challenge number to client
client computes hash of challenge combined with a user supplied password and also sends a login name
login server looks up client by login name, de-hashes stored password using "server secret" and rehashes the sent challenge + stored (now unhashed) password and compares to hash client sent.

This will work, although it requires that the server be able to decrypt the passwords.
That may be okay for a game, but is generally not a good idea, in case your server database gets somehow broken.
Making it hard for an attacker to get the actual password, such as using a specially hardened en/de-crypt server that's not visible to the external network, may help.
These days, I'd probably instead prefer to use TLS or HTTPS to provide plaintext name and password to the server, and the server hashes that plaintext password using bcrypt to compare to stored-in-database hashed-password. (This is safe as long as TLS / HTTPS is safe.)
An attacker can then only get the passwords that are in flight during the time of attack, rather than all the passwords.

if password okay, login server generates an authentication ID, stores it on the sql server and sends client a ticket with their auth id, their user id and IP of server to connect to (could do load balancing here by smartly choosing different server ips?)

I would probably send a ticket that consists of:
This lets the lobby server verify the ticket (time+userid) without connecting back to the server, assuming lobby server and main server have the same clock and secret.

client disconnects from login server and connects to new ip given for lobby server
lobby server asks for user id and authentication token
client sends requested information

You can just have the client provide the information in its connection -- no need to "ask" for it. That's an efficiency thing, not a security thing.

Periodically lobby server should request auth token from client

Player could just provide the ticket every 30 seconds or whatever without any "request." You'd simply have a timer for how long ago a valid ticket was provided to the server, and disconnect any client that hasn't provided a valid ticket in X amount of time. Again, simplicity, but not a security thing.

My main concern is whether just accepting commands from the client after an auth token has been confirmed as valid and then occasionally checking that whatever is talking still has the valid auth token is sufficient runtime security

What attacks are you trying to guard against?

Most script kiddies on the internet (including game hackers) do not have the ability to receive data sent to a specific IP address. They can spoof the source IP address of some packet that's sent, but they won't see the return of that. Thus, once established, the periodic ticket sending is not particularly necessary.

Another option: You can provide an encryption key to the client when it first connects. The client can then encrypt each packet with that key. (Make sure to prefix each packet with a sufficiently long sufficiently random nonce!) The server can then tell that the client was the one that originally connected (or could originally receive the connect message) because the packet decrypts correctly.

Another option: You can use TLS. (Which means you can't do UDP NAT punch-through.)

#5194443 Unit movement synchronization in fast paced games

Posted by hplus0603 on 24 November 2014 - 10:32 AM

with like 200 ms latency, the game is unplayable.

Diablo would be totally playable with 200 ms latency, so you must be doing something different.

Note that some pretty high-end games, like Guild Wars, seem to be doing it this way. When the internet (or the server) is slow, actions take a significant amount of time to take effect.

So what bandwidth should I aim for? What's the limit?

I can't answer that question without more information. What kinds of users are you aiming for? Do people play over mobile networks? Are you aiming only for the inner cities of Korea and Japan? Should it work fine over Hughes Satellite with 1.6 second downstream latency, and 56 kbps modem upstream?
Will your users also do other things in the household, like calling on a VoIP phone, or watching Netflix, or sharing files with Bittorrent?

#5194295 IOCP critical section design problem

Posted by hplus0603 on 23 November 2014 - 12:06 PM

Your design, as described, will lead to deadlock.

There are several design solutions to deadlock described in typical undergraduate literature -- check a good textbook like Tannenbaum/Woodhull or similar.

In brief, there are three options:

1) Define a strict ordering for your locks such that to hold lock B, you must always first hold lock A. (Or alternatively, to hold lock a, you must never hold lock B.) This means that threads will be blocked on the earlier shared lock in the operation, and thus won't dead lock -- just wait.

2) Use a deadlock detection algorithm. This is easier in the case of, for example, file locking, or database row locking, but can also be done in mutex locking. Apply some deadlock-breaking solution when a deadlock is detected; for example throwing an error and failing one of the two deadlocking threads, letting the other thread continue.

3) Only hold locks for very short time intervals (to protect mutable data structures) and use some other mechanism to serialize order-of-events. For example, change user mutation to a messaging system -- each user has an incoming queue of messages, and those messages are processed in order. If user A wants to affect user B, post a message to user B, rather than lock the data structure.

#5193984 creating basic lobby services

Posted by hplus0603 on 21 November 2014 - 10:13 AM

facilitating NAT punch-through. This could all be done as a RESTful service.

NAT punch-through does not work over REST because of the low-level networking details involved -- basic NAT actually uses UDP! Even TCP NAT cannot be done REST-fully, because it relies on persistent connections and re-using local port numbers.

Game matchmaking CAN be done REST-fully, assuming that you're OK doing long-waiting on a match. I e, the client would issue a HTTP request for a game match, and the server wouldn't return the match until a match was actually made, stalling the request 1-20 seconds while searching.
The reason you don't want to do multiple REST requests for matchmaking, is that you'd run into situations like this:
1) client issues REST request to "put me into the queue"
2) client's supposed to poll every so often for "did I find something"
3) clients queue entry gets match to a game
4) however, client shut down, and server doesn't know about it, so other players are matched with a zombie player

Matchmaking is not a great match to the REST model. It's real-time data -- it's not cacheable. REST works best when data has some amount of cacheability lifetime.

#5193983 Unit movement synchronization in fast paced games

Posted by hplus0603 on 21 November 2014 - 10:09 AM

You can save/send/sync unit locations every 200 milliseconds and it will look fine. 200 milliseconds is very little time for a "clicky" game and is still quite playable for a controller-FPS game like HALO. Only the twitchiest of shooters (Unreal Tournament, etc) would be bothered by 200 ms.

I would not predict anything -- I'd run everything in the past. This means that the player character itself would also run in the past. The reason being:
1) I click where to go
2) packet makes it to server
3) server starts moving my character
4) position/velocity update makes it to my client
5) I see my character start to move

This is similar to the RTS game networking principle.

what's the ideal bandwidth usage for an ARPG?

If you have deterministic simulation, and basically run the RPG like a RTS game, the bandwidth usage would be less than a kilobyte per second or less. All you need to send is initiating events like user clicks, time stamped, and initial entity spawn events. The simulation (including AI) would then run the same on all the machines. Note that this model *requires* the command delay that is outlined above. A good article for that model is here: http://www.gamasutra.com/view/feature/131503/1500_archers_on_a_288_network_.php

If you do not have a deterministic simulation (and chances are, you won't,) then each entity would have to update position/orientation/velocity/goal at some frequency, and you'd multiply the size-of-update by number-of-entities to get the bandwidth used, after adding protocol/framing/packet overhead. Twenty units, times 32 byte updates each, times 10 updates per second, would cost about 10 kB/second with those overheads included.

#5193852 creating basic lobby services

Posted by hplus0603 on 20 November 2014 - 01:43 PM

cloud computing where an application can scale and be granted (or removed) extra resources as and when required

Note that your application will not scale across hosts in the cloud unless you explicitly build it to be federated. Is that a goal of yours? Federated matchmaking is really, really, hard. And not needed for any game you're likely to create on your own :-)

do you possibly have any links to useful articles on it

I wrote a chapter in one of the Game Programming Gems books about it.
A web page variant of that chapter is here: http://www.mindcontrol.org/~hplus/authentication.html

#5193851 Unit movement synchronization in fast paced games

Posted by hplus0603 on 20 November 2014 - 01:38 PM

First of all: "Just add networked multiplayer" is a little bit like "just add a baby to this couple" -- it actually changes EVERYTHING.

Second, if the game wasn't built for multiplayer, the best you can probably do without TOTALLY re-architecting everything would be to treat one game instance as the server, and have the commands from the other clients go to the server to be executed. Then, the server continually sends the state/reactions of all the units to the clients, and the clients are all passive viewers of the world state. This introduces latency for the players who are on clients, but that's a small price to pay for a method of networking that is actually possible to add to an existing game without total re-architecting.

Note that you'd still need to re-architect the UI -- instead of directly applying to objects, it would have to send requests to apply to entities, and the actual display updates would have to happen when the updated data arrives from the server.

You cannot use input-only synchronization with Unity -- it does not use a deterministic simulation engine. Your best bet is to just send "position/velocity/animation" data for each entity with significant frequency. Maybe more frequent for player characters than monsters. Then just interpolate those entities along the known path on the viewing clients -- don't attempt to do path finding.

#5193823 creating basic lobby services

Posted by hplus0603 on 20 November 2014 - 11:08 AM

Do you want a single server process to be able to handle a multitude of games? If so, each request would need to have a game identifier. It might be simpler to say that you run a different service (on a different port/host) for each different game.

Typically, you'll want login information to go with lobbying. I e, if a user says "I'm Britney Spears," you have to make sure that that user is, in fact, uniquely registered as Britney Spears; typically using a password. And, once passwords/logins are involved, you either get into sophisticated key exchange schemes (which are harder over UDP,) or you end up first establishing a session key using TLS/HTTPS, and then verifying that key once provided on the UDP session. I recommend the latter :-)

So, you'd want some service that accepts username-and-password, and provides session-key. That service also accepts username-and-session-key and returns "yes" or "no" (for use by the lobby.) Alternatively, the session key can contain the user name and a signature using a shared secret with the lobby server.

The lobby then accepts username-and-session-key, and then accepts host-game-parameters or find-game-parameters, and provides updates to the client based on whether matches are found. A nice variation is if the client provides general-game-parameters, and the lobby server first finds someone hosting; if not found, it turns the client into a host, and makes it wait for other clients -- that way, a player doesn't have to decide whether to be host or client. When the wire protocol tells the client whether to host or be client, you can then later make "smarter" decisions on who hosts (based on reputation, networking, payment plans, etc) without changing the client software.

Additionally, you'll probably want the lobby server to provide NAT punch-through introduction services.

Finally, you want a log of things-that-happened to come out of both the session server and the lobby server. That way, you can debug and audit the operation of the system.

#5193621 How to estimate latency in one direction only

Posted by hplus0603 on 19 November 2014 - 10:12 AM

It depends on what sort of game you're making and what exactly you're trying to do with it. Motion prediction and other anti-lag features for fast-motion real-time gaming (which Abraham did say he was trying to do) do very much require knowing precise timestamps to do properly.

Yes -- you need high resolution in time stamps. The highest resolution for most fixed-step engines is the physics step/tick count. Some engines (like Unreal) use variable step size, which is bad for physics stability, and also makes ticks happen at different times on different clients, so those engines need high-resolution time stamps in fractional seconds instead. I much recommend fixed tick size!

Trying to get the wall-clock-time to be the same for the same simulation-step-time for all players at the same time, adds no value, and requires expensive hardware. Not to mention that "same time" literally becomes relative at a global scale -- speed of light becomes a factor even in defining what "same time" means! Who's reference frame? All the lag compensation techniques are basically just ways to deal with this, although the real-observed delay is an order of magnitude higher than the speed-of-light best case.

#5193492 How to estimate latency in one direction only

Posted by hplus0603 on 18 November 2014 - 01:12 PM

Short of shipping a precise GPS-based time source with each copy of your game, there's no good way to get one-way latency :-)

Note that what matters is that all players see the same events in the same sequence/order -- not the exact time at which they see the events. You need a monotonic clock for your simulation, but the clocks don't actually need to be exactly in sync, and trying to make them in sync is hard, and gives no extra value.

#5193489 Issue With Simple Client To Server Chat Program

Posted by hplus0603 on 18 November 2014 - 01:10 PM

UDP broadcast will not work across the internet.
The way to "broadcast" a message is to enqueue a copy of the message to each of the connected clients.

#5193455 Issue With Simple Client To Server Chat Program

Posted by hplus0603 on 18 November 2014 - 10:34 AM

SOCKET local_socket = *( (SOCKET *)&Parameter );

Try this:

SOCKET local_socket = *(reinterpret_cast<SOCKET *>(&Parameter));

That's no better than the previous code (which also would work, just like this.) What you really want is this:

SOCKET local_socket = (SOCKET)Parameter;
There is no reason to take the address of the value just to derefenrece it again.
In fact, if sizeof(Parameter) > sizeof(SOCKET), the initial address-based casts may fail, whereas the plain value cast will succeed.

#5192675 Cloud Architecture/Port problem

Posted by hplus0603 on 13 November 2014 - 11:18 AM

Is that what you're saying?


once the lobby creates a game it shouldn't be involved again.

Your previous quesiton was this:

if all communication is to one port then why use a Game ID?

Your later example uses a different port per game instance.

#5192563 Cloud Architecture/Port problem

Posted by hplus0603 on 12 November 2014 - 08:33 PM

if all communication is to one port then why use a Game ID?

Two reasons:

1) If you don't want to forward the ip:port of each player from the lobby server to the game instance server, you can match up incoming packets from players to the right game session using this ID when the first packet comes in.

2) Some ISPs and/or NAT situations are said to sometimes change the visible IP:port of remote players. If you include the game ID (and a game-specific player ID, equally random-and-hard-to-guess,) then the player session can survive even if the remote IP:port suddenly changes. (This will also happen for roaming devices like phones, laptops being carried around, etc.)