Issue information

Issue ID
#991
Status
Fixed
Severity
Critical
Started
Hercules Elf Bot
Feb 17, 2008 20:40
Last Post
Hercules Elf Bot
Feb 17, 2008 20:40
Confirmation
N/A

Hercules Elf Bot - Feb 17, 2008 20:40

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