Originally posted by [b]Slennox[/b]
http://www.eathena.ws/board/index.php?autocom=bugtracker&showbug=991
Recently upgraded to trunk 12212M and problems seem to have started... One crash after few hours, and another in just few minutes. I have the bt for this last one:
CODE
[Error]: clif_parse_WantToConnection: double login attempt AID/CID: 2000443/150366, rejecting...
[Info]: Closed connection from '84.122.64.137'.
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1208109376 (LWP 20773)]
0x0806232e in clif_authfail_fd (fd=-33686019, type=2) at clif.c:551
551 if (!fd || !session[fd] || session[fd]->func_parse != clif_parse) //clif_authfail should only be invoked on players!
(gdb) bt full
#0 0x0806232e in clif_authfail_fd (fd=-33686019, type=2) at clif.c:551
No locals.
#1 0x08052dc2 in chrif_disconnectplayer (fd=10) at chrif.c:878
sd = <value optimized out>
#2 0x0805438d in chrif_parse (fd=10) at chrif.c:1302
r = <value optimized out>
packet_len = 7
cmd = 11039
#3 0x0812f8e0 in do_sockets (next=50) at socket.c:823
rfd = {__fds_bits = {1024, 0 <repeats 31 times>}}
timeout = {tv_sec = 0, tv_usec = 9000}
ret = 0
i = <value optimized out>
#4 0x0812e3d6 in main (argc=1, argv=0xbf86ab04) at core.c:254
next = 2
The event that triggered the SEGFAULT seems the
[Error]: clif_parse_WantToConnection: double login attempt AID/CID: 2000443/150366, rejecting....
I've tried to reproduce the problem in a test server and the only way I have found to trigger that message is sending a WantToConnection packet directly to map-server for an already authenticated account ID. Because of that, I think someone is doing this on purpose. I've not been able to reproduce the crash though.
CODE
int chrif_disconnectplayer(int fd)
{
struct map_session_data* sd;
sd = map_id2sd(RFIFOL(fd, 2));
if(sd == NULL)
return -1;
if (!sd->fd)
{ //No connection
if (sd->state.autotrade)
map_quit(sd); //Remove it.
//Else we don't remove it because the char should have a timer to remove the player because it force-quit before,
//and we don't want them kicking their previous instance before the 10 secs penalty time passes. [Skotlex]
return 0;
}
switch(RFIFOB(fd, 6))
{
case 1: clif_authfail_fd(sd->fd, 1); break; //server closed
case 2: clif_authfail_fd(sd->fd, 2); break; //someone else logged in
case 3: clif_authfail_fd(sd->fd, 4); break; //server overpopulated
case 4: clif_authfail_fd(sd->fd, 10); break; //out of available time paid for
case 5: clif_authfail_fd(sd->fd, 15); break; //forced to dc by gm
}
return 0;
}
sd->fd got somewhow corrupted or filled with garbage in the context of fd=10 in chrif_disconnectplayer (), which seems the socket from we received the crafted WantToConnection packet. But how can this socket have a sd in the first place if it's not an authenticated client? Else, we would have returned in:
CODE
if(sd == NULL)
return -1;
It even bypasses this check:
CODE
if (!sd->fd)
{ //No connection
if (sd->state.autotrade)
map_quit(sd); //Remove it.
//Else we don't remove it because the char should have a timer to remove the player because it force-quit before,
//and we don't want them kicking their previous instance before the 10 secs penalty time passes. [Skotlex]
return 0;
}
If it's a socket with a sd, how has it got to there bypassing login-server & char-server? Maybe the culprit is map_id2sd(RFIFOL(fd, 2))?
I have reverted to trunk 121XX, which seem stable (2 weeks uptime)... and lets see.
Sle
This post has been edited by Slennox: Feb 17 2008, 04:47 PM