mirror of
https://github.com/3proxy/3proxy.git
synced 2025-02-23 10:35:40 +08:00
Call poll() only on EAGAIN/EINTR
This commit is contained in:
parent
4ec9229acb
commit
2b1025a79b
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
147
src/socks.c
147
src/socks.c
@ -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,64 +332,61 @@ fflush(stderr);
|
|||||||
if(!(buf = myalloc(LARGEBUFSIZE))) {RETURN(21);}
|
if(!(buf = myalloc(LARGEBUFSIZE))) {RETURN(21);}
|
||||||
sin = param->sincr;
|
sin = param->sincr;
|
||||||
|
|
||||||
|
fds[2].events = fds[1].events = fds[0].events = 0;
|
||||||
|
fds[0].fd = param->remsock;
|
||||||
|
fds[1].fd = param->clisock;
|
||||||
|
fds[2].fd = param->ctrlsock;
|
||||||
for(;;){
|
for(;;){
|
||||||
fds[0].fd = param->remsock;
|
|
||||||
fds[1].fd = param->clisock;
|
|
||||||
fds[2].fd = param->ctrlsock;
|
|
||||||
fds[2].events = fds[1].events = fds[0].events = POLLIN;
|
|
||||||
|
|
||||||
res = so._poll(fds, 3, conf.timeouts[CONNECTION_L]*1000);
|
if(!fds[1].events || fds[1].revents){
|
||||||
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) {
|
len = so._recvfrom(param->clisock, (char *)buf, 65535, 0, (struct sockaddr *)&sin, &sasize);
|
||||||
param->res = 464;
|
if(len >= 0) {
|
||||||
break;
|
fds[1].events = fds[1].revents = 0;
|
||||||
}
|
if(len < 10) continue;
|
||||||
if(SAADDRLEN(&sin) != SAADDRLEN(¶m->sincr) || memcmp(SAADDR(&sin), SAADDR(¶m->sincr), SAADDRLEN(&sin))){
|
|
||||||
param->res = 465;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(buf[0] || buf[1] || buf[2]) {
|
|
||||||
param->res = 466;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
size = 4;
|
|
||||||
switch(buf[3]) {
|
|
||||||
case 4:
|
|
||||||
size = 16;
|
|
||||||
case 1:
|
|
||||||
i = 4+size;
|
|
||||||
memcpy(SAADDR(¶m->sinsr), buf+4, size);
|
|
||||||
*SAFAMILY(¶m->sinsr) = (size == 4)?AF_INET:AF_INET6;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
size = buf[4];
|
|
||||||
for (i=4; size; i++, size--){
|
|
||||||
buf[i] = buf[i+1];
|
|
||||||
}
|
|
||||||
buf[i++] = 0;
|
|
||||||
if(!getip46(param->srv->family, buf+4, (struct sockaddr *) ¶m->sinsr)) RETURN(100);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
RETURN(997);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(SAPORT(¶m->sinsr), buf+i, 2);
|
sasize = sizeof(sin);
|
||||||
i+=2;
|
if((len = so._recvfrom(param->clisock, (char *)buf, 65535, 0, (struct sockaddr *)&sin, &sasize)) <= 10) {
|
||||||
|
param->res = 464;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(SAADDRLEN(&sin) != SAADDRLEN(¶m->sincr) || memcmp(SAADDR(&sin), SAADDR(¶m->sincr), SAADDRLEN(&sin))){
|
||||||
|
param->res = 465;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(buf[0] || buf[1] || buf[2]) {
|
||||||
|
param->res = 466;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
size = 4;
|
||||||
|
switch(buf[3]) {
|
||||||
|
case 4:
|
||||||
|
size = 16;
|
||||||
|
case 1:
|
||||||
|
i = 4+size;
|
||||||
|
memcpy(SAADDR(¶m->sinsr), buf+4, size);
|
||||||
|
*SAFAMILY(¶m->sinsr) = (size == 4)?AF_INET:AF_INET6;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
size = buf[4];
|
||||||
|
for (i=4; size; i++, size--){
|
||||||
|
buf[i] = buf[i+1];
|
||||||
|
}
|
||||||
|
buf[i++] = 0;
|
||||||
|
if(!getip46(param->srv->family, buf+4, (struct sockaddr *) ¶m->sinsr)) RETURN(100);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
RETURN(997);
|
||||||
|
}
|
||||||
|
|
||||||
sasize = sizeof(param->sinsr);
|
memcpy(SAPORT(¶m->sinsr), buf+i, 2);
|
||||||
if(len > (int)i){
|
i+=2;
|
||||||
socksendto(param->remsock, (struct sockaddr *)¶m->sinsr, buf+i, len - i, conf.timeouts[SINGLEBYTE_L]*1000);
|
|
||||||
param->statscli64+=(len - i);
|
sasize = sizeof(param->sinsr);
|
||||||
param->nwrites++;
|
if(len > (int)i){
|
||||||
|
socksendto(param->remsock, (struct sockaddr *)¶m->sinsr, buf+i, len - i, conf.timeouts[SINGLEBYTE_L]*1000);
|
||||||
|
param->statscli64+=(len - i);
|
||||||
|
param->nwrites++;
|
||||||
#if SOCKSTRACE > 1
|
#if SOCKSTRACE > 1
|
||||||
fprintf(stderr, "UDP packet relayed from client to %s:%hu size %d, header %d\n",
|
fprintf(stderr, "UDP packet relayed from client to %s:%hu size %d, header %d\n",
|
||||||
inet_ntoa(param->sins.sin_addr),
|
inet_ntoa(param->sins.sin_addr),
|
||||||
@ -404,23 +400,32 @@ fprintf(stderr, "client address is assumed to be %s:%hu\n",
|
|||||||
);
|
);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
else if(len ==0 || (len <0 && errno != EINTR && errno != EAGAIN)){
|
||||||
|
param->res = 464;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fds[1].events = POLLIN;
|
||||||
}
|
}
|
||||||
if (fds[0].revents) {
|
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(¶m->sinsl) == AF_INET)?1:4;
|
buf[3]=(*SAFAMILY(¶m->sinsl) == AF_INET)?1:4;
|
||||||
if((len = so._recvfrom(param->remsock, (char *)buf+6+SAADDRLEN(¶m->sinsl), 65535 - (6+SAADDRLEN(¶m->sinsl)), 0, (struct sockaddr *)¶m->sinsr, &sasize)) <= 0) {
|
len = so._recvfrom(param->remsock, (char *)buf+6+SAADDRLEN(¶m->sinsl), 65535 - (6+SAADDRLEN(¶m->sinsl)), 0, (struct sockaddr *)¶m->sinsr, &sasize);
|
||||||
|
if(len == 0 || (len < 0 && errno != EAGAIN && errno !=EINTR)) {
|
||||||
param->res = 468;
|
param->res = 468;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
param->statssrv64+=len;
|
else if(len > 0){
|
||||||
param->nreads++;
|
fds[0].events = fds[0].revents = 0;
|
||||||
memcpy(buf+4, SAADDR(¶m->sinsr), SAADDRLEN(¶m->sinsr));
|
param->statssrv64+=len;
|
||||||
memcpy(buf+4+SAADDRLEN(¶m->sinsr), SAPORT(¶m->sinsr), 2);
|
param->nreads++;
|
||||||
sasize = sizeof(sin);
|
memcpy(buf+4, SAADDR(¶m->sinsr), SAADDRLEN(¶m->sinsr));
|
||||||
socksendto(param->clisock, (struct sockaddr *)&sin, buf, len + 6 + SAADDRLEN(¶m->sinsr), conf.timeouts[SINGLEBYTE_L]*1000);
|
memcpy(buf+4+SAADDRLEN(¶m->sinsr), SAPORT(¶m->sinsr), 2);
|
||||||
|
sasize = sizeof(sin);
|
||||||
|
socksendto(param->clisock, (struct sockaddr *)&sin, buf, len + 6 + SAADDRLEN(¶m->sinsr), conf.timeouts[SINGLEBYTE_L]*1000);
|
||||||
#if SOCKSTRACE > 1
|
#if SOCKSTRACE > 1
|
||||||
fprintf(stderr, "UDP packet relayed to client from %hu size %d\n",
|
fprintf(stderr, "UDP packet relayed to client from %hu size %d\n",
|
||||||
ntohs(*SAPORT(¶m->sinsr)),
|
ntohs(*SAPORT(¶m->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;
|
||||||
|
Loading…
Reference in New Issue
Block a user