int sockgetcharcli(struct clientparam * param, int timeosec, int timeousec){ int len; if(!param->clibuf){ if(!(param->clibuf = myalloc(BUFSIZE))) return 0; param->clibufsize = BUFSIZE; param->clioffset = param->cliinbuf = 0; } if(param->cliinbuf && param->clioffset < param->cliinbuf){ return (int)param->clibuf[param->clioffset++]; } param->clioffset = param->cliinbuf = 0; if ((len = sockrecvfrom(param->clisock, ¶m->sinc, param->clibuf, param->clibufsize, timeosec*1000 + timeousec))<=0) return EOF; param->cliinbuf = len; param->clioffset = 1; return (int)*param->clibuf; }
int sockfillbuffcli(struct clientparam * param, unsigned long size, int timeosec){ int len; if(!param->clibuf) return 0; if(param->cliinbuf == param->clioffset){ param->cliinbuf = param->clioffset = 0; } else if(param->clioffset){ memmove(param->clibuf, param->clibuf + param->clioffset, param->cliinbuf - param->clioffset); param->cliinbuf -= param->clioffset; param->clioffset = 0; } if(size <= param->cliinbuf) return size; size -= param->cliinbuf; if((len = sockrecvfrom(param->clisock, ¶m->sinc, param->clibuf + param->cliinbuf, (param->clibufsize - param->cliinbuf) < size? param->clibufsize - param->cliinbuf:size, timeosec*1000)) > 0){ param->cliinbuf += len; } return param->cliinbuf; }
int sockgetcharsrv(struct clientparam * param, int timeosec, int timeousec){ int len; int bufsize; if(!param->srvbuf){ bufsize = BUFSIZE; if(param->ndatfilterssrv > 0 && bufsize < 32768) bufsize = 32768; if(!(param->srvbuf = myalloc(bufsize))) return 0; param->srvbufsize = bufsize; param->srvoffset = param->srvinbuf = 0; } if(param->srvinbuf && param->srvoffset < param->srvinbuf){ return (int)param->srvbuf[param->srvoffset++]; } param->srvoffset = param->srvinbuf = 0; if ((len = sockrecvfrom(param->remsock, ¶m->sins, param->srvbuf, param->srvbufsize, timeosec*1000 + timeousec))<=0) return EOF; param->srvinbuf = len; param->srvoffset = 1; param->nreads++; param->statssrv += len; return (int)*param->srvbuf; }
void * udppmchild(struct clientparam* param) { unsigned char *buf = NULL; int res, i; #ifdef _WIN32 SASIZETYPE size; unsigned long ul = 1; #endif struct udpmap *udpmappings = NULL; struct pollfd fds[256]; if(!param->hostname)parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport)); if (!param->req.sin_addr.s_addr) { param->srv->fds.events = POLLIN; RETURN (100); } if(!param->clibuf && (!(param->clibuf=myalloc(UDPBUFSIZE)) || !(param->clibufsize = UDPBUFSIZE))){ param->srv->fds.events = POLLIN; RETURN (21); } param->cliinbuf = param->clioffset = 0; i = sockrecvfrom(param->srv->srvsock, ¶m->sinc, param->clibuf, param->clibufsize, 0); if(i<=0){ param->srv->fds.events = POLLIN; RETURN (214); } param->cliinbuf = i; #ifdef _WIN32 if((param->clisock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) { RETURN(818); } if(so._setsockopt(param->clisock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&ul, sizeof(int))) {RETURN(820);}; ioctlsocket(param->clisock, FIONBIO, &ul); size = sizeof(struct sockaddr_in); if(so._getsockname(param->srv->srvsock, (struct sockaddr *)¶m->sins, &size)) {RETURN(21);}; if(so._bind(param->clisock,(struct sockaddr *)¶m->sins,sizeof(struct sockaddr_in))) { RETURN(822); } #else param->clisock = param->srv->srvsock; #endif param->sins.sin_family = AF_INET; param->sins.sin_port = htons(0); param->sins.sin_addr.s_addr = param->extip; if ((param->remsock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);} if(so._bind(param->remsock,(struct sockaddr *)¶m->sins,sizeof(param->sins))) {RETURN (12);} #ifdef _WIN32 ioctlsocket(param->remsock, FIONBIO, &ul); #else fcntl(param->remsock,F_SETFL,O_NONBLOCK); #endif param->sins.sin_addr.s_addr = param->req.sin_addr.s_addr; param->sins.sin_port = param->req.sin_port; param->operation = UDPASSOC; if((res = (*param->srv->authfunc)(param))) {RETURN(res);} if(param->srv->singlepacket) { param->srv->fds.events = POLLIN; } param->res = sockmap(param, conf.timeouts[(param->srv->singlepacket)?SINGLEBYTE_L:STRING_L]); if(!param->srv->singlepacket) { param->srv->fds.events = POLLIN; } CLEANRET: if(buf)myfree(buf); (*param->srv->logfunc)(param, NULL); #ifndef _WIN32 param->clisock = INVALID_SOCKET; #endif freeparam(param); return (NULL); }
void * dnsprchild(void * data) { #define param ((struct clientparam*)data) unsigned long ip = 0; unsigned char *buf, *s1, *s2; char * host = NULL; unsigned char c; SASIZETYPE size; int res, i; int len; unsigned type=0; unsigned ttl; #ifdef _WIN32 unsigned long ul; #endif if(!(buf = myalloc(BUFSIZE))){ param->srvfds->events = POLLIN; RETURN (21); } size = sizeof(struct sockaddr_in); i = recvfrom(param->srvsock, buf, BUFSIZE, 0, (struct sockaddr *)¶m->sinc, &size); #ifdef _WIN32 if((param->clisock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) { RETURN(818); } if(setsockopt(param->clisock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&ul, sizeof(int))) {RETURN(820);}; ioctlsocket(param->clisock, FIONBIO, &ul); size = sizeof(struct sockaddr_in); if(getsockname(param->srvsock, (struct sockaddr *)¶m->sins, &size)) {RETURN(21);}; if(bind(param->clisock,(struct sockaddr *)¶m->sins,sizeof(struct sockaddr_in))) { RETURN(822); } #else param->clisock = param->srvsock; #endif param->srvfds->events = POLLIN; if(i < 0) { RETURN(813); } buf[BUFSIZE - 1] = 0; if(i<=13 || i>1000){ RETURN (814); } param->operation = DNSRESOLVE; if((res = (*param->authfunc)(param))) {RETURN(res);} if(buf[4]!=0 || buf[5]!=1) RETURN(816); for(len = 12; len<i; len+=(c+1)){ c = buf[len]; if(!c)break; buf[len] = '.'; } if(len > (i-4)) {RETURN(817);} host = mystrdup((char *)buf+13); if(!host) {RETURN(21);} for(s2 = buf + 12; (s1 = (unsigned char *)strchr((char *)s2 + 1, '.')); s2 = s1)*s2 = (unsigned char)((s1 - s2) - 1); *s2 = (len - (s2 - buf)) - 1; type = ((unsigned)buf[len+1])*256 + (unsigned)buf[len+2]; if(type==1){ ip = udpresolve((unsigned char *)host, &ttl, param); } len+=5; if(ip){ buf[2] = 0x85; buf[3] = 0x80; buf[6] = 0; buf[7] = 1; buf[8] = buf[9] = buf[10] = buf[11] = 0; memset(buf+len, 0, 16); buf[len] = 0xc0; buf[len+1] = 0x0c; buf[len+3] = 1; buf[len+5] = 1; ttl = htonl(ttl); memcpy(buf + len + 6, &ttl, 4); buf[len+11] = 4; memcpy(buf+len+12,(void *)&ip,4); len+=16; } if(type == 0x0c) { unsigned a, b, c, d; sscanf(host, "%u.%u.%u.%u", &a, &b, &c, &d); ip = htonl((d<<24) ^ (c<<16) ^ (b<<8) ^ a); if(ip == param->intip){ buf[2] = 0x85; buf[3] = 0x80; buf[6] = 0; buf[7] = 1; buf[8] = buf[9] = buf[10] = buf[11] = 0; memset(buf+len, 0, 20); buf[len] = 0xc0; buf[len+1] = 0x0c; buf[len+3] = 0x0c; buf[len+5] = 1; ttl = htonl(3600); memcpy(buf + len + 6, &ttl, 4); buf[len+11] = 7; buf[len+12] = 6; memcpy(buf+len+13,(void *)"3proxy",6); len+=20; } else ip = 0; } if(!ip && nservers[0] && type!=1){ if((param->remsock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) { RETURN(818); } #ifdef _WIN32 ioctlsocket(param->remsock, FIONBIO, &ul); #else fcntl(param->remsock,F_SETFL,O_NONBLOCK); #endif param->sins.sin_family = AF_INET; param->sins.sin_port = htons(0); param->sins.sin_addr.s_addr = htonl(0); if(bind(param->remsock,(struct sockaddr *)¶m->sins,sizeof(struct sockaddr_in))) { RETURN(819); } param->sins.sin_addr.s_addr = nservers[0]; param->sins.sin_port = htons(53); if(socksendto(param->remsock, ¶m->sins, buf, i, conf.timeouts[SINGLEBYTE_L]*1000) != i){ RETURN(820); } param->statscli += i; len = sockrecvfrom(param->remsock, ¶m->sins, buf, BUFSIZE, 15000); if(len <= 13) { RETURN(821); } param->statssrv += len; if(buf[6] || buf[7]){ if(socksendto(param->clisock, ¶m->sinc, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){ RETURN(822); } RETURN(0); } } if(!ip) { buf[2] = 0x85; buf[3] = 0x83; } usleep(SLEEPTIME); res = socksendto(param->clisock, ¶m->sinc, buf, len, conf.timeouts[SINGLEBYTE_L]*1000); if(res != len){RETURN(819);} if(!ip) {RETURN(888);} CLEANRET: if(param->res!=813){ sprintf((char *)buf, "%04x/%s(%u.%u.%u.%u) ", (unsigned)type, host, (unsigned)(ntohl(ip)&0xff000000)>>24, (unsigned)(ntohl(ip)&0x00ff0000)>>16, (unsigned)(ntohl(ip)&0x0000ff00)>>8, (unsigned)(ntohl(ip)&0x000000ff) ); (*param->logfunc)(param, buf); }
void * dnsprchild(struct clientparam* param) { unsigned long ip = 0; unsigned char *bbuf; unsigned char *buf, *s1, *s2; char * host = NULL; unsigned char c; SASIZETYPE size; int res, i; int len; unsigned type=0; unsigned ttl; unsigned char addr[16]; #ifdef _WIN32 unsigned long ul = 1; #endif if(!(bbuf = myalloc(BUFSIZE+2))){ param->srv->fds.events = POLLIN; RETURN (21); } buf = bbuf+2; size = sizeof(param->sincr); i = so._recvfrom(param->srv->srvsock, buf, BUFSIZE, 0, (struct sockaddr *)¶m->sincr, &size); size = sizeof(param->sinsl); getsockname(param->srv->srvsock, (struct sockaddr *)¶m->sincl, &size); #ifdef _WIN32 if((param->clisock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) { RETURN(818); } ioctlsocket(param->clisock, FIONBIO, &ul); if(so._setsockopt(param->clisock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&ul, sizeof(int))) {RETURN(820);}; if(so._bind(param->clisock,(struct sockaddr *)¶m->sincl,sizeof(param->sincl))) { RETURN(822); } #else param->clisock = param->srv->srvsock; #endif param->srv->fds.events = POLLIN; if(i < 0) { RETURN(813); } buf[BUFSIZE - 1] = 0; if(i<=13 || i>1000){ RETURN (814); } param->operation = DNSRESOLVE; if((res = (*param->srv->authfunc)(param))) {RETURN(res);} if(buf[4]!=0 || buf[5]!=1) RETURN(816); for(len = 12; len<i; len+=(c+1)){ c = buf[len]; if(!c)break; buf[len] = '.'; } if(len > (i-4)) {RETURN(817);} host = mystrdup((char *)buf+13); if(!host) {RETURN(21);} for(s2 = buf + 12; (s1 = (unsigned char *)strchr((char *)s2 + 1, '.')); s2 = s1)*s2 = (unsigned char)((s1 - s2) - 1); *s2 = (len - (int)(s2 - buf)) - 1; type = ((unsigned)buf[len+1])*256 + (unsigned)buf[len+2]; if((type==0x01 || type==0x1c) && !param->srv->singlepacket){ ip = udpresolve((type==0x1c)?AF_INET6:AF_INET, (unsigned char *)host, addr, &ttl, param, 0); } len+=5; if(ip){ buf[2] = 0x85; buf[3] = 0x80; buf[6] = 0; buf[7] = 1; buf[8] = buf[9] = buf[10] = buf[11] = 0; memset(buf+len, 0, 16); buf[len] = 0xc0; buf[len+1] = 0x0c; buf[len+3] = type; buf[len+5] = 1; ttl = htonl(ttl); memcpy(buf + len + 6, &ttl, 4); buf[len+11] = type==1? 4:16; memcpy(buf+len+12,(void *)&addr,type==1? 4:16); len+=(type==1?16:28); } else if(type == 0x0c) { unsigned a, b, c, d; sscanf(host, "%u.%u.%u.%u", &a, &b, &c, &d); ip = htonl((d<<24) ^ (c<<16) ^ (b<<8) ^ a); if(*SAFAMILY(¶m->sincl) == AF_INET && ip == *(unsigned long*)SAADDR(¶m->sincl)){ buf[2] = 0x85; buf[3] = 0x80; buf[6] = 0; buf[7] = 1; buf[8] = buf[9] = buf[10] = buf[11] = 0; memset(buf+len, 0, 20); buf[len] = 0xc0; buf[len+1] = 0x0c; buf[len+3] = 0x0c; buf[len+5] = 1; ttl = htonl(3600); memcpy(buf + len + 6, &ttl, 4); buf[len+11] = 7; buf[len+12] = 6; memcpy(buf+len+13,(void *)"3proxy",6); len+=20; } else ip = 0; } if(!ip && numservers){ if((param->remsock=so._socket(SASOCK(&nservers[0].addr), nservers[0].usetcp? SOCK_STREAM:SOCK_DGRAM, nservers[0].usetcp?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) { RETURN(818); } memset(¶m->sinsl, 0, sizeof(param->sinsl)); *SAFAMILY(¶m->sinsl) = *SAFAMILY(&nservers[0].addr); if(so._bind(param->remsock,(struct sockaddr *)¶m->sinsl,sizeof(param->sinsl))) { RETURN(819); } memcpy(¶m->sinsr, &nservers[0].addr, sizeof(param->sinsr)); if(nservers[0].usetcp) { if(so._connect(param->remsock,(struct sockaddr *)¶m->sinsr,sizeof(param->sinsr))) RETURN(830); buf-=2; *(unsigned short*)buf = htons(i); i+=2; } else { #ifdef _WIN32 /* ioctlsocket(param->remsock, FIONBIO, &ul); */ #else /* fcntl(param->remsock,F_SETFL,O_NONBLOCK); */ #endif } if(socksendto(param->remsock, (struct sockaddr *)¶m->sinsr, buf, i, conf.timeouts[SINGLEBYTE_L]*1000) != i){ RETURN(820); } param->statscli64 += i; param->nwrites++; len = sockrecvfrom(param->remsock, (struct sockaddr *)¶m->sinsr, buf, BUFSIZE, 15000); if(len <= 13) { RETURN(821); } param->statssrv64 += len; param->nreads++; if(nservers[0].usetcp) { unsigned short us; us = ntohs(*(unsigned short *)buf); if(us > 4096) RETURN(833); buf += 2; len -= 2; if(len < us) len += sockgetlinebuf(param, SERVER, buf+len, us - len, 0, conf.timeouts[SINGLEBYTE_L]); if(len != us) RETURN(832); } if(buf[6] || buf[7]){ if(socksendto(param->clisock, (struct sockaddr *)¶m->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){ RETURN(822); } RETURN(0); } } if(!ip) { buf[2] = 0x85; buf[3] = 0x83; } res = socksendto(param->clisock, (struct sockaddr *)¶m->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000); if(res != len){RETURN(819);} if(!ip) {RETURN(888);} CLEANRET: if(param->res!=813){ sprintf((char *)buf, "%04x/%s/", (unsigned)type, host?host:""); if(ip && type == 0x01 || type == 0x1c){ myinet_ntop(type == 0x01? AF_INET:AF_INET6, addr, buf+strlen(buf), 64); } (*param->srv->logfunc)(param, buf); } if(bbuf)myfree(bbuf); if(host)myfree(host); #ifndef _WIN32 param->clisock = INVALID_SOCKET; #endif freeparam(param); return (NULL); }