[Freeciv-Dev] Re: (PR#15098) Re: civserver crash in calc_unit_ordering
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=15098 >
ok, solved. This was by far the hardest bug that I've tracked down.
Here's what has to happen for this bug to occur:
1. quitidle must be set. also auth must be enabled. also, I believe that
quit on end must be set too. :)
2. a new user (not in database) logs in and sets a new password
3. other users (not new) log in.
4. the new user must attempt to start the game. (via /start)
5. all the other users must not try to start the game yet (they must wait
at least 300 seconds). I don't think the crash will happen if they do.
6. The bug happens: The new user is disconnected. He is rejected for a
timeout in entering a password. The problem is that the connection has
already been established, and the player was created. The player is not
removed. Nutshell: pconn->server.status didn't get updated like it shoulda.
7. The last user who hasn't hit start does so. The game starts, and all get
a nation selection popup, including the player who has no connection.
So the game stays in SELECT_RACES_STATE
8. Everybody gets bored, because they're waiting on a non-existent player,
and quits,
9. The quitidle gets triggered.
10. Server attempted to save the game, but no map has been created, so
there is a crash.
There may be slightly different paths to this crash, but these are the
essentials.
trunk is vulnerable too, but not in the same way. Different crashes occur
since there is no SELECT_RACES_STATE anymore.
Here's the patch: I'll commit this immediately.
-mike
Index: server/connecthand.c
===================================================================
--- server/connecthand.c (revision 11497)
+++ server/connecthand.c (working copy)
@@ -70,6 +70,7 @@
/* "establish" the connection */
pconn->established = TRUE;
+ pconn->server.status = AS_ESTABLISHED;
conn_list_append(game.est_connections, pconn);
Index: server/auth.c
===================================================================
--- server/auth.c (revision 11497)
+++ server/auth.c (working copy)
@@ -246,7 +246,6 @@
establish_new_connection(pconn);
} else if (pconn->server.status == AS_REQUESTING_OLD_PASS) {
if (authdb_check_password(pconn, password, strlen(password)) == 1) {
- pconn->server.status = AS_ESTABLISHED;
establish_new_connection(pconn);
} else {
pconn->server.status = AS_FAILED;
|
|