sockgetchar.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. 3APA3A simpliest proxy server
  3. (c) 2002-2008 by ZARAZA <3APA3A@security.nnov.ru>
  4. please read License Agreement
  5. */
  6. #include "proxy.h"
  7. #define BUFSIZE (param->srv->bufsize?param->srv->bufsize:((param->service == S_UDPPM)?UDPBUFSIZE:TCPBUFSIZE))
  8. int socksend(SOCKET sock, unsigned char * buf, int bufsize, int to){
  9. int sent = 0;
  10. int res;
  11. struct pollfd fds;
  12. fds.fd = sock;
  13. fds.events = POLLOUT;
  14. do {
  15. if(conf.timetoexit) return 0;
  16. res = so._poll(&fds, 1, to*1000);
  17. if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue;
  18. if(res < 1) break;
  19. res = so._send(sock, buf + sent, bufsize - sent, 0);
  20. if(res < 0) {
  21. if(errno == EAGAIN || errno == EINTR) continue;
  22. break;
  23. }
  24. sent += res;
  25. } while (sent < bufsize);
  26. return sent;
  27. }
  28. int socksendto(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int bufsize, int to){
  29. int sent = 0;
  30. int res;
  31. struct pollfd fds;
  32. fds.fd = sock;
  33. do {
  34. if(conf.timetoexit) return 0;
  35. fds.events = POLLOUT;
  36. res = so._poll(&fds, 1, to);
  37. if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue;
  38. if(res < 1) break;
  39. res = so._sendto(sock, buf + sent, bufsize - sent, 0, (struct sockaddr *)sin, sizeof(struct sockaddr_in));
  40. if(res < 0) {
  41. if(errno != EAGAIN) break;
  42. continue;
  43. }
  44. sent += res;
  45. } while (sent < bufsize);
  46. return sent;
  47. }
  48. int sockrecvfrom(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int bufsize, int to){
  49. struct pollfd fds;
  50. SASIZETYPE sasize;
  51. int res;
  52. fds.fd = sock;
  53. fds.events = POLLIN;
  54. if(conf.timetoexit) return EOF;
  55. if (so._poll(&fds, 1, to)<1) return 0;
  56. sasize = sizeof(struct sockaddr_in);
  57. do {
  58. res = so._recvfrom(sock, buf, bufsize, 0, (struct sockaddr *)sin, &sasize);
  59. } while (res < 0 && (errno == EAGAIN || errno == EINTR));
  60. return res;
  61. }
  62. int sockgetcharcli(struct clientparam * param, int timeosec, int timeousec){
  63. int len;
  64. if(!param->clibuf){
  65. if(!(param->clibuf = myalloc(BUFSIZE))) return 0;
  66. param->clibufsize = BUFSIZE;
  67. param->clioffset = param->cliinbuf = 0;
  68. }
  69. if(param->cliinbuf && param->clioffset < param->cliinbuf){
  70. return (int)param->clibuf[param->clioffset++];
  71. }
  72. param->clioffset = param->cliinbuf = 0;
  73. if ((len = sockrecvfrom(param->clisock, &param->sinc, param->clibuf, param->clibufsize, timeosec*1000 + timeousec))<=0) return EOF;
  74. param->cliinbuf = len;
  75. param->clioffset = 1;
  76. return (int)*param->clibuf;
  77. }
  78. int sockfillbuffcli(struct clientparam * param, unsigned long size, int timeosec){
  79. int len;
  80. if(!param->clibuf) return 0;
  81. if(param->cliinbuf == param->clioffset){
  82. param->cliinbuf = param->clioffset = 0;
  83. }
  84. else if(param->clioffset){
  85. memmove(param->clibuf, param->clibuf + param->clioffset, param->cliinbuf - param->clioffset);
  86. param->cliinbuf -= param->clioffset;
  87. param->clioffset = 0;
  88. }
  89. if(size <= param->cliinbuf) return size;
  90. size -= param->cliinbuf;
  91. if((len = sockrecvfrom(param->clisock, &param->sinc, param->clibuf + param->cliinbuf, (param->clibufsize - param->cliinbuf) < size? param->clibufsize - param->cliinbuf:size, timeosec*1000)) > 0){
  92. param->cliinbuf += len;
  93. }
  94. return param->cliinbuf;
  95. }
  96. int sockfillbuffsrv(struct clientparam * param, unsigned long size, int timeosec){
  97. int len;
  98. if(!param->srvbuf) return 0;
  99. if(param->srvinbuf == param->srvoffset){
  100. param->srvinbuf = param->srvoffset = 0;
  101. }
  102. else if(param->srvoffset){
  103. memmove(param->srvbuf, param->srvbuf + param->srvoffset, param->srvinbuf - param->srvoffset);
  104. param->srvinbuf -= param->srvoffset;
  105. param->srvoffset = 0;
  106. }
  107. if(size <= param->srvinbuf) return size;
  108. size -= param->srvinbuf;
  109. if((len = sockrecvfrom(param->remsock, &param->sinc, param->srvbuf + param->srvinbuf, (param->srvbufsize - param->srvinbuf) < size? param->srvbufsize - param->srvinbuf:size, timeosec*1000)) > 0){
  110. param->srvinbuf += len;
  111. param->nreads++;
  112. param->statssrv64 += len;
  113. }
  114. return param->srvinbuf;
  115. }
  116. int sockgetcharsrv(struct clientparam * param, int timeosec, int timeousec){
  117. int len;
  118. int bufsize;
  119. if(!param->srvbuf){
  120. bufsize = BUFSIZE;
  121. if(param->ndatfilterssrv > 0 && bufsize < 32768) bufsize = 32768;
  122. if(!(param->srvbuf = myalloc(bufsize))) return 0;
  123. param->srvbufsize = bufsize;
  124. param->srvoffset = param->srvinbuf = 0;
  125. }
  126. if(param->srvinbuf && param->srvoffset < param->srvinbuf){
  127. return (int)param->srvbuf[param->srvoffset++];
  128. }
  129. param->srvoffset = param->srvinbuf = 0;
  130. if ((len = sockrecvfrom(param->remsock, &param->sins, param->srvbuf, param->srvbufsize, timeosec*1000 + timeousec))<=0) return EOF;
  131. param->srvinbuf = len;
  132. param->srvoffset = 1;
  133. param->nreads++;
  134. param->statssrv64 += len;
  135. return (int)*param->srvbuf;
  136. }
  137. int sockgetlinebuf(struct clientparam * param, DIRECTION which, unsigned char * buf, int bufsize, int delim, int to){
  138. int c;
  139. int i=0;
  140. if(bufsize<2) return 0;
  141. c = (which)?sockgetcharsrv(param, to, 0):sockgetcharcli(param, to, 0);
  142. if (c == EOF) {
  143. return 0;
  144. }
  145. do {
  146. buf[i++] = c;
  147. if(delim != EOF && c == delim) break;
  148. }while(i < bufsize && (c = (which)?sockgetcharsrv(param, to, 0):sockgetcharcli(param, to, 0)) != EOF);
  149. return i;
  150. }