mirror of
https://github.com/3proxy/3proxy.git
synced 2026-05-31 13:30:11 +08:00
Minor cleanups
This commit is contained in:
parent
381ef993a7
commit
05c4832c6c
@ -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 *) ¶m->msec_start, sizeof(param->msec_start)) & 0xff;
|
||||
random_vector_pool[i] += myrand() & 0xff;
|
||||
}
|
||||
did_random = 1;
|
||||
|
||||
|
||||
55
src/common.c
55
src/common.c
@ -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
|
||||
|
||||
41
src/conf.c
41
src/conf.c
@ -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, ".");
|
||||
|
||||
38
src/ftp.c
38
src/ftp.c
@ -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(¶m->req) = *SAPORT(¶m->sinsr) = htons((uint16_t)((b5<<8)^b6));
|
||||
*SAPORT(¶m->req) = *SAPORT(¶m->sinsr) = htons((uint16_t)(((b5 & 0xff)<<8) | (b6 & 0xff)));
|
||||
*SAPORT(¶m->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;
|
||||
|
||||
@ -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));
|
||||
|
||||
|
||||
183
src/proxy.c
183
src/proxy.c
@ -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(¶m->sincr) == AF_INET6) len += sprintf((char*)buf + len, "\"[");
|
||||
len += myinet_ntop(*SAFAMILY(¶m->sincr), SAADDR(¶m->sincr), (char *)buf + len, 128);
|
||||
if(*SAFAMILY(¶m->sincr) == AF_INET6) len += sprintf((char*)buf + len, "]:%d\";by=", (int)ntohs(*SAPORT(¶m->sincr)));
|
||||
else len += sprintf((char*)buf + len, ":%d;by=", (int)ntohs(*SAPORT(¶m->sincr)));
|
||||
gethostname((char *)(buf + len), 256);
|
||||
sprintf((char*)buf+strlen((char *)buf), ":%d\r\n", (int)ntohs(*SAPORT(¶m->sincl)));
|
||||
hlen += sprintf((char*)buf + hlen, "Forwarded: for=");
|
||||
if(*SAFAMILY(¶m->sincr) == AF_INET6) hlen += sprintf((char*)buf + hlen, "\"[");
|
||||
hlen += myinet_ntop(*SAFAMILY(¶m->sincr), SAADDR(¶m->sincr), (char *)buf + hlen, 128);
|
||||
if(*SAFAMILY(¶m->sincr) == AF_INET6) hlen += sprintf((char*)buf + hlen, "]:%d\";by=", (int)ntohs(*SAPORT(¶m->sincr)));
|
||||
else hlen += sprintf((char*)buf + hlen, ":%d;by=", (int)ntohs(*SAPORT(¶m->sincr)));
|
||||
gethostname((char *)(buf + hlen), 256);
|
||||
hlen += (int)strlen((char *)(buf + hlen));
|
||||
hlen += sprintf((char*)buf + hlen, ":%d\r\n", (int)ntohs(*SAPORT(¶m->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(¶m->srv->intsa)), conf.stringtable?conf.stringtable[2]:(unsigned char *)"", conf.stringtable?conf.stringtable[3]:(unsigned char *)"");
|
||||
if(anonymous != 2)myinet_ntop(*SAFAMILY(¶m->sincr), SAADDR(¶m->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(¶m->srv->intsa)), conf.stringtable?conf.stringtable[2]:(unsigned char *)"", conf.stringtable?conf.stringtable[3]:(unsigned char *)"");
|
||||
if(anonymous != 2)hlen += myinet_ntop(*SAFAMILY(¶m->sincr), SAADDR(¶m->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]);
|
||||
}
|
||||
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]);
|
||||
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]);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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(¶m->sincr, sizeof(param->sincr));
|
||||
else if(i==6) myrand(¶m->req, sizeof(param->req));
|
||||
|
||||
if(i*16 >= cur->cidr) ((uint16_t *)SAADDR(¶m->sinsl))[i] |= rand();
|
||||
if(i*16 >= cur->cidr) ((uint16_t *)SAADDR(¶m->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(¶m->sinsl))[i]);
|
||||
((uint16_t *)SAADDR(¶m->sinsl))[i] = htons(c);
|
||||
|
||||
@ -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;
|
||||
|
||||
47
src/socks.c
47
src/socks.c
@ -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);
|
||||
@ -203,28 +209,23 @@ void * sockschild(struct clientparam* param) {
|
||||
#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(¶m->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(¶m->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(¶m->req), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);}
|
||||
}
|
||||
|
||||
if(command > 1) {
|
||||
if(param->srv->so._bind(param->sostate, param->remsock,(struct sockaddr *)¶m->sinsl,SASIZE(¶m->sinsl))) {
|
||||
*SAPORT(¶m->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(¶m->sincr), SOCK_DGRAM, IPPROTO_UDP);
|
||||
if(param->clisock == INVALID_SOCKET) {RETURN(11);}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user