Minor cleanups

This commit is contained in:
Vladimir Dubrovin 2026-05-13 23:21:13 +03:00
parent 381ef993a7
commit 05c4832c6c
11 changed files with 216 additions and 177 deletions

View File

@ -281,7 +281,7 @@ void random_vector(uint8_t *vector, struct clientparam *param)
ntry = (int)basetime;
for (i = 0; i < (int)sizeof(random_vector_pool); i++) {
random_vector_pool[i] += myrand((void *) &param->msec_start, sizeof(param->msec_start)) & 0xff;
random_vector_pool[i] += myrand() & 0xff;
}
did_random = 1;

View File

@ -13,7 +13,25 @@
char * copyright = COPYRIGHT;
int randomizer = 1;
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
# define MYRAND_ARC4RANDOM 1
#elif defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 36)))
# define MYRAND_ARC4RANDOM 1
#elif defined(__linux__)
# define MYRAND_GETRANDOM 1
# include <sys/random.h>
#elif defined(_WIN32)
# if defined(__WATCOMC__)
# define MYRAND_CRYPTGENRANDOM 1
# include <wincrypt.h>
# else
# define MYRAND_BCRYPTGENRANDOM 1
# include <bcrypt.h>
# pragma comment(lib, "bcrypt.lib")
# endif
#else
# define MYRAND_FALLBACK 1
#endif
@ -188,18 +206,31 @@ int numservers=0;
char* NULLADDR="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
int myrand(void * entropy, int len){
int i;
uint16_t init;
init = randomizer;
for(i=0; i < len/2; i++){
init ^= ((uint16_t *)entropy)[i];
uint32_t myrand(void){
#if defined(MYRAND_ARC4RANDOM)
return arc4random();
#elif defined(MYRAND_GETRANDOM)
uint32_t r = 0;
ssize_t n;
do {
n = getrandom(&r, sizeof(r), 0);
} while(n < 0 && errno == EINTR);
return r;
#elif defined(MYRAND_BCRYPTGENRANDOM)
uint32_t r = 0;
BCryptGenRandom(NULL, (PUCHAR)&r, sizeof(r), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
return r;
#elif defined(MYRAND_CRYPTGENRANDOM)
uint32_t r = 0;
HCRYPTPROV prov;
if(CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT|CRYPT_SILENT)){
CryptGenRandom(prov, sizeof(r), (BYTE *)&r);
CryptReleaseContext(prov, 0);
}
srand(rand()+init);
randomizer = rand();
return rand();
return r;
#else
return ((uint32_t)rand() << 16) ^ (uint32_t)rand();
#endif
}
#ifndef WITH_POLL

View File

@ -108,6 +108,14 @@ int getrotate(char c){
unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t) {
struct tm *ts;
static const char * const rot_fmt[] = {
[NONE] = "%s",
[ANNUALLY] = "%s.%04d",
[MONTHLY] = "%s.%04d.%02d",
[DAILY] = "%s.%04d.%02d.%02d",
[HOURLY] = "%s.%04d.%02d.%02d-%02d",
[MINUTELY] = "%s.%04d.%02d.%02d-%02d.%02d",
};
ts = localtime(&t);
if(strlen((char *)name) >= 4096){
@ -117,32 +125,13 @@ unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsign
if(strchr((char *)name, '%')){
dobuf2(NULL, buf, NULL, NULL, ts, (char *)name);
}
else switch(lt){
case NONE:
sprintf((char *)buf, "%s", name);
break;
case ANNUALLY:
sprintf((char *)buf, "%s.%04d", name, ts->tm_year+1900);
break;
case MONTHLY:
sprintf((char *)buf, "%s.%04d.%02d", name, ts->tm_year+1900, ts->tm_mon+1);
break;
case WEEKLY:
t = t - (ts->tm_wday * (60*60*24));
ts = localtime(&t);
sprintf((char *)buf, "%s.%04d.%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday);
break;
case DAILY:
sprintf((char *)buf, "%s.%04d.%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday);
break;
case HOURLY:
sprintf((char *)buf, "%s.%04d.%02d.%02d-%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday, ts->tm_hour);
break;
case MINUTELY:
sprintf((char *)buf, "%s.%04d.%02d.%02d-%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday, ts->tm_hour, ts->tm_min);
break;
default:
break;
else if(lt == WEEKLY){
t = t - (ts->tm_wday * (60*60*24));
ts = localtime(&t);
sprintf((char *)buf, "%s.%04d.%02d.%02d", name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday);
}
else if((unsigned)lt < sizeof(rot_fmt)/sizeof(rot_fmt[0]) && rot_fmt[lt]){
sprintf((char *)buf, rot_fmt[lt], name, ts->tm_year+1900, ts->tm_mon+1, ts->tm_mday, ts->tm_hour, ts->tm_min);
}
if(ext){
strcat((char *)buf, ".");

View File

@ -7,6 +7,18 @@
#include "proxy.h"
/*
* Read one FTP server response, skipping continuation lines (lines whose
* 4th character is '-' per RFC 959). Returns the line length on success,
* 0/<0 on socket error/timeout. The final line's text is left in buf.
*/
static int ftpreadresponse(struct clientparam *param, char *buf, int buflen) {
int i;
while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, buflen - 1, '\n',
conf.timeouts[STRING_L])) > 0
&& (i < 3 || !isnumber(*buf) || buf[3] == '-')) {}
return i;
}
int ftplogin(struct clientparam *param, char *nbuf, int *innbuf) {
char tbuf[256];
@ -20,8 +32,7 @@ int ftplogin(struct clientparam *param, char *nbuf, int *innbuf) {
if(innbuf)*innbuf = 0;
if(len < 140) return 707;
while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
}
i = ftpreadresponse(param, buf, len);
if(i < 3) return 706;
buf[i] = 0;
if(atoi(buf)/100 != 2) {
@ -34,8 +45,7 @@ int ftplogin(struct clientparam *param, char *nbuf, int *innbuf) {
}
param->statscli64 += (int)strlen(buf);
param->nwrites++;
while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
}
i = ftpreadresponse(param, buf, len);
if(i < 3) return 704;
buf[i] = 0;
res = atoi(buf)/100;
@ -99,8 +109,7 @@ int ftpres(struct clientparam *param, unsigned char * buf, int l){
int i;
if (l < 16) return 755;
while((i = sockgetlinebuf(param, SERVER, buf, l - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
}
i = ftpreadresponse(param, (char *)buf, l);
buf[i] = 0;
if(i < 3) return 751;
if(buf[0] != '2' && buf[0] != '1') return 750;
@ -115,8 +124,7 @@ int ftpsyst(struct clientparam *param, unsigned char *buf, unsigned len){
}
param->statscli64 += 6;
param->nwrites++;
while((i = sockgetlinebuf(param, SERVER, buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
}
i = ftpreadresponse(param, (char *)buf, len);
if(i < 7) return 722;
buf[3] = 0;
if(atoi((char *)buf)/100 != 2) return 723;
@ -134,8 +142,7 @@ int ftppwd(struct clientparam *param, unsigned char *buf, unsigned len){
}
param->statscli64 += 5;
param->nwrites++;
while((i = sockgetlinebuf(param, SERVER, buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
}
i = ftpreadresponse(param, (char *)buf, len);
if(i < 7) return 732;
buf[3] = 0;
if(atoi((char *)buf)/100 != 2) return 733;
@ -159,8 +166,7 @@ int ftptype(struct clientparam *param, unsigned char* f_type){
}
param->statscli64 += (int)strlen(buf);
param->nwrites++;
while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
}
i = ftpreadresponse(param, buf, sizeof(buf));
if(i < 3) return 742;
if(buf[0] != '2') return 740;
return 0;
@ -181,8 +187,7 @@ SOCKET ftpdata(struct clientparam *param){
}
param->statscli64 += 6;
param->nwrites++;
while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
}
i = ftpreadresponse(param, buf, sizeof(buf));
if(i < 7) return INVALID_SOCKET;
if(buf[0] != '2') return INVALID_SOCKET;
buf[i-2] = 0;
@ -195,7 +200,7 @@ SOCKET ftpdata(struct clientparam *param){
rem = param->remsock;
param->remsock = INVALID_SOCKET;
param->req = param->sinsr;
*SAPORT(&param->req) = *SAPORT(&param->sinsr) = htons((uint16_t)((b5<<8)^b6));
*SAPORT(&param->req) = *SAPORT(&param->sinsr) = htons((uint16_t)(((b5 & 0xff)<<8) | (b6 & 0xff)));
*SAPORT(&param->sinsl) = 0;
i = param->operation;
param->operation = FTP_DATA;
@ -233,8 +238,7 @@ SOCKET ftpcommand(struct clientparam *param, unsigned char * command, unsigned c
}
param->statscli64 += (int)strlen(buf);
param->nwrites++;
while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
}
i = ftpreadresponse(param, buf, sizeof(buf));
if(i < 3) {
param->srv->so._closesocket(param->sostate, s);
return INVALID_SOCKET;

View File

@ -85,7 +85,7 @@ int inithashtable(struct hashtable *ht, unsigned tablesize, unsigned poolsize, u
ht->poolsize = poolsize;
ht->tablesize = tablesize;
ht->growlimit = growlimit;
ht->entropy = myrand(ht, sizeof(struct hashtable));
ht->entropy = myrand();
memset(ht->ihashtable, 0, ht->tablesize * sizeof(uint32_t));
memset(ht->hashvalues, 0, ht->poolsize * (sizeof(struct hashentry) + ht->recsize - 4));

View File

@ -135,6 +135,27 @@ char * proxy_stringtable[] = {
#define BUFSIZE (LINESIZE*2)
#define FTPBUFSIZE 1536
#define PST_COUNT (sizeof(proxy_stringtable)/sizeof(proxy_stringtable[0]) - 1)
static int proxy_stringtable_len[PST_COUNT];
static int pst_len(int idx){
int len = proxy_stringtable_len[idx];
if(!len) {
len = (int)strlen(proxy_stringtable[idx]);
proxy_stringtable_len[idx] = len;
}
return len;
}
static int send_st(struct clientparam *param, int idx){
return socksend(param, param->clisock, (unsigned char *)proxy_stringtable[idx], pst_len(idx), conf.timeouts[STRING_S]);
}
static void freeptr(void *p){
void **pp = (void **)p;
if(*pp) { free(*pp); *pp = NULL; }
}
static void logurl(struct clientparam * param, char * buf, char * req, int ftp){
char *sb;
char *se;
@ -347,16 +368,28 @@ for(;;){
if(!isconnect){
if(se==sg)*se-- = ' ';
*se = '/';
memmove(ss, se, i - (se - sb) + 1);
memmove(ss, se, i - (se - buf) + 1);
}
}
reqlen = i = (int)strlen((char *)buf);
if(!strncasecmp((char *)buf, "CONNECT", 7))param->operation = HTTP_CONNECT;
else if(!strncasecmp((char *)buf, "GET", 3))param->operation = (ftp)?FTP_GET:HTTP_GET;
else if(!strncasecmp((char *)buf, "PUT", 3))param->operation = (ftp)?FTP_PUT:HTTP_PUT;
else if(!strncasecmp((char *)buf, "POST", 4)||!strncasecmp((char *)buf, "BITS_POST", 9))param->operation = HTTP_POST;
else if(!strncasecmp((char *)buf, "HEAD", 4))param->operation = HTTP_HEAD;
else param->operation = HTTP_OTHER;
{
static const struct { const char *m; int mlen; int op_http, op_ftp; } methods[] = {
{"CONNECT", 7, HTTP_CONNECT, HTTP_CONNECT},
{"GET", 3, HTTP_GET, FTP_GET},
{"PUT", 3, HTTP_PUT, FTP_PUT},
{"POST", 4, HTTP_POST, HTTP_POST},
{"BITS_POST", 9, HTTP_POST, HTTP_POST},
{"HEAD", 4, HTTP_HEAD, HTTP_HEAD},
};
int k;
param->operation = HTTP_OTHER;
for(k = 0; k < (int)(sizeof(methods)/sizeof(methods[0])); k++){
if(!strncasecmp((char *)buf, methods[k].m, methods[k].mlen)){
param->operation = ftp ? methods[k].op_ftp : methods[k].op_http;
break;
}
}
}
do {
buf[inbuf+i]=0;
/*printf("Got: %s\n", buf+inbuf);*/
@ -403,7 +436,7 @@ for(;;){
}
if( i > 11 && !strncasecmp((char *)(buf+inbuf), "Expect: 100", 11)){
keepalive = 1;
socksend(param, param->clisock, (unsigned char *)proxy_stringtable[17], (int)strlen(proxy_stringtable[17]), conf.timeouts[STRING_S]);
send_st(param, 17);
continue;
}
if(param->transparent && i > 6 && !strncasecmp((char *)buf + inbuf, "Host:", 5)){
@ -516,7 +549,7 @@ for(;;){
#endif
if(isconnect && param->redirtype != R_HTTP) {
socksend(param, param->clisock, (unsigned char *)proxy_stringtable[8], (int)strlen(proxy_stringtable[8]), conf.timeouts[STRING_S]);
send_st(param, 8);
}
@ -593,7 +626,7 @@ for(;;){
res = ftptype(param, (unsigned char *)"I");
if(res)RETURN(res);
ftpbase[--i] = 0;
ftps = ftpcommand(param, param->operation == FTP_PUT? (unsigned char *)"PUT" : (unsigned char *)"RETR", ftpbase);
ftps = ftpcommand(param, param->operation == FTP_PUT? (unsigned char *)"STOR" : (unsigned char *)"RETR", ftpbase);
}
else {
if(inftpbuf){
@ -607,7 +640,7 @@ for(;;){
}
if(ftps == INVALID_SOCKET){RETURN(780);}
if(!mode){
socksend(param, param->clisock, (unsigned char *)proxy_stringtable[8], (int)strlen(proxy_stringtable[8]), conf.timeouts[STRING_S]);
send_st(param, 8);
s = param->remsock;
param->remsock = ftps;
if((param->operation == FTP_PUT) && (contentlength64 > 0)) param->waitclient64 = contentlength64;
@ -753,7 +786,7 @@ for(;;){
if((bufsize - inbuf) < LINESIZE){
if (bufsize > 20000){
if(!headsent++){
socksend(param, param->clisock, (unsigned char *)proxy_stringtable[9], (int)strlen(proxy_stringtable[9]), conf.timeouts[STRING_S]);
send_st(param, 9);
}
if((unsigned)socksend(param, param->clisock, buf, inbuf, conf.timeouts[STRING_S]) != inbuf){
RETURN(781);
@ -797,16 +830,10 @@ for(;;){
if(isconnect && param->redirtype != R_HTTP) {
if(param->redirectfunc) {
if(req)free(req);
if(buf)free(buf);
freeptr(&req); freeptr(&buf); freeptr(&ftpbase);
return (*param->redirectfunc)(param);
}
param->res = mapsocket(param, conf.timeouts[CONNECTION_L]);
if(param->redirectfunc) {
if(req)free(req);
if(buf)free(buf);
return (*param->redirectfunc)(param);
}
RETURN(param->res);
}
@ -828,44 +855,46 @@ for(;;){
param->nwrites++;
}
inbuf = 0;
{
int hlen = (int)strlen((char *)buf);
#ifndef ANONYMOUS
if(!anonymous){
int len = strlen((char *)buf);
len += sprintf((char*)buf + len, "Forwarded: for=");
if(*SAFAMILY(&param->sincr) == AF_INET6) len += sprintf((char*)buf + len, "\"[");
len += myinet_ntop(*SAFAMILY(&param->sincr), SAADDR(&param->sincr), (char *)buf + len, 128);
if(*SAFAMILY(&param->sincr) == AF_INET6) len += sprintf((char*)buf + len, "]:%d\";by=", (int)ntohs(*SAPORT(&param->sincr)));
else len += sprintf((char*)buf + len, ":%d;by=", (int)ntohs(*SAPORT(&param->sincr)));
gethostname((char *)(buf + len), 256);
sprintf((char*)buf+strlen((char *)buf), ":%d\r\n", (int)ntohs(*SAPORT(&param->sincl)));
hlen += sprintf((char*)buf + hlen, "Forwarded: for=");
if(*SAFAMILY(&param->sincr) == AF_INET6) hlen += sprintf((char*)buf + hlen, "\"[");
hlen += myinet_ntop(*SAFAMILY(&param->sincr), SAADDR(&param->sincr), (char *)buf + hlen, 128);
if(*SAFAMILY(&param->sincr) == AF_INET6) hlen += sprintf((char*)buf + hlen, "]:%d\";by=", (int)ntohs(*SAPORT(&param->sincr)));
else hlen += sprintf((char*)buf + hlen, ":%d;by=", (int)ntohs(*SAPORT(&param->sincr)));
gethostname((char *)(buf + hlen), 256);
hlen += (int)strlen((char *)(buf + hlen));
hlen += sprintf((char*)buf + hlen, ":%d\r\n", (int)ntohs(*SAPORT(&param->sincl)));
}
else if(anonymous>1){
sprintf((char*)buf+strlen((char *)buf), "Via: 1.1 ");
gethostname((char *)(buf+strlen((char *)buf)), 256);
sprintf((char*)buf+strlen((char *)buf), ":%d (%s %s)\r\nX-Forwarded-For: ", (int)ntohs(*SAPORT(&param->srv->intsa)), conf.stringtable?conf.stringtable[2]:(unsigned char *)"", conf.stringtable?conf.stringtable[3]:(unsigned char *)"");
if(anonymous != 2)myinet_ntop(*SAFAMILY(&param->sincr), SAADDR(&param->sincr), (char *)buf + strlen((char *)buf), 128);
hlen += sprintf((char*)buf + hlen, "Via: 1.1 ");
gethostname((char *)(buf + hlen), 256);
hlen += (int)strlen((char *)(buf + hlen));
hlen += sprintf((char*)buf + hlen, ":%d (%s %s)\r\nX-Forwarded-For: ", (int)ntohs(*SAPORT(&param->srv->intsa)), conf.stringtable?conf.stringtable[2]:(unsigned char *)"", conf.stringtable?conf.stringtable[3]:(unsigned char *)"");
if(anonymous != 2)hlen += myinet_ntop(*SAFAMILY(&param->sincr), SAADDR(&param->sincr), (char *)buf + hlen, 128);
else {
unsigned long tmp;
tmp = ((unsigned long)myrand(param, sizeof(struct clientparam))<<16)^(unsigned long)rand();
myinet_ntop(AF_INET, &tmp, (char *)buf + strlen((char *)buf), 64);
uint32_t tmp = myrand();
hlen += myinet_ntop(AF_INET, &tmp, (char *)buf + hlen, 64);
}
sprintf((char*)buf+strlen((char *)buf), "\r\n");
hlen += sprintf((char*)buf + hlen, "\r\n");
}
#endif
if(keepalive <= 1) {
sprintf((char*)buf+strlen((char *)buf), "Connection: %s\r\n", keepalive? "keep-alive":"close");
hlen += sprintf((char*)buf + hlen, "Connection: %s\r\n", keepalive? "keep-alive":"close");
}
if(param->extusername){
sprintf((char*)buf + strlen((char *)buf), "%s: Basic ", (redirect)?"Proxy-Authorization":"Authorization");
hlen += sprintf((char*)buf + hlen, "%s: Basic ", (redirect)?"Proxy-Authorization":"Authorization");
sprintf((char*)username, "%.128s:%.128s", param->extusername, param->extpassword?param->extpassword:(unsigned char*)"");
en64(username, buf+strlen((char *)buf), (int)strlen((char *)username));
sprintf((char*)buf + strlen((char *)buf), "\r\n");
hlen = (int)(en64(username, buf + hlen, (int)strlen((char *)username)) - buf);
hlen += sprintf((char*)buf + hlen, "\r\n");
}
sprintf((char*)buf+strlen((char *)buf), "\r\n");
if ((res = socksend(param, param->remsock, buf+reqlen, (int)strlen((char *)buf+reqlen), conf.timeouts[STRING_S])) != (int)strlen((char *)buf+reqlen)) {
hlen += sprintf((char*)buf + hlen, "\r\n");
if ((res = socksend(param, param->remsock, buf+reqlen, hlen - reqlen, conf.timeouts[STRING_S])) != hlen - reqlen) {
RETURN(518);
}
}
#ifdef TCP_CORK
{
int opt = 0;
@ -1004,16 +1033,17 @@ for(;;){
#else
#endif
if(!isconnect || param->operation){
if(authenticate && !param->transparent) sprintf((char*)buf+strlen((char *)buf),
int hlen = (int)strlen((char *)buf);
if(authenticate && !param->transparent) hlen += sprintf((char*)buf + hlen,
"Proxy-support: Session-Based-Authentication\r\n"
"Connection: Proxy-support\r\n"
);
if(!param->srv->transparent && res>=200){
if(ckeepalive <= 1) sprintf((char*)buf+strlen((char *)buf), "Connection: %s\r\n",
if(ckeepalive <= 1) hlen += sprintf((char*)buf + hlen, "Connection: %s\r\n",
(hascontent && ckeepalive)?"keep-alive":"close");
}
sprintf((char*)buf + strlen((char *)buf), "\r\n");
if((socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S])) != (int)strlen((char *)buf)) {
hlen += sprintf((char*)buf + hlen, "\r\n");
if(socksend(param, param->clisock, buf, hlen, conf.timeouts[STRING_S]) != hlen) {
RETURN(521);
}
}
@ -1084,51 +1114,32 @@ REQUESTEND:
CLEANRET:
if(param->res != 555 && param->res && param->clisock != INVALID_SOCKET && (param->res < 90 || param->res >=800 || param->res == 100 ||(param->res > 500 && param->res< 800))) {
if((param->res>=509 && param->res < 517) || param->res > 900) {
int stidx = -1;
int r = param->res;
if((r >= 509 && r < 517) || r > 900) {
if(buf) while( (i = sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, '\n', conf.timeouts[STRING_S])) > 2);
}
if(param->res == 10) {
socksend(param, param->clisock, (unsigned char *)proxy_stringtable[2], (int)strlen(proxy_stringtable[2]), conf.timeouts[STRING_S]);
if(r == 10) stidx = 2;
else if(r == 700 || r == 701) stidx = 16;
else if(r == 100 || (r > 10 && r < 20) || (r > 701 && r <= 705)) stidx = 1;
else if(r >= 20 && r < 30) stidx = 6;
else if(r >= 30 && r < 80) stidx = 5;
else if(r == 1 || (!param->srv->needuser && r < 10)) stidx = 11;
else if(r < 10) stidx = 7;
else if(r == 999) stidx = 4;
else if(r == 519) stidx = 3;
else if(r == 517) stidx = 15;
else if(r == 780) stidx = 10;
else if(r >= 511 && r <= 516) stidx = 0;
if(stidx >= 0) {
send_st(param, stidx);
if(r == 700 || r == 701) socksend(param, param->clisock, (unsigned char *)ftpbuf, inftpbuf, conf.timeouts[STRING_S]);
}
else if (param->res == 700 || param->res == 701){
socksend(param, param->clisock, (unsigned char *)proxy_stringtable[16], (int)strlen(proxy_stringtable[16]), conf.timeouts[STRING_S]);
socksend(param, param->clisock, (unsigned char *)ftpbuf, inftpbuf, conf.timeouts[STRING_S]);
}
else if(param->res == 100 || (param->res >10 && param->res < 20) || (param->res >701 && param->res <= 705)) {
socksend(param, param->clisock, (unsigned char *)proxy_stringtable[1], (int)strlen(proxy_stringtable[1]), conf.timeouts[STRING_S]);
}
else if(param->res >=20 && param->res < 30) {
socksend(param, param->clisock, (unsigned char *)proxy_stringtable[6], (int)strlen(proxy_stringtable[6]), conf.timeouts[STRING_S]);
}
else if(param->res >=30 && param->res < 80) {
socksend(param, param->clisock, (unsigned char *)proxy_stringtable[5], (int)strlen(proxy_stringtable[5]), conf.timeouts[STRING_S]);
}
else if(param->res == 1 || (!param->srv->needuser && param->res < 10)) {
socksend(param, param->clisock, (unsigned char *)proxy_stringtable[11], (int)strlen(proxy_stringtable[11]), conf.timeouts[STRING_S]);
}
else if(param->res < 10) {
socksend(param, param->clisock, (unsigned char *)proxy_stringtable[7], (int)strlen(proxy_stringtable[7]), conf.timeouts[STRING_S]);
}
else if(param->res == 999) {
socksend(param, param->clisock, (unsigned char *)proxy_stringtable[4], (int)strlen(proxy_stringtable[4]), conf.timeouts[STRING_S]);
}
else if(param->res == 519) {
socksend(param, param->clisock, (unsigned char *)proxy_stringtable[3], (int)strlen(proxy_stringtable[3]), conf.timeouts[STRING_S]);
}
else if(param->res == 517) {
socksend(param, param->clisock, (unsigned char *)proxy_stringtable[15], (int)strlen(proxy_stringtable[15]), conf.timeouts[STRING_S]);
}
else if(param->res == 780) {
socksend(param, param->clisock, (unsigned char *)proxy_stringtable[10], (int)strlen(proxy_stringtable[10]), conf.timeouts[STRING_S]);
}
else if(param->res >= 511 && param->res<=516){
socksend(param, param->clisock, (unsigned char *)proxy_stringtable[0], (int)strlen(proxy_stringtable[0]), conf.timeouts[STRING_S]);
}
}
}
logurl(param, (char *)buf, (char *)req, ftp);
if(req)free(req);
if(buf)free(buf);
if(ftpbase)free(ftpbase);
freeptr(&req); freeptr(&buf); freeptr(&ftpbase);
freeparam(param);
return (NULL);
}

View File

@ -317,7 +317,7 @@ int readconfig(FILE * fp);
int connectwithpoll(struct clientparam *param, SOCKET sock, struct sockaddr *sa, SASIZETYPE size, int to);
int myrand(void * entropy, int len);
uint32_t myrand(void);
uint32_t murmurhash3(const void *key, int len, uint32_t seed);
extern char *copyright;

View File

@ -274,14 +274,14 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
return 100;
}
r2 = (myrand(param, sizeof(struct clientparam))%1000);
r2 = (myrand()%1000);
for(cur = acentry->chains; cur; cur=cur->next){
if(((weight = weight - cur->weight) > r2)|| done) {
if(weight <= 0) {
weight += 1000;
done = 0;
r2 = (myrand(param, sizeof(struct clientparam))%1000);
r2 = (myrand()%1000);
}
continue;
}
@ -290,7 +290,7 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
if(weight <= 0) {
weight += 1000;
done = 0;
r2 = (myrand(param, sizeof(struct clientparam))%1000);
r2 = (myrand()%1000);
}
if(!connected){
if(cur->type == R_EXTIP){
@ -302,12 +302,9 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
int i;
for(i = 0; i < 8; i++){
if(i==4)myrand(&param->sincr, sizeof(param->sincr));
else if(i==6) myrand(&param->req, sizeof(param->req));
if(i*16 >= cur->cidr) ((uint16_t *)SAADDR(&param->sinsl))[i] |= rand();
if(i*16 >= cur->cidr) ((uint16_t *)SAADDR(&param->sinsl))[i] |= (uint16_t)myrand();
else if ((i+1)*16 > cur->cidr){
c = rand();
c = (uint16_t)myrand();
c >>= (cur->cidr - (i*16));
c |= ntohs(((uint16_t *)SAADDR(&param->sinsl))[i]);
((uint16_t *)SAADDR(&param->sinsl))[i] = htons(c);

View File

@ -70,7 +70,7 @@ uint32_t udpresolve(int af, unsigned char * name, unsigned char * value, uint32_
}
len = (int)strlen((char *)name);
serial = myrand(name,len);
serial = myrand();
*(unsigned short*)buf = serial; /* query id */
buf[2] = 1; /* recursive */
buf[3] = 0;

View File

@ -9,6 +9,12 @@
#include "proxy.h"
#ifdef __linux__
#include <sched.h>
static int switch_ns(struct srvparam *srv, int target_fd) {
if(target_fd < 0) return 0;
if(srv->saved_nsfd >= 0 && setns(srv->saved_nsfd, CLONE_NEWNET)) return -1;
return setns(target_fd, CLONE_NEWNET);
}
#endif
#define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
@ -75,14 +81,14 @@ void * sockschild(struct clientparam* param) {
RETURN(412);
}
if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);}
if (i && (unsigned)(res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != i){RETURN(441);};
if (i && (res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != (int)i) {RETURN(441);}
buf[i] = 0;
if(!param->username) {
param->username = (unsigned char *)strdup((char *)buf);
if(!param->username){RETURN(21);}
}
if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(445);}
if (i && (unsigned)(res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != i){RETURN(441);};
if (i && (res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != (int)i) {RETURN(441);}
buf[i] = 0;
if(!param->password) {
param->password = (unsigned char *)strdup((char *)buf);
@ -198,33 +204,28 @@ void * sockschild(struct clientparam* param) {
case 2:
case 3:
#ifndef NOIPV6
#ifndef NOIPV6
param->sinsl = *SAFAMILY(&param->req)==AF_INET6? param->srv->extsa6 : param->srv->extsa;
#else
param->sinsl = param->srv->extsa;
#endif
#ifdef __linux__
if(command == 3 && param->srv->o_nsfd >= 0) {
if(param->srv->saved_nsfd >= 0 && setns(param->srv->saved_nsfd, CLONE_NEWNET)) {RETURN(11);}
if(setns(param->srv->o_nsfd, CLONE_NEWNET)) {RETURN(11);}
}
#endif
if ((param->remsock=param->srv->so._socket(param->sostate, SASOCK(&param->req), command == 2? SOCK_STREAM:SOCK_DGRAM, command == 2?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);}
param->operation = command == 2?BIND:UDPASSOC;
if(command == 2){
if ((param->remsock=param->srv->so._socket(param->sostate, SASOCK(&param->req), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {RETURN (11);}
#ifdef REUSE
if (command == 2){
int opt;
{
int opt;
#ifdef SO_REUSEADDR
opt = 1;
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&opt, sizeof(int));
opt = 1;
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&opt, sizeof(int));
#endif
#ifdef SO_REUSEPORT
opt = 1;
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_SOCKET, SO_REUSEPORT, (unsigned char *)&opt, sizeof(int));
opt = 1;
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_SOCKET, SO_REUSEPORT, (unsigned char *)&opt, sizeof(int));
#endif
}
}
#endif
}
break;
default:
@ -249,6 +250,13 @@ void * sockschild(struct clientparam* param) {
}
#endif
if(command == 3) {
#ifdef __linux__
if(switch_ns(param->srv, param->srv->o_nsfd)) {RETURN(11);}
#endif
if ((param->remsock=param->srv->so._socket(param->sostate, SASOCK(&param->req), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);}
}
if(command > 1) {
if(param->srv->so._bind(param->sostate, param->remsock,(struct sockaddr *)&param->sinsl,SASIZE(&param->sinsl))) {
*SAPORT(&param->sinsl) = 0;
@ -263,10 +271,7 @@ fflush(stderr);
if(command == 3) {
param->ctrlsock = param->clisock;
#ifdef __linux__
if(param->srv->i_nsfd >= 0) {
if(param->srv->saved_nsfd >= 0 && setns(param->srv->saved_nsfd, CLONE_NEWNET)) {RETURN(11);}
if(setns(param->srv->i_nsfd, CLONE_NEWNET)) {RETURN(11);}
}
if(switch_ns(param->srv, param->srv->i_nsfd)) {RETURN(11);}
#endif
param->clisock = param->srv->so._socket(param->sostate, SASOCK(&param->sincr), SOCK_DGRAM, IPPROTO_UDP);
if(param->clisock == INVALID_SOCKET) {RETURN(11);}

View File

@ -201,11 +201,13 @@ int udpsockmap(struct clientparam *param, int timeo)
sendlen = len + hdrsize;
} else if (nhops >= 2) {
int off = 0, k;
int bad = 0;
for (k = 1; k < nhops; k++) {
int next = socks5_udp_skip_hdr(param->srvbuf + off, len - off);
if (next < 0) break;
if (next < 0) { bad = 1; break; }
off += next;
}
if (bad) continue;
sendoff = off;
sendlen = len - off;
}