Change login command kill to kill less ruthlessly
The victim's connection closes without any explanation. Output may be lost. This is because kill_cmd() kills by calling io_shutdown(), which shuts down the socket and drains the I/O queues. How this makes the victim's thread terminate is a bit subtle: shutting down the socket makes it ready. If the victim's thread is waiting for I/O, it wakes up. Since all further reads return EOF, and all further writes fail, the command terminates quickly (short of inifinite loop bugs), then the command loop, and finally the thread. To make kill behave more nicely, change kill_cmd() to work exactly like server shutdown: send a flash message to the victim, set his EOF indicator, abort the command, forbid sleeping on I/O, wake up the victim's thread. Just as reliable, but doesn't lose output. If the victim's client fails to close his connection, the victim's thread may still linger in state PS_SHUTDOWN for up to login_grace_time (default 120s). An attacker could try to use that to make the server run out of file descriptors or memory, but simply connecting achieves the same effect more cheaply.
This commit is contained in:
parent
918f3ec6ae
commit
eb25be08d4
1 changed files with 6 additions and 2 deletions
|
@ -381,8 +381,12 @@ kill_cmd(void)
|
||||||
return RET_FAIL;
|
return RET_FAIL;
|
||||||
}
|
}
|
||||||
logerror("%s killed country #%d", praddr(player), player->cnum);
|
logerror("%s killed country #%d", praddr(player), player->cnum);
|
||||||
io_shutdown(other->iop, IO_READ | IO_WRITE);
|
pr_flash(other, "Disconnected by %s\n", praddr(player));
|
||||||
pr_id(player, C_EXIT, "closed socket of offending job\n");
|
io_set_eof(other->iop);
|
||||||
|
other->aborted = 1;
|
||||||
|
other->may_sleep = PLAYER_SLEEP_NEVER;
|
||||||
|
empth_wakeup(other->proc);
|
||||||
|
pr_id(player, C_EXIT, "terminated %s's connection\n", praddr(other));
|
||||||
return RET_OK;
|
return RET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue