Explorar el Código

Name resolution via TCP support

Supports _real_ name resolution via parent proxy over TCP in nserver /
dnspr.
Can be used to create UDP->TCP name proxy, e.g.

nserver 127.0.0.1/tcp
nscache 65535
auth none
dnspr
auth iponly
tcppm 53 77.88.8.8 53

now, all names are resolved via TCP connection to 77.88.8.8
(dns.yandex.ru).
z3APA3A hace 11 años
padre
commit
15f9f24f04
Se han modificado 9 ficheros con 96 adiciones y 37 borrados
  1. 9 2
      src/3proxy.c
  2. 45 13
      src/auth.c
  3. 1 1
      src/common.c
  4. 30 15
      src/dnspr.c
  5. 1 1
      src/proxy.h
  6. 1 1
      src/socks.c
  7. 6 1
      src/structures.h
  8. 2 2
      src/udppm.c
  9. 1 1
      src/version.h

+ 9 - 2
src/3proxy.c

@@ -1003,10 +1003,17 @@ 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] && res < MAXNSERVERS; res++);
+	for(res = 0; nservers[res].ip && res < MAXNSERVERS; res++);
 	if(res < MAXNSERVERS) {
-		nservers[res] = getip(argv[1]);
+		if((str = strchr((char *)argv[1], '/')))
+			*str = 0;
+		nservers[res].ip = getip(argv[1]);
+		if(str) {
+			nservers[res].usetcp = strstr(str + 1, "tcp")? 1:0;
+			*str = '/';
+		}
 	}
 	resolvfunc = myresolver;
 	return 0;

+ 45 - 13
src/auth.c

@@ -950,7 +950,8 @@ unsigned long hashresolv(struct hashtable *ht, const unsigned char* name, unsign
 	return 0;
 }
 
-unsigned long nservers[MAXNSERVERS] = {0, 0, 0, 0, 0};
+struct nserver nservers[MAXNSERVERS] = {{0,0}, {0,0}, {0,0}, {0,0}, {0,0}};
+int tcpresolve = 0;
 
 unsigned long authnserver;
 
@@ -964,34 +965,53 @@ unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientpa
 		return retval;
 	}
 	
