Ver Fonte

update

git-svn-id: https://svn.code.sf.net/p/rathena/svn/branches/stable@924 54d463be-8e91-2dee-dedb-b68131a5f0ec
amber há 20 anos atrás
pai
commit
f68c8a4805
11 ficheiros alterados com 43 adições e 46 exclusões
  1. 15 0
      Changelog.txt
  2. 3 0
      conf-tmpl/login_athena.conf
  3. 2 0
      src/common/core.c
  4. 11 3
      src/common/socket.c
  5. 6 0
      src/common/socket.h
  6. 0 5
      src/map/clif.c
  7. 2 6
      src/map/map.c
  8. 0 1
      src/map/map.h
  9. 1 1
      src/map/party.c
  10. 3 27
      src/map/pc.c
  11. 0 3
      src/map/pc.h

+ 15 - 0
Changelog.txt

@@ -1,4 +1,19 @@
 Date	Added
+01/06
+	* Fixed typo in src/map/map.c causing compile 
+	  errors (SVN 924) [MouseJstr]
+	* Removed the alive_timer mechanism entirly replaced with
+	  a stall detection mechanism that will disconnect a player
+	  who has not sent any data for a configurable 
+	  (conf/login_athena.conf:stall_time) amount of time.  The default
+	  is currently 60 seconds.
+
+	  The root cause of the disconnect error is that some NAT based
+	  routers are not dropping the TCP connection when the aliased
+	  machine goes offline abnormally.   This means that we are seeing
+	  a stalled but perfectly valid TCP connection.
+
+	  (SVN 924) [MouseJstr]
 01/05
 	* Fixed some typos in map_versionscreen() [MC Cameri]
 	* Removed loop freeing in map-server's do_final(), it was causing seg faults [MC Cameri]

+ 3 - 0
conf-tmpl/login_athena.conf

@@ -151,4 +151,7 @@ flush_on: 0
 // How often to flush the buffer in Mugendai's GUI
 flush_time: 60
 
+// How long can a socket stall before closing the connection
+stall_time: 60
+
 import: conf/import/login_conf.txt

+ 2 - 0
src/common/core.c

@@ -169,6 +169,8 @@ int main(int argc,char **argv)
 
 	display_title();
 
