From a0fb6bc388fb1d4f0fcfd7d3d8af71a9c8cf86ca Mon Sep 17 00:00:00 2001 From: shennetsind Date: Wed, 31 Oct 2012 20:17:38 +0000 Subject: Fixed bugreport:6779 dropped between-server ping timers, replaced by a much more reliable and performance-efficient on-demand flagging. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16854 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/char/char.c | 43 +++++++++++++++++-------------------------- src/common/socket.c | 14 +++++++++++--- src/common/socket.h | 1 + src/map/chrif.c | 24 ++++++++++++------------ 4 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/char/char.c b/src/char/char.c index 09d8dbcc6..d7f7749c4 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -2032,31 +2032,38 @@ void loginif_on_ready(void) } -int parse_fromlogin(int fd) -{ +int parse_fromlogin(int fd) { struct char_session_data* sd = NULL; int i; // only process data from the login-server - if( fd != login_fd ) - { + if( fd != login_fd ) { ShowDebug("parse_fromlogin: Disconnecting invalid session #%d (is not the login-server)\n", fd); do_close(fd); return 0; } - if( session[fd]->flag.eof ) - { + if( session[fd]->flag.eof ) { do_close(fd); login_fd = -1; loginif_on_disconnect(); return 0; + } else if ( session[fd]->flag.ping ) {/* we've reached stall time */ + if( DIFF_TICK(last_tick, session[fd]->rdata_tick) > (stall_time * 2) ) {/* we can't wait any longer */ + set_eof(fd); + return 0; + } else if( session[fd]->flag.ping != 2 ) { /* we haven't sent ping out yet */ + WFIFOHEAD(fd,2);// sends a ping packet to login server (will receive pong 0x2718) + WFIFOW(fd,0) = 0x2719; + WFIFOSET(fd,2); + + session[fd]->flag.ping = 2; + } } sd = (struct char_session_data*)session[fd]->session_data; - while(RFIFOREST(fd) >= 2) - { + while(RFIFOREST(fd) >= 2) { uint16 command = RFIFOW(fd,0); switch( command ) @@ -2164,6 +2171,7 @@ int parse_fromlogin(int fd) if (RFIFOREST(fd) < 2) return 0; RFIFOSKIP(fd,2); + session[fd]->flag.ping = 0; break; // changesex reply @@ -2357,7 +2365,6 @@ int parse_fromlogin(int fd) } int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data); -int ping_login_server(int tid, unsigned int tick, int id, intptr_t data); int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data); void do_init_loginif(void) @@ -2365,11 +2372,7 @@ void do_init_loginif(void) // establish char-login connection if not present add_timer_func_list(check_connect_login_server, "check_connect_login_server"); add_timer_interval(gettick() + 1000, check_connect_login_server, 0, 0, 10 * 1000); - - // keep the char-login connection alive - add_timer_func_list(ping_login_server, "ping_login_server"); - add_timer_interval(gettick() + 1000, ping_login_server, 0, 0, ((int)stall_time-2) * 1000); - + // send a list of all online account IDs to login server add_timer_func_list(send_accounts_tologin, "send_accounts_tologin"); add_timer_interval(gettick() + 1000, send_accounts_tologin, 0, 0, 3600 * 1000); //Sync online accounts every hour @@ -4299,18 +4302,6 @@ int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data return 1; } -// sends a ping packet to login server (will receive pong 0x2718) -int ping_login_server(int tid, unsigned int tick, int id, intptr_t data) -{ - if (login_fd > 0 && session[login_fd] != NULL) - { - WFIFOHEAD(login_fd,2); - WFIFOW(login_fd,0) = 0x2719; - WFIFOSET(login_fd,2); - } - return 0; -} - //------------------------------------------------ //Invoked 15 seconds after mapif_disconnectplayer in case the map server doesn't //replies/disconnect the player we tried to kick. [Skotlex] diff --git a/src/common/socket.c b/src/common/socket.c index 3d7bb66b4..d24a9c1d8 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -797,8 +797,13 @@ int do_sockets(int next) continue; if (session[i]->rdata_tick && DIFF_TICK(last_tick, session[i]->rdata_tick) > stall_time) { - ShowInfo("Session #%d timed out\n", i); - set_eof(i); + if( session[i]->flag.server ) {/* server is special */ + if( session[i]->flag.ping != 2 )/* only update if necessary otherwise it'd resend the ping unnecessarily */ + session[i]->flag.ping = 1; + } else { + ShowInfo("Session #%d timed out\n", i); + set_eof(i); + } } session[i]->func_parse(i); @@ -1073,8 +1078,11 @@ int socket_config_read(const char* cfgName) if(sscanf(line, "%[^:]: %[^\r\n]", w1, w2) != 2) continue; - if (!strcmpi(w1, "stall_time")) + if (!strcmpi(w1, "stall_time")) { stall_time = atoi(w2); + if( stall_time < 3 ) + stall_time = 3;/* a minimum is required to refrain it from killing itself */ + } #ifndef MINICORE else if (!strcmpi(w1, "enable_ip_rules")) { ip_rules = config_switch(w2); diff --git a/src/common/socket.h b/src/common/socket.h index 3265f6487..7c0e02f5d 100644 --- a/src/common/socket.h +++ b/src/common/socket.h @@ -76,6 +76,7 @@ struct socket_data struct { unsigned char eof : 1; unsigned char server : 1; + unsigned char ping : 2; } flag; uint32 client_addr; // remote client address diff --git a/src/map/chrif.c b/src/map/chrif.c index 44a74d83a..e07313855 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -1363,7 +1363,9 @@ void chrif_keepalive(int fd) { WFIFOW(fd,0) = 0x2b23; WFIFOSET(fd,2); } - +void chrif_keepalive_ack(int fd) { + session[fd]->flag.ping = 0;/* reset ping state, we received a packet */ +} /*========================================== * *------------------------------------------*/ @@ -1382,6 +1384,14 @@ int chrif_parse(int fd) { char_fd = -1; chrif_on_disconnect(); return 0; + } else if ( session[fd]->flag.ping ) {/* we've reached stall time */ + if( DIFF_TICK(last_tick, session[fd]->rdata_tick) > (stall_time * 2) ) {/* we can't wait any longer */ + set_eof(fd); + return 0; + } else if( session[fd]->flag.ping != 2 ) { /* we haven't sent ping out yet */ + chrif_keepalive(fd); + session[fd]->flag.ping = 2; + } } while ( RFIFOREST(fd) >= 2 ) { @@ -1428,7 +1438,7 @@ int chrif_parse(int fd) { case 0x2b20: chrif_removemap(fd); break; case 0x2b21: chrif_save_ack(fd); break; case 0x2b22: chrif_updatefamelist_ack(fd); break; - case 0x2b24: /* chrif_keepalive_ack(fd) */ break; + case 0x2b24: chrif_keepalive_ack(fd); break; case 0x2b25: chrif_deadopt(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break; case 0x2b27: chrif_authfail(fd); break; default: @@ -1443,12 +1453,6 @@ int chrif_parse(int fd) { return 0; } -int ping_char_server(int tid, unsigned int tick, int id, intptr_t data) { - chrif_check(-1); - chrif_keepalive(char_fd); - return 0; -} - // unused int send_usercount_tochar(int tid, unsigned int tick, int id, intptr_t data) { chrif_check(-1); @@ -1604,15 +1608,11 @@ int do_init_chrif(void) { auth_db_ers = ers_new(sizeof(struct auth_node),"chrif.c::auth_db_ers",ERS_OPT_NONE); add_timer_func_list(check_connect_char_server, "check_connect_char_server"); - add_timer_func_list(ping_char_server, "ping_char_server"); add_timer_func_list(auth_db_cleanup, "auth_db_cleanup"); // establish map-char connection if not present add_timer_interval(gettick() + 1000, check_connect_char_server, 0, 0, 10 * 1000); - // keep the map-char connection alive - add_timer_interval(gettick() + 1000, ping_char_server, 0, 0, ((int)stall_time-2) * 1000); - // wipe stale data for timed-out client connection requests add_timer_interval(gettick() + 1000, auth_db_cleanup, 0, 0, 30 * 1000); -- cgit v1.2.3-60-g2f50