udppm.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*
  2. 3APA3A simpliest proxy server
  3. (c) 2002-2016 by Vladimir Dubrovin <3proxy@3proxy.ru>
  4. please read License Agreement
  5. */
  6. #include "proxy.h"
  7. #ifndef PORTMAP
  8. #define PORTMAP
  9. #endif
  10. #ifndef UDP
  11. #define UDP
  12. #endif
  13. #define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
  14. struct udpmap {
  15. struct udpmap *next;
  16. time_t updated;
  17. SOCKET s;
  18. int single;
  19. unsigned long cliip;
  20. unsigned short cliport;
  21. };
  22. void * udppmchild(struct clientparam* param) {
  23. unsigned char *buf = NULL;
  24. int res, i;
  25. #ifdef _WIN32
  26. SASIZETYPE size;
  27. unsigned long ul = 1;
  28. #endif
  29. struct udpmap *udpmappings = NULL;
  30. struct pollfd fds[256];
  31. if(!param->hostname)parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport));
  32. if (SAISNULL(&param->req)) {
  33. param->srv->fds.events = POLLIN;
  34. RETURN (100);
  35. }
  36. if(!param->clibuf && (!(param->clibuf=myalloc(UDPBUFSIZE)) || !(param->clibufsize = UDPBUFSIZE))){
  37. param->srv->fds.events = POLLIN;
  38. RETURN (21);
  39. }
  40. param->cliinbuf = param->clioffset = 0;
  41. i = sockrecvfrom(param->srv->srvsock, (struct sockaddr *)&param->sincr, param->clibuf, param->clibufsize, 0);
  42. if(i<=0){
  43. param->srv->fds.events = POLLIN;
  44. RETURN (214);
  45. }
  46. param->cliinbuf = i;
  47. #ifdef _WIN32
  48. if((param->clisock=so._socket(SASOCK(&param->sincr), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
  49. RETURN(818);
  50. }
  51. if(so._setsockopt(param->clisock, SOL_SOCKET, SO_REUSEADDR, (char *)&ul, sizeof(int))) {RETURN(820);};
  52. ioctlsocket(param->clisock, FIONBIO, &ul);
  53. size = sizeof(param->sinsl);
  54. if(so._getsockname(param->srv->srvsock, (struct sockaddr *)&param->sinsl, &size)) {RETURN(21);};
  55. if(so._bind(param->clisock,(struct sockaddr *)&param->sinsl,SASIZE(&param->sinsl))) {
  56. RETURN(822);
  57. }
  58. #else
  59. param->clisock = param->srv->srvsock;
  60. #endif
  61. #ifndef NOIPV6
  62. memcpy(&param->sinsl, *SAFAMILY(&param->req) == AF_INET? (struct sockaddr *)&param->srv->extsa : (struct sockaddr *)&param->srv->extsa6, SASIZE(&param->req));
  63. #else
  64. memcpy(&param->sinsl, &param->srv->extsa, SASIZE(&param->req));
  65. #endif
  66. *SAPORT(&param->sinsl) = 0;
  67. if ((param->remsock=so._socket(SASOCK(&param->sinsl), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);}
  68. if(so._bind(param->remsock,(struct sockaddr *)&param->sinsl,SASIZE(&param->sinsl))) {RETURN (12);}
  69. #ifdef _WIN32
  70. ioctlsocket(param->remsock, FIONBIO, &ul);
  71. #else
  72. fcntl(param->remsock,F_SETFL,O_NONBLOCK);
  73. #endif
  74. memcpy(&param->sinsr, &param->req, sizeof(param->req));
  75. param->operation = UDPASSOC;
  76. if((res = (*param->srv->authfunc)(param))) {RETURN(res);}
  77. if(param->srv->singlepacket) {
  78. param->srv->fds.events = POLLIN;
  79. }
  80. param->res = sockmap(param, conf.timeouts[(param->srv->singlepacket)?SINGLEBYTE_L:STRING_L]);
  81. if(!param->srv->singlepacket) {
  82. param->srv->fds.events = POLLIN;
  83. }
  84. CLEANRET:
  85. if(buf)myfree(buf);
  86. (*param->srv->logfunc)(param, NULL);
  87. #ifndef _WIN32
  88. param->clisock = INVALID_SOCKET;
  89. #endif
  90. freeparam(param);
  91. return (NULL);
  92. }
  93. #ifdef WITHMAIN
  94. struct proxydef childdef = {
  95. udppmchild,
  96. 0,
  97. 1,
  98. S_UDPPM,
  99. " -s single packet UDP service for request/reply (DNS-like) services\n"
  100. };
  101. #include "proxymain.c"
  102. #endif