فهرست منبع

adding guard for polling loop to prevent CPU exhastion in the case of system misbihavior

z3APA3A 5 سال پیش
والد
کامیت
637cb2e76d
3فایلهای تغییر یافته به همراه27 افزوده شده و 14 حذف شده
  1. 6 6
      doc/html/howtoe.html
  2. 3 3
      doc/html/howtor.html
  3. 18 5
      src/sockmap.c

+ 6 - 6
doc/html/howtoe.html

@@ -873,12 +873,12 @@ You can control 3proxy service via "Services" administration ot via "net" comman
 <li>since 0.9
     <li>90 - unexpected system error (should not happen)
     <li>91 - unexpected poll error (should not happen)
-    <li>92 - connection terminated by timeout
-    <li>93 - dirty connection termination by server or client (or network issue) with unsent data
-    <li>94 - clear connection termination by server or client with unsent data
-    <li>95 - dirty connection termination by client (or network issue)
-    <li>96 - dirty connection termination by server (or network issue)
-    <li>97 - dirty connection termination by both client and server (probably network issue)
+    <li>92 - connection terminated by timeout (see timeouts)
+    <li>93 - connection terminated by ratelimit-related timeout
+    <li>94 - connection termination by server or client with unsent data
+    <li>95 - dirty connection termination by client (or networking issue)
+    <li>96 - dirty connection termination by server (or networking issue)
+    <li>97 - dirty connection termination by both client and server (probably networking issue)
 <li>prior to 0.9:
 		<li>90 - socket error or connection broken
 		<li>91 - TCP/IP common failure

+ 3 - 3
doc/html/howtor.html

@@ -1049,9 +1049,9 @@
     <li>с версии 0.9
     <li>90 - неожиданная системная ошибка (не должно происходить)
     <li>91 - ошибка poll (не должно происходить)
-    <li>92 - соединение прервано по таймауту
-    <li>93 - клиент или сервер &quot;грязно&quot; закрыли соединение или произошла сетевая ошибка, остались неотправленные данные 
-    <li>94 - клиент или сервер &quot;чисто&quot; закрыли соединение или произошла сетевая ошибка, остались неотправленные данные
+    <li>92 - соединение прервано по таймауту на сетевую операцию (см. timeouts)
+    <li>93 - соединение прервано по таймауту связанному с рейтлимитом 
+    <li>94 - клиент или сервер закрыли соединение или произошла сетевая ошибка, остались неотправленные данные
     <li>95 - клиент "грязно" закрыл соединение или сетевая ошибка
     <li>96 - сервер "грязно" закрыл соединение или сетевая ошибка
     <li>97 - клиент и сервер "грязно" закрыли соединение или сетевая ошибка

+ 18 - 5
src/sockmap.c

@@ -57,6 +57,7 @@ int sockmap(struct clientparam * param, int timeo, int usesplice){
  FILTER_ACTION action;
  int res;
  SASIZETYPE sasize;
+ int needaction = 0;
 
 #ifdef WITHSPLICE
  uint64_t inclientpipe = 0, inserverpipe = 0;
@@ -155,8 +156,11 @@ sprintf(logbuf, "int FROMCLIENT = %d, TOCLIENTBUF = %d, FROMCLIENTBUF = %d, TOSE
 log(logbuf);
 #endif
 
+	if(needaction > 2 && !sleeptime){
+		sleeptime = (1<<(needaction-2));
+	}
 	if(sleeptime > 0) {
-		if(sleeptime > (timeo * 1000)){RETURN (92);}
+		if(sleeptime > (timeo * 1000)){RETURN (93);}
 		memset(fds, 0, sizeof(fds));
 		fds[0].fd = param->clisock;
 		fds[1].fd = param->remsock;
@@ -216,6 +220,7 @@ log("done send to server from buf");
 				sl1 = (*param->bandlimfunc)(param, 0, res);
 				if(sl1 > sleeptime) sleeptime = sl1;
 		    	}
+			needaction = 0;
 			continue;
 		}
 	}
@@ -247,6 +252,7 @@ log("done send to client from buf");
 			param->srvoffset += res;
 			if(param->srvoffset == param->srvinbuf)param->srvoffset = param->srvinbuf =0;
 			if(param->srvinbuf < param->srvbufsize) TOSERVERBUF = 1;
+			needaction = 0;
 			continue;
 		}
 	}
@@ -270,6 +276,7 @@ log("done send to server from pipe");
 					sl1 = (*param->bandlimfunc)(param, 0, res);
 					if(sl1 > sleeptime) sleeptime = sl1;
 		    		}
+				needaction = 0;
 				continue;
 			}
 			else {
@@ -288,6 +295,7 @@ log("done send to client from pipe");
 				inserverpipe -= res;
 				fromserver -= res;
 				if(fromserver)TOSERVERPIPE = 1;
+				needaction = 0;
 				continue;
 			}
 			else {
@@ -313,6 +321,7 @@ log("done read from client to pipe");
 #endif
 				inclientpipe += res;
 				if(inclientpipe >= MAXSPLICE) TOCLIENTPIPE = 0;
+				needaction = 0;
 				continue;
 			}
 		}
@@ -346,8 +355,9 @@ log("done read from server to pipe\n");
 					fromserver = inserverpipe;
 					FROMSERVER = 0;
 				}
+				needaction = 0;
+				continue;
 			}
-			continue;
 		}
 	}
 	else
@@ -370,6 +380,7 @@ log("done read from client to buf");
 				inclientbuf += res;
 				param->cliinbuf += res;
 				if(param->clibufsize == param->cliinbuf) TOCLIENTBUF = 0;
+				needaction = 0;
 				continue;
 			}
 		}
@@ -402,6 +413,7 @@ log("done read from server to buf");
 					fromserver = inserverbuf;
 					FROMSERVER = 0;
 				}
+				needaction = 0;
 				continue;
 			}
 		}
@@ -639,7 +651,7 @@ log("leaving poll");
 #ifdef WITHLOG
 log("poll error");
 #endif
-				if(errno != EAGAIN && errno != EINTR) RETURN(91);
+				if(errno != EINTR) RETURN(91);
 				break;
 			}
 			if(res < 1){
@@ -650,14 +662,15 @@ log("timeout");
 			}
 		}
 	}
+	needaction++;
 
  }
  res = 0;
  if(!fromserver && param->waitserver64) res = 98;
  else if(!fromclient && param->waitclient64) res = 99;
- else if((inclientbuf || inserverbuf)) res = HASERROR?93:94;
+ else if((inclientbuf || inserverbuf)) res = 94;
 #ifdef WITHSPLICE
- else if(inclientpipe || inserverpipe) res = HASERROR?93:94;
+ else if(inclientpipe || inserverpipe) res = 94;
 #endif
  else if(HASERROR) res = 94+HASERROR;