sockgetchar.c 4.8 KB

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