mirror of
https://github.com/3proxy/3proxy.git
synced 2025-02-23 18:45:40 +08:00
nserver address may be given as IPv6
This commit is contained in:
parent
a4cb2f36b5
commit
042fc2afde
11
src/3proxy.c
11
src/3proxy.c
@ -1003,18 +1003,19 @@ static int h_flushusers(int argc, unsigned char **argv){
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static int h_nserver(int argc, unsigned char **argv){
|
static int h_nserver(int argc, unsigned char **argv){
|
||||||
int res;
|
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
for(res = 0; nservers[res].ip && res < MAXNSERVERS; res++);
|
if(numservers < MAXNSERVERS) {
|
||||||
if(res < MAXNSERVERS) {
|
|
||||||
if((str = strchr((char *)argv[1], '/')))
|
if((str = strchr((char *)argv[1], '/')))
|
||||||
*str = 0;
|
*str = 0;
|
||||||
nservers[res].ip = getip(argv[1]);
|
if(!getip46(46, argv[1], (struct sockaddr *)&nservers[numservers].addr)) return 1;
|
||||||
|
*SAPORT(&nservers[numservers].addr) = htons(53);
|
||||||
if(str) {
|
if(str) {
|
||||||
nservers[res].usetcp = strstr(str + 1, "tcp")? 1:0;
|
nservers[numservers].usetcp = strstr(str + 1, "tcp")? 1:0;
|
||||||
*str = '/';
|
*str = '/';
|
||||||
}
|
}
|
||||||
|
numservers++;
|
||||||
|
|
||||||
}
|
}
|
||||||
resolvfunc = myresolver;
|
resolvfunc = myresolver;
|
||||||
return 0;
|
return 0;
|
||||||
|
52
src/auth.c
52
src/auth.c
@ -950,61 +950,68 @@ unsigned long hashresolv(struct hashtable *ht, const unsigned char* name, unsign
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct nserver nservers[MAXNSERVERS] = {{0,0}, {0,0}, {0,0}, {0,0}, {0,0}};
|
struct nserver nservers[MAXNSERVERS] = {{{0},0}, {{0},0}, {{0},0}, {{0},0}, {{0},0}};
|
||||||
|
|
||||||
unsigned long authnserver;
|
unsigned long authnserver;
|
||||||
|
|
||||||
|
|
||||||
unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientparam* param, int makeauth){
|
unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientparam* param, int makeauth){
|
||||||
|
|
||||||
int i;
|
int i,n;
|
||||||
unsigned long retval;
|
unsigned long retval;
|
||||||
|
|
||||||
if((retval = hashresolv(&dns_table, name, retttl))) {
|
if((retval = hashresolv(&dns_table, name, retttl))) {
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
n = (makeauth && authnserver)? 1 : numservers;
|
||||||
for(i=0; (i<(makeauth && authnserver)? 1 : MAXNSERVERS) && ((makeauth && authnserver) || nservers[i].ip); i++){
|
for(i=0; i<n; i++){
|
||||||
unsigned short nq, na;
|
unsigned short nq, na;
|
||||||
unsigned char b[4098], *buf, *s1, *s2;
|
unsigned char b[4098], *buf, *s1, *s2;
|
||||||
int j, k, len, flen;
|
int j, k, len, flen;
|
||||||
SOCKET sock;
|
SOCKET sock;
|
||||||
unsigned ttl;
|
unsigned ttl;
|
||||||
time_t t;
|
time_t t;
|
||||||
struct sockaddr_in sin, *sinsp;
|
#ifndef NOIPV6
|
||||||
|
struct sockaddr_in6 addr;
|
||||||
|
#else
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
#endif
|
||||||
|
struct sockaddr *sinsr, *sinsl;
|
||||||
int usetcp = 0;
|
int usetcp = 0;
|
||||||
unsigned short serial = 1;
|
unsigned short serial = 1;
|
||||||
|
|
||||||
buf = b+2;
|
buf = b+2;
|
||||||
|
|
||||||
sinsp = (param && !makeauth)? (struct sockaddr_in *)¶m->sinsr : &sin;
|
sinsl = (param && !makeauth)? (struct sockaddr *)¶m->sinsl : (struct sockaddr *)&addr;
|
||||||
memset(sinsp, 0, sizeof(struct sockaddr_in));
|
sinsr = (param && !makeauth)? (struct sockaddr *)¶m->sinsr : (struct sockaddr *)&addr;
|
||||||
|
memset(sinsl, 0, sizeof(addr));
|
||||||
|
memset(sinsr, 0, sizeof(addr));
|
||||||
|
|
||||||
|
|
||||||
if(makeauth && authnserver){
|
if(makeauth && authnserver){
|
||||||
if((sock=so._socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) break;
|
if((sock=so._socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) break;
|
||||||
|
*SAFAMILY(sinsl) = AF_INET;
|
||||||
|
*SAFAMILY(sinsr) = AF_INET;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
usetcp = nservers[i].usetcp;
|
usetcp = nservers[i].usetcp;
|
||||||
if((sock=so._socket(PF_INET, usetcp?SOCK_STREAM:SOCK_DGRAM, usetcp?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) break;
|
if((sock=so._socket(SASOCK(&nservers[i].addr), usetcp?SOCK_STREAM:SOCK_DGRAM, usetcp?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) break;
|
||||||
|
*SAFAMILY(sinsl) = *SAFAMILY(&nservers[i].addr);
|
||||||
|
|
||||||
}
|
}
|
||||||
sinsp->sin_family = AF_INET;
|
if(so._bind(sock,sinsl,sizeof(addr))){
|
||||||
sinsp->sin_port = htons(0);
|
|
||||||
sinsp->sin_addr.s_addr = htonl(0);
|
|
||||||
if(so._bind(sock,(struct sockaddr *)sinsp,sizeof(struct sockaddr_in))){
|
|
||||||
so._shutdown(sock, SHUT_RDWR);
|
so._shutdown(sock, SHUT_RDWR);
|
||||||
so._closesocket(sock);
|
so._closesocket(sock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(makeauth && authnserver){
|
if(makeauth && authnserver){
|
||||||
sinsp->sin_addr.s_addr = authnserver;
|
((struct sockaddr_in *)sinsr)->sin_addr.s_addr = authnserver;
|
||||||
|
((struct sockaddr_in *)sinsr)->sin_port = htons(53);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sinsp->sin_addr.s_addr = nservers[i].ip;
|
memcpy(sinsr, &nservers[i].addr, sizeof(addr));
|
||||||
}
|
}
|
||||||
sinsp->sin_port = htons(53);
|
|
||||||
if(usetcp){
|
if(usetcp){
|
||||||
if(so._connect(sock,(struct sockaddr *)sinsp,sizeof(struct sockaddr_in))) {
|
if(so._connect(sock,sinsr,sizeof(addr))) {
|
||||||
so._shutdown(sock, SHUT_RDWR);
|
so._shutdown(sock, SHUT_RDWR);
|
||||||
so._closesocket(sock);
|
so._closesocket(sock);
|
||||||
break;
|
break;
|
||||||
@ -1040,13 +1047,13 @@ unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientpa
|
|||||||
len+=2;
|
len+=2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(socksendto(sock, (struct sockaddr *)sinsp, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
|
if(socksendto(sock, sinsr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
|
||||||
so._shutdown(sock, SHUT_RDWR);
|
so._shutdown(sock, SHUT_RDWR);
|
||||||
so._closesocket(sock);
|
so._closesocket(sock);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(param) param->statscli64 += len;
|
if(param) param->statscli64 += len;
|
||||||
len = sockrecvfrom(sock, (struct sockaddr *) sinsp, buf, 4096, 15000);
|
len = sockrecvfrom(sock, sinsr, buf, 4096, 15000);
|
||||||
so._shutdown(sock, SHUT_RDWR);
|
so._shutdown(sock, SHUT_RDWR);
|
||||||
so._closesocket(sock);
|
so._closesocket(sock);
|
||||||
if(len <= 13) {
|
if(len <= 13) {
|
||||||
@ -1054,8 +1061,13 @@ unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientpa
|
|||||||
}
|
}
|
||||||
if(param) param->statssrv64 += len;
|
if(param) param->statssrv64 += len;
|
||||||
if(usetcp){
|
if(usetcp){
|
||||||
buf+=2;
|
unsigned short us;
|
||||||
|
us = ntohs(*(unsigned short*)buf);
|
||||||
len-=2;
|
len-=2;
|
||||||
|
buf+=2;
|
||||||
|
if(us > 4096 || us < len || (us > len && sockrecvfrom(sock, sinsr, buf+len, us-len, 15000) != us-len)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(*(unsigned short *)buf != serial)continue;
|
if(*(unsigned short *)buf != serial)continue;
|
||||||
if((na = buf[7] + (((unsigned short)buf[6])<<8)) < 1) {
|
if((na = buf[7] + (((unsigned short)buf[6])<<8)) < 1) {
|
||||||
|
@ -88,6 +88,8 @@ struct extparam conf = {
|
|||||||
'@'
|
'@'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int numservers=0;
|
||||||
|
|
||||||
int myrand(void * entropy, int len){
|
int myrand(void * entropy, int len){
|
||||||
int i;
|
int i;
|
||||||
unsigned short init;
|
unsigned short init;
|
||||||
|
25
src/dnspr.c
25
src/dnspr.c
@ -40,13 +40,13 @@ void * dnsprchild(struct clientparam* param) {
|
|||||||
buf = bbuf+2;
|
buf = bbuf+2;
|
||||||
size = sizeof(param->sincr);
|
size = sizeof(param->sincr);
|
||||||
i = so._recvfrom(param->srv->srvsock, buf, BUFSIZE, 0, (struct sockaddr *)¶m->sincr, &size);
|
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
|
#ifdef _WIN32
|
||||||
if((param->clisock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
|
if((param->clisock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
|
||||||
RETURN(818);
|
RETURN(818);
|
||||||
}
|
}
|
||||||
ioctlsocket(param->clisock, FIONBIO, &ul);
|
ioctlsocket(param->clisock, FIONBIO, &ul);
|
||||||
size = sizeof(param->sinsl);
|
|
||||||
if(so._getsockname(param->srv->srvsock, (struct sockaddr *)¶m->sincl, &size)) {RETURN(21);};
|
|
||||||
if(so._setsockopt(param->clisock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&ul, sizeof(int))) {RETURN(820);};
|
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))) {
|
if(so._bind(param->clisock,(struct sockaddr *)¶m->sincl,sizeof(param->sincl))) {
|
||||||
RETURN(822);
|
RETURN(822);
|
||||||
@ -109,7 +109,7 @@ void * dnsprchild(struct clientparam* param) {
|
|||||||
unsigned a, b, c, d;
|
unsigned a, b, c, d;
|
||||||
sscanf(host, "%u.%u.%u.%u", &a, &b, &c, &d);
|
sscanf(host, "%u.%u.%u.%u", &a, &b, &c, &d);
|
||||||
ip = htonl((d<<24) ^ (c<<16) ^ (b<<8) ^ a);
|
ip = htonl((d<<24) ^ (c<<16) ^ (b<<8) ^ a);
|
||||||
if(*SAFAMILY(¶m->srv->intsa) == AF_INET && ip == *(unsigned long*)SAADDR(¶m->srv->intsa)){
|
if(*SAFAMILY(¶m->sincl) == AF_INET && ip == *(unsigned long*)SAADDR(¶m->sincl)){
|
||||||
buf[2] = 0x85;
|
buf[2] = 0x85;
|
||||||
buf[3] = 0x80;
|
buf[3] = 0x80;
|
||||||
buf[6] = 0;
|
buf[6] = 0;
|
||||||
@ -129,19 +129,16 @@ void * dnsprchild(struct clientparam* param) {
|
|||||||
}
|
}
|
||||||
else ip = 0;
|
else ip = 0;
|
||||||
}
|
}
|
||||||
if(!ip && nservers[0].ip){
|
if(!ip && numservers){
|
||||||
if((param->remsock=so._socket(PF_INET, nservers[0].usetcp? SOCK_STREAM:SOCK_DGRAM, nservers[0].usetcp?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) {
|
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);
|
RETURN(818);
|
||||||
}
|
}
|
||||||
*SAFAMILY(¶m->sinsl) = AF_INET;
|
memset(¶m->sinsl, 0, sizeof(param->sinsl));
|
||||||
*SAPORT(¶m->sinsl) = htons(0);
|
*SAFAMILY(¶m->sinsl) = *SAFAMILY(&nservers[0].addr);
|
||||||
*(unsigned long*)SAADDR(¶m->sinsl) = htonl(0);
|
|
||||||
if(so._bind(param->remsock,(struct sockaddr *)¶m->sinsl,sizeof(param->sinsl))) {
|
if(so._bind(param->remsock,(struct sockaddr *)¶m->sinsl,sizeof(param->sinsl))) {
|
||||||
RETURN(819);
|
RETURN(819);
|
||||||
}
|
}
|
||||||
*SAFAMILY(¶m->sinsr) = AF_INET;
|
memcpy(¶m->sinsr, &nservers[0].addr, sizeof(param->sinsr));
|
||||||
*(unsigned long*)SAADDR(¶m->sinsr) = nservers[0].ip;
|
|
||||||
*SAPORT(¶m->sinsr) = htons(53);
|
|
||||||
if(nservers[0].usetcp) {
|
if(nservers[0].usetcp) {
|
||||||
if(so._connect(param->remsock,(struct sockaddr *)¶m->sinsr,sizeof(param->sinsr))) RETURN(830);
|
if(so._connect(param->remsock,(struct sockaddr *)¶m->sinsr,sizeof(param->sinsr))) RETURN(830);
|
||||||
buf-=2;
|
buf-=2;
|
||||||
@ -168,8 +165,13 @@ void * dnsprchild(struct clientparam* param) {
|
|||||||
param->statssrv64 += len;
|
param->statssrv64 += len;
|
||||||
param->nreads++;
|
param->nreads++;
|
||||||
if(nservers[0].usetcp) {
|
if(nservers[0].usetcp) {
|
||||||
|
unsigned short us;
|
||||||
|
us = ntohs(*(unsigned short *)buf);
|
||||||
|
if(us > 4096) RETURN(833);
|
||||||
buf += 2;
|
buf += 2;
|
||||||
len -= 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(buf[6] || buf[7]){
|
||||||
if(socksendto(param->clisock, (struct sockaddr *)¶m->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
|
if(socksendto(param->clisock, (struct sockaddr *)¶m->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
|
||||||
@ -183,7 +185,6 @@ void * dnsprchild(struct clientparam* param) {
|
|||||||
buf[2] = 0x85;
|
buf[2] = 0x85;
|
||||||
buf[3] = 0x83;
|
buf[3] = 0x83;
|
||||||
}
|
}
|
||||||
/* usleep(SLEEPTIME); */
|
|
||||||
res = socksendto(param->clisock, (struct sockaddr *)¶m->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000);
|
res = socksendto(param->clisock, (struct sockaddr *)¶m->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000);
|
||||||
if(res != len){RETURN(819);}
|
if(res != len){RETURN(819);}
|
||||||
if(!ip) {RETURN(888);}
|
if(!ip) {RETURN(888);}
|
||||||
|
@ -460,8 +460,9 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
so._setsockopt(new_sock, SOL_SOCKET, SO_LINGER, (unsigned char *)&lg, sizeof(lg));
|
so._setsockopt(new_sock, SOL_SOCKET, SO_LINGER, (unsigned char *)&lg, sizeof(lg));
|
||||||
so._setsockopt(new_sock, SOL_SOCKET, SO_OOBINLINE, (unsigned char *)&opt, sizeof(int));
|
so._setsockopt(new_sock, SOL_SOCKET, SO_OOBINLINE, (unsigned char *)&opt, sizeof(int));
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
srv.fds.events = 0;
|
srv.fds.events = 0;
|
||||||
|
}
|
||||||
if(! (newparam = myalloc (sizeof(defparam)))){
|
if(! (newparam = myalloc (sizeof(defparam)))){
|
||||||
if(!isudp) so._closesocket(new_sock);
|
if(!isudp) so._closesocket(new_sock);
|
||||||
defparam.res = 21;
|
defparam.res = 21;
|
||||||
@ -896,6 +897,7 @@ void freeconf(struct extparam *confp){
|
|||||||
confp->singlepacket = 0;
|
confp->singlepacket = 0;
|
||||||
confp->maxchild = 100;
|
confp->maxchild = 100;
|
||||||
resolvfunc = NULL;
|
resolvfunc = NULL;
|
||||||
|
numservers = 0;
|
||||||
acl = confp->acl;
|
acl = confp->acl;
|
||||||
confp->acl = NULL;
|
confp->acl = NULL;
|
||||||
confp->logtime = confp->time = 0;
|
confp->logtime = confp->time = 0;
|
||||||
@ -927,6 +929,7 @@ void freeconf(struct extparam *confp){
|
|||||||
for(i = 0; i < archiverc; i++) myfree(archiver[i]);
|
for(i = 0; i < archiverc; i++) myfree(archiver[i]);
|
||||||
myfree(archiver);
|
myfree(archiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FILTER_ACTION handlereqfilters(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
|
FILTER_ACTION handlereqfilters(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
|
||||||
|
@ -298,9 +298,14 @@ struct trafcount {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct nserver {
|
struct nserver {
|
||||||
unsigned long ip;
|
#ifndef NOIPV6
|
||||||
|
struct sockaddr_in6 addr;
|
||||||
|
#else
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
#endif
|
||||||
int usetcp;
|
int usetcp;
|
||||||
};
|
};
|
||||||
|
extern int numservers;
|
||||||
|
|
||||||
typedef void * (* PROXYFUNC)(struct clientparam *);
|
typedef void * (* PROXYFUNC)(struct clientparam *);
|
||||||
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
#define VERSION "3proxy-0.8b-devel"
|
#define VERSION "3proxy-0.8b-devel"
|
||||||
#define BUILDDATE "141212231810"
|
#define BUILDDATE "141213035229"
|
||||||
|
Loading…
Reference in New Issue
Block a user