mirror of
https://github.com/3proxy/3proxy.git
synced 2025-02-23 10:35: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){
|
||||
int res;
|
||||
char *str;
|
||||
|
||||
for(res = 0; nservers[res].ip && res < MAXNSERVERS; res++);
|
||||
if(res < MAXNSERVERS) {
|
||||
if(numservers < MAXNSERVERS) {
|
||||
if((str = strchr((char *)argv[1], '/')))
|
||||
*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) {
|
||||
nservers[res].usetcp = strstr(str + 1, "tcp")? 1:0;
|
||||
nservers[numservers].usetcp = strstr(str + 1, "tcp")? 1:0;
|
||||
*str = '/';
|
||||
}
|
||||
numservers++;
|
||||
|
||||
}
|
||||
resolvfunc = myresolver;
|
||||
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;
|
||||
}
|
||||
|
||||
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 udpresolve(unsigned char * name, unsigned *retttl, struct clientparam* param, int makeauth){
|
||||
|
||||
int i;
|
||||
int i,n;
|
||||
unsigned long retval;
|
||||
|
||||
if((retval = hashresolv(&dns_table, name, retttl))) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
for(i=0; (i<(makeauth && authnserver)? 1 : MAXNSERVERS) && ((makeauth && authnserver) || nservers[i].ip); i++){
|
||||
n = (makeauth && authnserver)? 1 : numservers;
|
||||
for(i=0; i<n; i++){
|
||||
unsigned short nq, na;
|
||||
unsigned char b[4098], *buf, *s1, *s2;
|
||||
int j, k, len, flen;
|
||||
SOCKET sock;
|
||||
unsigned ttl;
|
||||
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;
|
||||
unsigned short serial = 1;
|
||||
|
||||
buf = b+2;
|
||||
|
||||
sinsp = (param && !makeauth)? (struct sockaddr_in *)¶m->sinsr : &sin;
|
||||
memset(sinsp, 0, sizeof(struct sockaddr_in));
|
||||
sinsl = (param && !makeauth)? (struct sockaddr *)¶m->sinsl : (struct sockaddr *)&addr;
|
||||
sinsr = (param && !makeauth)? (struct sockaddr *)¶m->sinsr : (struct sockaddr *)&addr;
|
||||
memset(sinsl, 0, sizeof(addr));
|
||||
memset(sinsr, 0, sizeof(addr));
|
||||
|
||||
|
||||
if(makeauth && authnserver){
|
||||
if((sock=so._socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) break;
|
||||
*SAFAMILY(sinsl) = AF_INET;
|
||||
*SAFAMILY(sinsr) = AF_INET;
|
||||
}
|
||||
else {
|
||||
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;
|
||||
sinsp->sin_port = htons(0);
|
||||
sinsp->sin_addr.s_addr = htonl(0);
|
||||
if(so._bind(sock,(struct sockaddr *)sinsp,sizeof(struct sockaddr_in))){
|
||||
if(so._bind(sock,sinsl,sizeof(addr))){
|
||||
so._shutdown(sock, SHUT_RDWR);
|
||||
so._closesocket(sock);
|
||||
break;
|
||||
}
|
||||
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 {
|
||||
sinsp->sin_addr.s_addr = nservers[i].ip;
|
||||
memcpy(sinsr, &nservers[i].addr, sizeof(addr));
|
||||
}
|
||||
sinsp->sin_port = htons(53);
|
||||
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._closesocket(sock);
|
||||
break;
|
||||
@ -1040,13 +1047,13 @@ unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientpa
|
||||
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._closesocket(sock);
|
||||
continue;
|
||||
}
|
||||
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._closesocket(sock);
|
||||
if(len <= 13) {
|
||||
@ -1054,8 +1061,13 @@ unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientpa
|
||||
}
|
||||
if(param) param->statssrv64 += len;
|
||||
if(usetcp){
|
||||
buf+=2;
|
||||
unsigned short us;
|
||||
us = ntohs(*(unsigned short*)buf);
|
||||
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((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 i;
|
||||
unsigned short init;
|
||||
|
25
src/dnspr.c
25
src/dnspr.c
@ -40,13 +40,13 @@ void * dnsprchild(struct clientparam* param) {
|
||||
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);
|
||||
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._bind(param->clisock,(struct sockaddr *)¶m->sincl,sizeof(param->sincl))) {
|
||||
RETURN(822);
|
||||
@ -109,7 +109,7 @@ void * dnsprchild(struct clientparam* param) {
|
||||
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->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[3] = 0x80;
|
||||
buf[6] = 0;
|
||||
@ -129,19 +129,16 @@ void * dnsprchild(struct clientparam* param) {
|
||||
}
|
||||
else ip = 0;
|
||||
}
|
||||
if(!ip && nservers[0].ip){
|
||||
if((param->remsock=so._socket(PF_INET, nservers[0].usetcp? SOCK_STREAM:SOCK_DGRAM, nservers[0].usetcp?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) {
|
||||
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);
|
||||
}
|
||||
*SAFAMILY(¶m->sinsl) = AF_INET;
|
||||
*SAPORT(¶m->sinsl) = htons(0);
|
||||
*(unsigned long*)SAADDR(¶m->sinsl) = htonl(0);
|
||||
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);
|
||||
}
|
||||
*SAFAMILY(¶m->sinsr) = AF_INET;
|
||||
*(unsigned long*)SAADDR(¶m->sinsr) = nservers[0].ip;
|
||||
*SAPORT(¶m->sinsr) = htons(53);
|
||||
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;
|
||||
@ -168,8 +165,13 @@ void * dnsprchild(struct clientparam* param) {
|
||||
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){
|
||||
@ -183,7 +185,6 @@ void * dnsprchild(struct clientparam* param) {
|
||||
buf[2] = 0x85;
|
||||
buf[3] = 0x83;
|
||||
}
|
||||
/* usleep(SLEEPTIME); */
|
||||
res = socksendto(param->clisock, (struct sockaddr *)¶m->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000);
|
||||
if(res != len){RETURN(819);}
|
||||
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_OOBINLINE, (unsigned char *)&opt, sizeof(int));
|
||||
}
|
||||
else
|
||||
else {
|
||||
srv.fds.events = 0;
|
||||
}
|
||||
if(! (newparam = myalloc (sizeof(defparam)))){
|
||||
if(!isudp) so._closesocket(new_sock);
|
||||
defparam.res = 21;
|
||||
@ -896,6 +897,7 @@ void freeconf(struct extparam *confp){
|
||||
confp->singlepacket = 0;
|
||||
confp->maxchild = 100;
|
||||
resolvfunc = NULL;
|
||||
numservers = 0;
|
||||
acl = confp->acl;
|
||||
confp->acl = NULL;
|
||||
confp->logtime = confp->time = 0;
|
||||
@ -927,6 +929,7 @@ void freeconf(struct extparam *confp){
|
||||
for(i = 0; i < archiverc; i++) myfree(archiver[i]);
|
||||
myfree(archiver);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 {
|
||||
unsigned long ip;
|
||||
#ifndef NOIPV6
|
||||
struct sockaddr_in6 addr;
|
||||
#else
|
||||
struct sockaddr_in addr;
|
||||
#endif
|
||||
int usetcp;
|
||||
};
|
||||
extern int numservers;
|
||||
|
||||
typedef void * (* PROXYFUNC)(struct clientparam *);
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
#define VERSION "3proxy-0.8b-devel"
|
||||
#define BUILDDATE "141212231810"
|
||||
#define BUILDDATE "141213035229"
|
||||
|
Loading…
Reference in New Issue
Block a user