+	tick_ = time(0);
+
 	do_init(argc,argv);
 	while(runflag){
 		next=do_timer(gettick_nocache());

+ 11 - 3
src/common/socket.c

@@ -37,6 +37,8 @@
 
 fd_set readfds;
 int fd_max;
+time_t tick_;
+time_t stall_time_ = 60;
 
 int rfifo_size = 65536;
 int wfifo_size = 65536;
@@ -106,6 +108,7 @@ static int recv_to_fifo(int fd)
 	//{ int i; printf("recv %d : ",fd); for(i=0;i<len;i++){ printf("%02x ",RFIFOB(fd,session[fd]->rdata_size+i)); } printf("\n");}
 	if(len>0){
 		session[fd]->rdata_size+=len;
+		session[fd]->rdata_tick = tick_;
 	} else if(len<=0){
 		// value of connection is not necessary the same
 //		printf("set eof : connection #%d\n", fd);
@@ -209,6 +212,7 @@ static int connect_client(int listen_fd)
 	session[fd]->func_send   = send_from_fifo;
 	session[fd]->func_parse  = default_func_parse;
 	session[fd]->client_addr = client_address;
+	session[fd]->rdata_tick = tick_;
 
   //printf("new_session : %d %d\n",fd,session[fd]->eof);
 	return fd;
@@ -347,6 +351,7 @@ int make_connection(long ip,int port)
 	session[fd]->func_recv  = recv_to_fifo;
 	session[fd]->func_send  = send_from_fifo;
 	session[fd]->func_parse = default_func_parse;
+	session[fd]->rdata_tick = tick_;
 
 	return fd;
 }
@@ -407,7 +412,10 @@ int do_sendrecv(int next)
 	struct timeval timeout;
 	int ret,i;
 
-	rfd=readfds;
+	tick_ = time(0);
+
+	memcpy(&rfd, &readfds, sizeof(rfd));
+
 	FD_ZERO(&wfd);
 	for(i=0;i<fd_max;i++){
 		if(!session[i] && FD_ISSET(i,&readfds)){
@@ -431,13 +439,11 @@ int do_sendrecv(int next)
 		if(FD_ISSET(i,&wfd)){
 			//printf("write:%d\n",i);
 			if(session[i]->func_send)
-			    //send_from_fifo(i);
 				session[i]->func_send(i);
 		}
 		if(FD_ISSET(i,&rfd)){
 			//printf("read:%d\n",i);
 			if(session[i]->func_recv)
-			    //recv_to_fifo(i);
 				session[i]->func_recv(i);
 		}
 	}
@@ -450,6 +456,8 @@ int do_parsepacket(void)
 	for(i=0;i<fd_max;i++){
 		if(!session[i])
 			continue;
+		if ((session[i]->rdata_tick != 0) && ((tick_ - session[i]->rdata_tick) > stall_time_)) 
+			session[i]->eof = 1;
 		if(session[i]->rdata_size==0 && session[i]->eof==0)
 			continue;
 		if(session[i]->func_parse){

+ 6 - 0
src/common/socket.h

@@ -12,8 +12,13 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #endif
+#include <time.h>
+
 #include "malloc.h"
 
+extern time_t tick_;
+extern time_t stall_time_;
+
 // define declaration
 
 #define RFIFOP(fd,pos) (session[fd]->rdata+session[fd]->rdata_pos+(pos))
@@ -55,6 +60,7 @@ struct socket_data{
 	unsigned char *rdata,*wdata;
 	int max_rdata,max_wdata;
 	int rdata_size,wdata_size;
+	time_t rdata_tick;
 	int rdata_pos;
 	struct sockaddr_in client_addr;
 	int (*func_recv)(int);

+ 0 - 5
src/map/clif.c

@@ -7545,11 +7545,6 @@ void clif_parse_TickSend(int fd, struct map_session_data *sd) {
 		break;
 	}
 
-	//double connection bug fix by Valaris
-	if(sd->alive_timer > 0) 
-		delete_timer(sd->alive_timer,pc_alive_timer);
-	sd->alive_timer=add_timer(gettick()+60*1000,pc_alive_timer,sd->bl.id,0);
-
 	sd->server_tick = gettick();
 	clif_servertick(sd);
 }

+ 2 - 6
src/map/map.c

@@ -1051,12 +1051,6 @@ int map_quit(struct map_session_data *sd) {
 	storage_storage_dirty(sd);
 	storage_storage_save(sd);
 
-	//double connect bug fix by Valaris
-	if(sd->alive_timer > 0) {
-		delete_timer(sd->alive_timer,pc_alive_timer);
-		sd->alive_timer = -1;	// not 0, the server will assume it's still active
-	}
-
 	if( sd->npc_stackbuf && sd->npc_stackbuf != NULL) {
 		free( sd->npc_stackbuf );
 		sd->npc_stackbuf = NULL;
@@ -2440,6 +2434,8 @@ int sql_config_read(char *cfgName)
 			strcpy(login_server_pw, w2);
 		} else if(strcmpi(w1,"login_server_db")==0){
 			strcpy(login_server_db, w2);
+		} else if(strcmpi(w1,"stall_time")==0){
+			stall_time_ = atoi(w2);
 		} else if(strcmpi(w1,"lowest_gm_level")==0){
 			lowest_gm_level = atoi(w2);
 		} else if(strcmpi(w1,"read_gm_interval")==0){

+ 0 - 1
src/map/map.h

@@ -332,7 +332,6 @@ struct map_session_data {
 	int last_skillid,last_skilllv;		// Added by RoVeRT
 	
 	unsigned char change_level; // [celest]
-        int alive_timer; //[Valaris]
 
 #ifndef TXT_ONLY
 	int mail_counter;	// mail counter for mail system [Valaris]

+ 1 - 1
src/map/party.c

@@ -591,7 +591,7 @@ int party_exp_share(struct party *p,int map,int base_exp,int job_exp,int zeny)
 		return 0;
 	for(i=0;i<MAX_PARTY;i++)
 		if((sd=p->member[i].sd)!=NULL && sd->bl.m==map && session[sd->fd] != NULL) {
-			if (/* pc_issit(sd) || */ sd->chatID || (sd->idletime < (time(0) - 120)))
+			if (/* pc_issit(sd) || */ sd->chatID || (sd->idletime < (tick_ - 120)))
 				continue;
 #ifdef TWILIGHT
 			pc_gainexp(sd,base_exp,job_exp);

+ 3 - 27
src/map/pc.c

@@ -4016,11 +4016,6 @@ int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrt
 //	map_addblock(&sd->bl);	/// ブロック登?とspawnは
 //	clif_spawnpc(sd);
 
-	//double connection bug fix by Valaris
-	if(sd->alive_timer > 0) 
-		delete_timer(sd->alive_timer,pc_alive_timer);
-	sd->alive_timer=add_timer(gettick()+60*1000,pc_alive_timer,sd->bl.id,0);
-
 	return 0;
 }
 
@@ -4323,7 +4318,7 @@ int pc_walktoxy(struct map_session_data *sd,int x,int y)
 
 	sd->to_x=x;
 	sd->to_y=y;
-	sd->idletime = time(0);
+	sd->idletime = tick_;
 
 	if(sd->walktimer != -1 && sd->state.change_walk_target==0){
 		// 現在?いている最中の目的地?更なのでマス目の中心に?た暫ノ
@@ -4652,7 +4647,7 @@ int pc_attack_timer(int tid,unsigned int tick,int id,int data)
 	if(sd == NULL)
 		return 0;
 
-	sd->idletime = time(0);
+	sd->idletime = tick_;
 
 	if(sd->attacktimer != tid){
 		if(battle_config.error_log)
@@ -4773,7 +4768,7 @@ int pc_attack(struct map_session_data *sd,int target_id,int type)
 	if(bl==NULL)
 		return 1;
 
-	sd->idletime = time(0);
+	sd->idletime = tick_;
 	
 	if(bl->type==BL_NPC) { // monster npcs [Valaris]
 		//npc_click(sd,RFIFOL(sd->fd,2));
@@ -7894,24 +7889,6 @@ int map_night_timer(int tid, unsigned int tick, int id, int data) { // by [yor]
 	return 0;
 }
 
-/*==========================================
- * I'm alive timer (to prevent double connect bug) by Valaris
- *------------------------------------------
- */
-int pc_alive_timer(int tid,unsigned int tick,int id,int data)
-{
-	//struct map_session_data *sd=(struct map_session_data*)map_id2bl(id);
-	struct map_session_data *sd=map_id2sd(id); // more accurate [celest]
-	nullpo_retr(0, sd);
-	if(sd->alive_timer != tid)
-		return 0;
-	sd->alive_timer = -1;
-//	map_quit(sd);
-	clif_timedout (sd);
-
-	return 0;
-}
-
 void pc_setstand(struct map_session_data *sd){
 	nullpo_retv(sd);
 
@@ -8308,7 +8285,6 @@ int do_init_pc(void) {
 	// add night/day timer (by [yor])
 	add_timer_func_list(map_day_timer, "map_day_timer"); // by [yor]
 	add_timer_func_list(map_night_timer, "map_night_timer"); // by [yor]
-	add_timer_func_list(pc_alive_timer, "pc_alive_timer"); //by Valaris
 	{
 		int day_duration = battle_config.day_duration;
 		int night_duration = battle_config.night_duration;

+ 0 - 3
src/map/pc.h

@@ -200,8 +200,5 @@ extern int night_timer_tid;
 int map_day_timer(int,unsigned int,int,int); // by [yor]
 int map_night_timer(int,unsigned int,int,int); // by [yor]
 
-//double connect bug fix
-int pc_alive_timer(int tid,unsigned int tick,int,int);
-
 #endif