Call poll() only on EAGAIN/EINTR

This commit is contained in:
z3APA3A 2020-11-16 14:11:18 +03:00
parent 4ec9229acb
commit 2b1025a79b
3 changed files with 105 additions and 84 deletions

View File

@ -265,9 +265,7 @@ void cyclestep(void){
if(conf.timetoexit){ if(conf.timetoexit){
conf.paused++; conf.paused++;
doschedule(); doschedule();
usleep(SLEEPTIME*999); usleep(3*SLEEPTIME*999);
usleep(SLEEPTIME*999);
usleep(SLEEPTIME*999);
return; return;
} }

View File

@ -10,19 +10,20 @@
int socksend(SOCKET sock, char * buf, int bufsize, int to){ int socksend(SOCKET sock, char * buf, int bufsize, int to){
int sent = 0; int sent = 0;
int res; int res;
struct pollfd fds; struct pollfd fds={0};
fds.fd = sock; fds.fd = sock;
fds.events = POLLOUT;
do { do {
if(conf.timetoexit) return 0;
res = so._poll(&fds, 1, to*1000);
if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue;
if(res < 1) break;
res = so._send(sock, (char *)buf + sent, bufsize - sent, 0); res = so._send(sock, (char *)buf + sent, bufsize - sent, 0);
if(res < 0) { if(res < 0) {
if(errno == EAGAIN || errno == EINTR) continue; if(errno == EAGAIN || errno == EINTR) continue;
break; break;
fds.events = POLLOUT;
if(conf.timetoexit) return sent;
res = so._poll(&fds, 1, to*1000);
if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue;
if(res < 1) break;
res = 0;
} }
sent += res; sent += res;
} while (sent < bufsize); } while (sent < bufsize);
@ -33,19 +34,20 @@ int socksend(SOCKET sock, char * buf, int bufsize, int to){
int socksendto(SOCKET sock, struct sockaddr * sin, char * buf, int bufsize, int to){ int socksendto(SOCKET sock, struct sockaddr * sin, char * buf, int bufsize, int to){
int sent = 0; int sent = 0;
int res; int res;
struct pollfd fds; struct pollfd fds={0};
fds.fd = sock; fds.fd = sock;
do { do {
if(conf.timetoexit) return 0; if(conf.timetoexit) return 0;
fds.events = POLLOUT;
res = so._poll(&fds, 1, to);
if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue;
if(res < 1) break;
res = so._sendto(sock, (char *)buf + sent, bufsize - sent, 0, sin, SASIZE(sin)); res = so._sendto(sock, (char *)buf + sent, bufsize - sent, 0, sin, SASIZE(sin));
if(res < 0) { if(res < 0) {
if(errno != EAGAIN && errno != EINTR) break; if(errno != EAGAIN && errno != EINTR) break;
continue; fds.events = POLLOUT;
if(conf.timetoexit) return sent;
res = so._poll(&fds, 1, to);
if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue;
if(res < 1) break;
res = 0;
} }
sent += res; sent += res;
} while (sent < bufsize); } while (sent < bufsize);
@ -53,18 +55,18 @@ int socksendto(SOCKET sock, struct sockaddr * sin, char * buf, int bufsize, int
} }
int sockrecvfrom(SOCKET sock, struct sockaddr * sin, char * buf, int bufsize, int to){ int sockrecvfrom(SOCKET sock, struct sockaddr * sin, char * buf, int bufsize, int to){
struct pollfd fds; struct pollfd fds={0};
SASIZETYPE sasize; SASIZETYPE sasize;
int res; int res;
fds.fd = sock; fds.fd = sock;
fds.events = POLLIN;
if(conf.timetoexit) return EOF;
if (so._poll(&fds, 1, to)<1) return 0;
sasize = SASIZE(sin);
do { do {
sasize = SASIZE(sin);
res = so._recvfrom(sock, (char *)buf, bufsize, 0, (struct sockaddr *)sin, &sasize); res = so._recvfrom(sock, (char *)buf, bufsize, 0, (struct sockaddr *)sin, &sasize);
} while (res < 0 && (errno == EAGAIN || errno == EINTR)); if ((res >= 0) || (errno != EAGAIN && errno != EINTR) || conf.timetoexit) break;
fds.events = POLLIN;
res = so._poll(&fds, 1, to);
} while (res == 1 || (res < 0 && (errno == EAGAIN || errno == EINTR)));
return res; return res;
} }

View File

@ -7,7 +7,6 @@
*/ */
#include "proxy.h" #include "proxy.h"
#define RETURN(xxx) { param->res = xxx; goto CLEANRET; } #define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
char * commands[] = {"UNKNOWN", "CONNECT", "BIND", "UDPMAP"}; char * commands[] = {"UNKNOWN", "CONNECT", "BIND", "UDPMAP"};
@ -333,22 +332,19 @@ fflush(stderr);
if(!(buf = myalloc(LARGEBUFSIZE))) {RETURN(21);} if(!(buf = myalloc(LARGEBUFSIZE))) {RETURN(21);}
sin = param->sincr; sin = param->sincr;
for(;;){ fds[2].events = fds[1].events = fds[0].events = 0;
fds[0].fd = param->remsock; fds[0].fd = param->remsock;
fds[1].fd = param->clisock; fds[1].fd = param->clisock;
fds[2].fd = param->ctrlsock; fds[2].fd = param->ctrlsock;
fds[2].events = fds[1].events = fds[0].events = POLLIN; for(;;){
if(!fds[1].events || fds[1].revents){
sasize = sizeof(sin);
len = so._recvfrom(param->clisock, (char *)buf, 65535, 0, (struct sockaddr *)&sin, &sasize);
if(len >= 0) {
fds[1].events = fds[1].revents = 0;
if(len < 10) continue;
res = so._poll(fds, 3, conf.timeouts[CONNECTION_L]*1000);
if(res <= 0) {
param->res = 463;
break;
}
if (fds[2].revents) {
param->res = 0;
break;
}
if (fds[1].revents) {
sasize = sizeof(sin); sasize = sizeof(sin);
if((len = so._recvfrom(param->clisock, (char *)buf, 65535, 0, (struct sockaddr *)&sin, &sasize)) <= 10) { if((len = so._recvfrom(param->clisock, (char *)buf, 65535, 0, (struct sockaddr *)&sin, &sasize)) <= 10) {
param->res = 464; param->res = 464;
@ -405,16 +401,25 @@ fprintf(stderr, "client address is assumed to be %s:%hu\n",
fflush(stderr); fflush(stderr);
#endif #endif
} }
continue;
} }
if (fds[0].revents) { else if(len ==0 || (len <0 && errno != EINTR && errno != EAGAIN)){
param->res = 464;
break;
}
fds[1].events = POLLIN;
}
if (!fds[0].events || fds[0].revents) {
sasize = sizeof(param->sinsr); sasize = sizeof(param->sinsr);
buf[0]=buf[1]=buf[2]=0; buf[0]=buf[1]=buf[2]=0;
buf[3]=(*SAFAMILY(&param->sinsl) == AF_INET)?1:4; buf[3]=(*SAFAMILY(&param->sinsl) == AF_INET)?1:4;
if((len = so._recvfrom(param->remsock, (char *)buf+6+SAADDRLEN(&param->sinsl), 65535 - (6+SAADDRLEN(&param->sinsl)), 0, (struct sockaddr *)&param->sinsr, &sasize)) <= 0) { len = so._recvfrom(param->remsock, (char *)buf+6+SAADDRLEN(&param->sinsl), 65535 - (6+SAADDRLEN(&param->sinsl)), 0, (struct sockaddr *)&param->sinsr, &sasize);
if(len == 0 || (len < 0 && errno != EAGAIN && errno !=EINTR)) {
param->res = 468; param->res = 468;
break; break;
} }
else if(len > 0){
fds[0].events = fds[0].revents = 0;
param->statssrv64+=len; param->statssrv64+=len;
param->nreads++; param->nreads++;
memcpy(buf+4, SAADDR(&param->sinsr), SAADDRLEN(&param->sinsr)); memcpy(buf+4, SAADDR(&param->sinsr), SAADDRLEN(&param->sinsr));
@ -429,6 +434,22 @@ fprintf(stderr, "UDP packet relayed to client from %hu size %d\n",
fflush(stderr); fflush(stderr);
#endif #endif
continue;
}
fds[0].events = POLLIN;
}
if (fds[2].revents) {
param->res = 0;
break;
}
fds[0].revents = fds[1].revents = fds[2].revents = 0;
fds[2].events = POLLIN;
res = so._poll(fds, 3, conf.timeouts[CONNECTION_L]*1000);
if(res == 0 || (res < 0 && errno != EAGAIN && errno != EINTR)) {
param->res = 463;
break;
} }
} }
break; break;