dnspr.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. 3APA3A simpliest proxy server
  3. (c) 2002-2008 by ZARAZA <3APA3A@security.nnov.ru>
  4. please read License Agreement
  5. $Id: dnspr.c,v 1.22 2009/09/17 12:21:05 v.dubrovin Exp $
  6. */
  7. #include "proxy.h"
  8. #ifndef UDP
  9. #define UDP
  10. #endif
  11. #define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
  12. #define BUFSIZE 4096
  13. void * dnsprchild(struct clientparam* param) {
  14. unsigned long ip = 0;
  15. unsigned char *buf, *s1, *s2;
  16. char * host = NULL;
  17. unsigned char c;
  18. SASIZETYPE size;
  19. int res, i;
  20. int len;
  21. unsigned type=0;
  22. unsigned ttl;
  23. #ifdef _WIN32
  24. unsigned long ul = 1;
  25. #endif
  26. if(!(buf = myalloc(BUFSIZE))){
  27. param->srv->fds.events = POLLIN;
  28. RETURN (21);
  29. }
  30. size = sizeof(struct sockaddr_in);
  31. i = so._recvfrom(param->srv->srvsock, buf, BUFSIZE, 0, (struct sockaddr *)&param->sinc, &size);
  32. #ifdef _WIN32
  33. if((param->clisock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
  34. RETURN(818);
  35. }
  36. ioctlsocket(param->clisock, FIONBIO, &ul);
  37. size = sizeof(struct sockaddr_in);
  38. if(so._getsockname(param->srv->srvsock, (struct sockaddr *)&param->sins, &size)) {RETURN(21);};
  39. if(so._setsockopt(param->clisock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&ul, sizeof(int))) {RETURN(820);};
  40. if(so._bind(param->clisock,(struct sockaddr *)&param->sins,sizeof(struct sockaddr_in))) {
  41. RETURN(822);
  42. }
  43. #else
  44. param->clisock = param->srv->srvsock;
  45. #endif
  46. param->srv->fds.events = POLLIN;
  47. if(i < 0) {
  48. RETURN(813);
  49. }
  50. buf[BUFSIZE - 1] = 0;
  51. if(i<=13 || i>1000){
  52. RETURN (814);
  53. }
  54. param->operation = DNSRESOLVE;
  55. if((res = (*param->srv->authfunc)(param))) {RETURN(res);}
  56. if(buf[4]!=0 || buf[5]!=1) RETURN(816);
  57. for(len = 12; len<i; len+=(c+1)){
  58. c = buf[len];
  59. if(!c)break;
  60. buf[len] = '.';
  61. }
  62. if(len > (i-4)) {RETURN(817);}
  63. host = mystrdup((char *)buf+13);
  64. if(!host) {RETURN(21);}
  65. for(s2 = buf + 12; (s1 = (unsigned char *)strchr((char *)s2 + 1, '.')); s2 = s1)*s2 = (unsigned char)((s1 - s2) - 1);
  66. *s2 = (len - (int)(s2 - buf)) - 1;
  67. type = ((unsigned)buf[len+1])*256 + (unsigned)buf[len+2];
  68. if(type==1){
  69. ip = udpresolve((unsigned char *)host, &ttl, param, 0);
  70. }
  71. len+=5;
  72. if(ip){
  73. buf[2] = 0x85;
  74. buf[3] = 0x80;
  75. buf[6] = 0;
  76. buf[7] = 1;
  77. buf[8] = buf[9] = buf[10] = buf[11] = 0;
  78. memset(buf+len, 0, 16);
  79. buf[len] = 0xc0;
  80. buf[len+1] = 0x0c;
  81. buf[len+3] = 1;
  82. buf[len+5] = 1;
  83. ttl = htonl(ttl);
  84. memcpy(buf + len + 6, &ttl, 4);
  85. buf[len+11] = 4;
  86. memcpy(buf+len+12,(void *)&ip,4);
  87. len+=16;
  88. }
  89. if(type == 0x0c) {
  90. unsigned a, b, c, d;
  91. sscanf(host, "%u.%u.%u.%u", &a, &b, &c, &d);
  92. ip = htonl((d<<24) ^ (c<<16) ^ (b<<8) ^ a);
  93. if(ip == param->srv->intip){
  94. buf[2] = 0x85;
  95. buf[3] = 0x80;
  96. buf[6] = 0;
  97. buf[7] = 1;
  98. buf[8] = buf[9] = buf[10] = buf[11] = 0;
  99. memset(buf+len, 0, 20);
  100. buf[len] = 0xc0;
  101. buf[len+1] = 0x0c;
  102. buf[len+3] = 0x0c;
  103. buf[len+5] = 1;
  104. ttl = htonl(3600);
  105. memcpy(buf + len + 6, &ttl, 4);
  106. buf[len+11] = 7;
  107. buf[len+12] = 6;
  108. memcpy(buf+len+13,(void *)"3proxy",6);
  109. len+=20;
  110. }
  111. else ip = 0;
  112. }
  113. if(!ip && nservers[0] && type!=1){
  114. if((param->remsock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
  115. RETURN(818);
  116. }
  117. #ifdef _WIN32
  118. ioctlsocket(param->remsock, FIONBIO, &ul);
  119. #else
  120. fcntl(param->remsock,F_SETFL,O_NONBLOCK);
  121. #endif
  122. param->sins.sin_family = AF_INET;
  123. param->sins.sin_port = htons(0);
  124. param->sins.sin_addr.s_addr = htonl(0);
  125. if(so._bind(param->remsock,(struct sockaddr *)&param->sins,sizeof(struct sockaddr_in))) {
  126. RETURN(819);
  127. }
  128. param->sins.sin_addr.s_addr = nservers[0];
  129. param->sins.sin_port = htons(53);
  130. if(socksendto(param->remsock, &param->sins, buf, i, conf.timeouts[SINGLEBYTE_L]*1000) != i){
  131. RETURN(820);
  132. }
  133. param->statscli64 += i;
  134. param->nwrites++;
  135. len = sockrecvfrom(param->remsock, &param->sins, buf, BUFSIZE, 15000);
  136. if(len <= 13) {
  137. RETURN(821);
  138. }
  139. param->statssrv64 += len;
  140. param->nreads++;
  141. if(buf[6] || buf[7]){
  142. if(socksendto(param->clisock, &param->sinc, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
  143. RETURN(822);
  144. }
  145. RETURN(0);
  146. }
  147. }
  148. if(!ip) {
  149. buf[2] = 0x85;
  150. buf[3] = 0x83;
  151. }
  152. usleep(SLEEPTIME);
  153. res = socksendto(param->clisock, &param->sinc, buf, len, conf.timeouts[SINGLEBYTE_L]*1000);
  154. if(res != len){RETURN(819);}
  155. if(!ip) {RETURN(888);}
  156. CLEANRET:
  157. if(param->res!=813){
  158. sprintf((char *)buf, "%04x/%s(%u.%u.%u.%u)",
  159. (unsigned)type,
  160. host?host:"",
  161. (unsigned)(ntohl(ip)&0xff000000)>>24,
  162. (unsigned)(ntohl(ip)&0x00ff0000)>>16,
  163. (unsigned)(ntohl(ip)&0x0000ff00)>>8,
  164. (unsigned)(ntohl(ip)&0x000000ff)
  165. );
  166. (*param->srv->logfunc)(param, buf);
  167. }
  168. if(buf)myfree(buf);
  169. if(host)myfree(host);
  170. #ifndef _WIN32
  171. param->clisock = INVALID_SOCKET;
  172. #endif
  173. freeparam(param);
  174. return (NULL);
  175. }