-	for(i=0; (i<(makeauth && authnserver)? 1 : MAXNSERVERS) && ((makeauth && authnserver) || nservers[i]); i++){
+	for(i=0; (i<(makeauth && authnserver)? 1 : MAXNSERVERS) && ((makeauth && authnserver) || nservers[i].ip); i++){
 		unsigned short nquery, nq, na;
-		unsigned char buf[4096], *s1, *s2;
+		unsigned char b[4098], *buf, *s1, *s2;
 		int j, k, len, flen;
 		SOCKET sock;
 		unsigned ttl;
 		time_t t;
 		struct sockaddr_in sin, *sinsp;
+		int usetcp = 0;
 
-		memset(&sin, 0, sizeof(sin));
-		sinsp = (param && !makeauth && *SAFAMILY(&param->sinsr) == AF_INET)? (struct sockaddr_in *)&param->sinsr : &sin;
+		buf = b+2;
+
+		sinsp = (param && !makeauth)? (struct sockaddr_in *)&param->sinsr : &sin;
+		memset(sinsp, 0, sizeof(struct sockaddr_in));
 		
 
-		if((sock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) break;
+		if(makeauth && authnserver){
+			if((sock=so._socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) break;
+		}
+		else {
+			usetcp = nservers[i].usetcp;
+			if((sock=so._socket(PF_INET, usetcp?SOCK_STREAM:SOCK_DGRAM, usetcp?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) break;
+		}
 		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,(struct sockaddr *)sinsp,sizeof(struct sockaddr_in))){
 			so._shutdown(sock, SHUT_RDWR);
 			so._closesocket(sock);
 			break;
 		}
-		sinsp->sin_addr.s_addr = (makeauth && authnserver)?authnserver : nservers[i];
+		if(makeauth && authnserver){
+			sinsp->sin_addr.s_addr = authnserver;
+		}
+		else {
+			sinsp->sin_addr.s_addr = nservers[i].ip;
+		}
 		sinsp->sin_port = htons(53);
-
+		if(usetcp){
+			if(so._connect(sock,(struct sockaddr *)sinsp,sizeof(struct sockaddr_in))) {
+				so._shutdown(sock, SHUT_RDWR);
+				so._closesocket(sock);
+				break;
+			}
+		}
 		len = (int)strlen((char *)name);
-		nquery = myrand(name, len);
-		*(unsigned short*)buf = nquery; /* query id */
+		*(unsigned short*)buf = htons(i+1); /* query id */
 		buf[2] = 1; 			/* recursive */
 		buf[3] = 0;
 		buf[4] = 0;
@@ -1012,6 +1032,12 @@ unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientpa
 		buf[len++] = (makeauth == 1)? 0x0c : 0x01;	/* PTR:host address */
 		buf[len++] = 0;
 		buf[len++] = 1;			/* INET */
+		if(usetcp){
+			buf-=2;
+			*(unsigned short*)buf = htons(len);
+			len+=2;
+		}
+
 		if(socksendto(sock, (struct sockaddr *)sinsp, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
 			so._shutdown(sock, SHUT_RDWR);
 			so._closesocket(sock);
@@ -1021,9 +1047,15 @@ unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientpa
 		len = sockrecvfrom(sock, (struct sockaddr *) sinsp, buf, 4096, 15000);
 		so._shutdown(sock, SHUT_RDWR);
 		so._closesocket(sock);
-		if(len <= 13) continue;
+		if(len <= 13) {
+			continue;
+		}
 		if(param) param->statssrv64 += len;
-		if(*(unsigned short *)buf != nquery)continue;
+		if(usetcp){
+			buf+=2;
+			len-=2;
+		}
+		if(*(unsigned short *)buf != htons(i+1))continue;
 		if((na = buf[7] + (((unsigned short)buf[6])<<8)) < 1) {
 			return 0;
 		}

+ 1 - 1
src/common.c

@@ -617,7 +617,7 @@ int doconnect(struct clientparam * param){
 		memcpy(SAADDR(&param->sinsr), SAADDR(&param->req), SAADDRLEN(&param->req)); 
 	}
 	if(!*SAPORT(&param->sinsr))*SAPORT(&param->sinsr) = *SAPORT(&param->req);
-	if ((param->remsock=so._socket(*SAFAMILY(&param->sinsr), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {return (11);}
+	if ((param->remsock=so._socket(SASOCK(&param->sinsr), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {return (11);}
 	so._setsockopt(param->remsock, SOL_SOCKET, SO_LINGER, (unsigned char *)&lg, sizeof(lg));
 #ifndef NOIPV6
 	if(*SAFAMILY(&param->sinsr) == AF_INET6) memcpy(&param->sinsl, &param->srv->extsa6, sizeof(param->srv->extsa6));

+ 30 - 15
src/dnspr.c

@@ -14,11 +14,12 @@
 #endif
 #define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
 
-#define BUFSIZE 4096
+#define BUFSIZE 16384
 
 
 void * dnsprchild(struct clientparam* param) {
  unsigned long ip = 0;
+ unsigned char *bbuf;
  unsigned char *buf, *s1, *s2;
  char * host = NULL;
  unsigned char c;
@@ -32,10 +33,11 @@ void * dnsprchild(struct clientparam* param) {
 #endif
 
 
- if(!(buf = myalloc(BUFSIZE))){
+ 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 *)&param->sincr, &size); 
 #ifdef _WIN32
@@ -44,9 +46,9 @@ void * dnsprchild(struct clientparam* param) {
 	}
 	ioctlsocket(param->clisock, FIONBIO, &ul);
 	size = sizeof(param->sinsl);
-	if(so._getsockname(param->srv->srvsock, (struct sockaddr *)&param->sinsl, &size)) {RETURN(21);};
+	if(so._getsockname(param->srv->srvsock, (struct sockaddr *)&param->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 *)&param->sinsl,sizeof(param->sinsl))) {
+	if(so._bind(param->clisock,(struct sockaddr *)&param->sincl,sizeof(param->sincl))) {
 		RETURN(822);
 	}
 
@@ -103,7 +105,7 @@ void * dnsprchild(struct clientparam* param) {
 	memcpy(buf+len+12,(void *)&ip,4);
 	len+=16;
  }
- if(type == 0x0c) {
+ 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);
@@ -127,15 +129,10 @@ void * dnsprchild(struct clientparam* param) {
 	}
 	else ip = 0;
  }
- if(!ip && nservers[0] && type!=1){
-	if((param->remsock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
+ if(!ip && nservers[0].ip && type!=1){
+	if((param->remsock=so._socket(PF_INET, nservers[0].usetcp? SOCK_STREAM:SOCK_DGRAM, nservers[0].usetcp?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) {
 		RETURN(818);
 	}
-#ifdef _WIN32
-	ioctlsocket(param->remsock, FIONBIO, &ul);
-#else
-	fcntl(param->remsock,F_SETFL,O_NONBLOCK);
-#endif
 	*SAFAMILY(&param->sinsl) = AF_INET;
 	*SAPORT(&param->sinsl) = htons(0);
 	*(unsigned long*)SAADDR(&param->sinsl) = htonl(0);
@@ -143,8 +140,22 @@ void * dnsprchild(struct clientparam* param) {
 		RETURN(819);
 	}
 	*SAFAMILY(&param->sinsr) = AF_INET;
-	*(unsigned long*)SAADDR(&param->sinsr) = nservers[0];
+	*(unsigned long*)SAADDR(&param->sinsr) = nservers[0].ip;
 	*SAPORT(&param->sinsr) = htons(53);
+	if(nservers[0].usetcp) {
+		if(so._connect(param->remsock,(struct sockaddr *)&param->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 *)&param->sinsr, buf, i, conf.timeouts[SINGLEBYTE_L]*1000) != i){
 		RETURN(820);
 	}
@@ -156,6 +167,10 @@ void * dnsprchild(struct clientparam* param) {
 	}
 	param->statssrv64 += len;
 	param->nreads++;
+	if(nservers[0].usetcp) {
+		buf += 2;
+		len -= 2;
+	}
 	if(buf[6] || buf[7]){
 		if(socksendto(param->clisock, (struct sockaddr *)&param->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
 			RETURN(822);
@@ -168,7 +183,7 @@ void * dnsprchild(struct clientparam* param) {
 	buf[2] = 0x85;
 	buf[3] = 0x83;
  }
- usleep(SLEEPTIME);
+ /* usleep(SLEEPTIME); */
  res = socksendto(param->clisock, (struct sockaddr *)&param->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000); 
  if(res != len){RETURN(819);}
  if(!ip) {RETURN(888);}
@@ -186,7 +201,7 @@ CLEANRET:
 	);
 	(*param->srv->logfunc)(param, buf);
  }
- if(buf)myfree(buf);
+ if(bbuf)myfree(bbuf);
  if(host)myfree(host);
 #ifndef _WIN32
  param->clisock = INVALID_SOCKET;

+ 1 - 1
src/proxy.h

@@ -184,7 +184,7 @@ unsigned bandlimitfunc(struct clientparam *param, unsigned nbytesin, unsigned nb
 
 int scanaddr(const unsigned char *s, unsigned long * ip, unsigned long * mask);
 int myinet_ntop(int af, void *src, char *dst, socklen_t size);
-extern unsigned long nservers[MAXNSERVERS];
+extern struct nserver nservers[MAXNSERVERS];
 extern unsigned long authnserver;
 unsigned long getip(unsigned char *name);
 unsigned long getip46(int family, unsigned char *name,  struct sockaddr *sa);

+ 1 - 1
src/socks.c

@@ -160,7 +160,7 @@ void * sockschild(struct clientparam* param) {
 	 memcpy(&param->sinsl, &param->srv->extsa, SASIZE(&param->req)); 
 #endif
 	 if(!*SAPORT(&param->sinsl))*SAPORT(&param->sinsl) = port;
-	 if ((param->remsock=so._socket(*SAFAMILY(&param->req), command == 2? SOCK_STREAM:SOCK_DGRAM, command == 2?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);}
+	 if ((param->remsock=so._socket(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;
 	 break;
 

+ 6 - 1
src/structures.h

@@ -297,6 +297,11 @@ struct trafcount {
 	time_t updated;
 };
 
+struct nserver {
+	unsigned long ip;
+	int usetcp;
+};
+
 typedef void * (* PROXYFUNC)(struct clientparam *);
 
 typedef enum {
@@ -623,7 +628,7 @@ extern struct sockfuncs so;
 struct pluginlink {
 	struct symbol symbols;
 	struct extparam *conf;
-	unsigned long *nservers;
+	struct nserver *nservers;
 	int * linenum;
 	struct auth *authfuncs;
 	struct commands * commandhandlers;

+ 2 - 2
src/udppm.c

@@ -57,7 +57,7 @@ void * udppmchild(struct clientparam* param) {
  param->cliinbuf = i;
 
 #ifdef _WIN32
-	if((param->clisock=so._socket(*SAFAMILY(&param->sincr), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
+	if((param->clisock=so._socket(SASOCK(&param->sincr), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
 		RETURN(818);
 	}
 	if(so._setsockopt(param->clisock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&ul, sizeof(int))) {RETURN(820);};
@@ -77,7 +77,7 @@ void * udppmchild(struct clientparam* param) {
  memcpy(&param->sinsl, &param->srv->extsa, SASIZE(&param->req));
 #endif
  *SAPORT(&param->sinsl) = 0;
- if ((param->remsock=so._socket(*SAFAMILY(&param->sinsl), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);}
+ if ((param->remsock=so._socket(SASOCK(&param->sinsl), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);}
  if(so._bind(param->remsock,(struct sockaddr *)&param->sinsl,sizeof(param->sinsl))) {RETURN (12);}
 #ifdef _WIN32
 	ioctlsocket(param->remsock, FIONBIO, &ul);

+ 1 - 1
src/version.h

@@ -1,2 +1,2 @@
 #define VERSION "3proxy-0.8b-devel"
-#define BUILDDATE "141210181747"
+#define BUILDDATE "141211025611"