diff --git a/src/3proxy.c b/src/3proxy.c index fd68212..c99c285 100644 --- a/src/3proxy.c +++ b/src/3proxy.c @@ -265,9 +265,7 @@ void cyclestep(void){ if(conf.timetoexit){ conf.paused++; doschedule(); - usleep(SLEEPTIME*999); - usleep(SLEEPTIME*999); - usleep(SLEEPTIME*999); + usleep(3*SLEEPTIME*999); return; } diff --git a/src/sockgetchar.c b/src/sockgetchar.c index 720712b..3e9db0f 100644 --- a/src/sockgetchar.c +++ b/src/sockgetchar.c @@ -10,19 +10,20 @@ int socksend(SOCKET sock, char * buf, int bufsize, int to){ int sent = 0; int res; - struct pollfd fds; + struct pollfd fds={0}; fds.fd = sock; - fds.events = POLLOUT; 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); if(res < 0) { if(errno == EAGAIN || errno == EINTR) continue; 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; } 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 sent = 0; int res; - struct pollfd fds; + struct pollfd fds={0}; fds.fd = sock; do { 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)); if(res < 0) { 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; } 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){ - struct pollfd fds; + struct pollfd fds={0}; SASIZETYPE sasize; int res; fds.fd = sock; - fds.events = POLLIN; - if(conf.timetoexit) return EOF; - if (so._poll(&fds, 1, to)<1) return 0; - sasize = SASIZE(sin); do { + sasize = SASIZE(sin); 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; } diff --git a/src/socks.c b/src/socks.c index 6069f19..a6d04c2 100644 --- a/src/socks.c +++ b/src/socks.c @@ -7,7 +7,6 @@ */ #include "proxy.h" - #define RETURN(xxx) { param->res = xxx; goto CLEANRET; } char * commands[] = {"UNKNOWN", "CONNECT", "BIND", "UDPMAP"}; @@ -333,64 +332,61 @@ fflush(stderr); if(!(buf = myalloc(LARGEBUFSIZE))) {RETURN(21);} 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(;;){ - 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(res <= 0) { - param->res = 463; - break; - } - if (fds[2].revents) { - param->res = 0; - break; - } - if (fds[1].revents) { + if(!fds[1].events || fds[1].revents){ sasize = sizeof(sin); - 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); - } + 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; - memcpy(SAPORT(¶m->sinsr), buf+i, 2); - i+=2; + sasize = sizeof(sin); + 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); - 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++; + memcpy(SAPORT(¶m->sinsr), buf+i, 2); + i+=2; + + sasize = sizeof(param->sinsr); + 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 fprintf(stderr, "UDP packet relayed from client to %s:%hu size %d, header %d\n", inet_ntoa(param->sins.sin_addr), @@ -404,23 +400,32 @@ fprintf(stderr, "client address is assumed to be %s:%hu\n", ); fflush(stderr); #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); buf[0]=buf[1]=buf[2]=0; 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; break; } - param->statssrv64+=len; - param->nreads++; - memcpy(buf+4, SAADDR(¶m->sinsr), SAADDRLEN(¶m->sinsr)); - 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); + else if(len > 0){ + fds[0].events = fds[0].revents = 0; + param->statssrv64+=len; + param->nreads++; + memcpy(buf+4, SAADDR(¶m->sinsr), SAADDRLEN(¶m->sinsr)); + 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 fprintf(stderr, "UDP packet relayed to client from %hu size %d\n", ntohs(*SAPORT(¶m->sinsr)), @@ -429,6 +434,22 @@ fprintf(stderr, "UDP packet relayed to client from %hu size %d\n", fflush(stderr); #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;