buffer.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. #include "tunala.h"
  2. #ifndef NO_BUFFER
  3. void buffer_init(buffer_t * buf)
  4. {
  5. buf->used = 0;
  6. buf->total_in = buf->total_out = 0;
  7. }
  8. void buffer_close(buffer_t * buf)
  9. {
  10. /* Our data is static - nothing needs "release", just reset it */
  11. buf->used = 0;
  12. }
  13. /* Code these simple ones in compact form */
  14. unsigned int buffer_used(buffer_t * buf)
  15. {
  16. return buf->used;
  17. }
  18. unsigned int buffer_unused(buffer_t * buf)
  19. {
  20. return (MAX_DATA_SIZE - buf->used);
  21. }
  22. int buffer_full(buffer_t * buf)
  23. {
  24. return (buf->used == MAX_DATA_SIZE ? 1 : 0);
  25. }
  26. int buffer_notfull(buffer_t * buf)
  27. {
  28. return (buf->used < MAX_DATA_SIZE ? 1 : 0);
  29. }
  30. int buffer_empty(buffer_t * buf)
  31. {
  32. return (buf->used == 0 ? 1 : 0);
  33. }
  34. int buffer_notempty(buffer_t * buf)
  35. {
  36. return (buf->used > 0 ? 1 : 0);
  37. }
  38. unsigned long buffer_total_in(buffer_t * buf)
  39. {
  40. return buf->total_in;
  41. }
  42. unsigned long buffer_total_out(buffer_t * buf)
  43. {
  44. return buf->total_out;
  45. }
  46. /*
  47. * These 3 static (internal) functions don't adjust the "total" variables as
  48. * it's not sure when they're called how it should be interpreted. Only the
  49. * higher-level "buffer_[to|from]_[fd|SSL|BIO]" functions should alter these
  50. * values.
  51. */
  52. # if 0 /* To avoid "unused" warnings */
  53. static unsigned int buffer_adddata(buffer_t * buf, const unsigned char *ptr,
  54. unsigned int size)
  55. {
  56. unsigned int added = MAX_DATA_SIZE - buf->used;
  57. if (added > size)
  58. added = size;
  59. if (added == 0)
  60. return 0;
  61. memcpy(buf->data + buf->used, ptr, added);
  62. buf->used += added;
  63. buf->total_in += added;
  64. return added;
  65. }
  66. static unsigned int buffer_tobuffer(buffer_t * to, buffer_t * from, int cap)
  67. {
  68. unsigned int moved, tomove = from->used;
  69. if ((int)tomove > cap)
  70. tomove = cap;
  71. if (tomove == 0)
  72. return 0;
  73. moved = buffer_adddata(to, from->data, tomove);
  74. if (moved == 0)
  75. return 0;
  76. buffer_takedata(from, NULL, moved);
  77. return moved;
  78. }
  79. # endif
  80. static unsigned int buffer_takedata(buffer_t * buf, unsigned char *ptr,
  81. unsigned int size)
  82. {
  83. unsigned int taken = buf->used;
  84. if (taken > size)
  85. taken = size;
  86. if (taken == 0)
  87. return 0;
  88. if (ptr)
  89. memcpy(ptr, buf->data, taken);
  90. buf->used -= taken;
  91. /* Do we have to scroll? */
  92. if (buf->used > 0)
  93. memmove(buf->data, buf->data + taken, buf->used);
  94. return taken;
  95. }
  96. # ifndef NO_IP
  97. int buffer_from_fd(buffer_t * buf, int fd)
  98. {
  99. int toread = buffer_unused(buf);
  100. if (toread == 0)
  101. /* Shouldn't be called in this case! */
  102. abort();
  103. toread = read(fd, buf->data + buf->used, toread);
  104. if (toread > 0) {
  105. buf->used += toread;
  106. buf->total_in += toread;
  107. }
  108. return toread;
  109. }
  110. int buffer_to_fd(buffer_t * buf, int fd)
  111. {
  112. int towrite = buffer_used(buf);
  113. if (towrite == 0)
  114. /* Shouldn't be called in this case! */
  115. abort();
  116. towrite = write(fd, buf->data, towrite);
  117. if (towrite > 0) {
  118. buffer_takedata(buf, NULL, towrite);
  119. buf->total_out += towrite;
  120. }
  121. return towrite;
  122. }
  123. # endif /* !defined(NO_IP) */
  124. # ifndef NO_OPENSSL
  125. static void int_ssl_check(SSL *s, int ret)
  126. {
  127. int e = SSL_get_error(s, ret);
  128. switch (e) {
  129. /*
  130. * These seem to be harmless and already "dealt with" by our
  131. * non-blocking environment. NB: "ZERO_RETURN" is the clean "error"
  132. * indicating a successfully closed SSL tunnel. We let this happen
  133. * because our IO loop should not appear to have broken on this
  134. * condition - and outside the IO loop, the "shutdown" state is
  135. * checked.
  136. */
  137. case SSL_ERROR_NONE:
  138. case SSL_ERROR_WANT_READ:
  139. case SSL_ERROR_WANT_WRITE:
  140. case SSL_ERROR_WANT_X509_LOOKUP:
  141. case SSL_ERROR_ZERO_RETURN:
  142. return;
  143. /*
  144. * These seem to be indications of a genuine error that should result
  145. * in the SSL tunnel being regarded as "dead".
  146. */
  147. case SSL_ERROR_SYSCALL:
  148. case SSL_ERROR_SSL:
  149. SSL_set_app_data(s, (char *)1);
  150. return;
  151. default:
  152. break;
  153. }
  154. /*
  155. * For any other errors that (a) exist, and (b) crop up - we need to
  156. * interpret what to do with them - so "politely inform" the caller that
  157. * the code needs updating here.
  158. */
  159. abort();
  160. }
  161. void buffer_from_SSL(buffer_t * buf, SSL *ssl)
  162. {
  163. int ret;
  164. if (!ssl || buffer_full(buf))
  165. return;
  166. ret = SSL_read(ssl, buf->data + buf->used, buffer_unused(buf));
  167. if (ret > 0) {
  168. buf->used += ret;
  169. buf->total_in += ret;
  170. }
  171. if (ret < 0)
  172. int_ssl_check(ssl, ret);
  173. }
  174. void buffer_to_SSL(buffer_t * buf, SSL *ssl)
  175. {
  176. int ret;
  177. if (!ssl || buffer_empty(buf))
  178. return;
  179. ret = SSL_write(ssl, buf->data, buf->used);
  180. if (ret > 0) {
  181. buffer_takedata(buf, NULL, ret);
  182. buf->total_out += ret;
  183. }
  184. if (ret < 0)
  185. int_ssl_check(ssl, ret);
  186. }
  187. void buffer_from_BIO(buffer_t * buf, BIO *bio)
  188. {
  189. int ret;
  190. if (!bio || buffer_full(buf))
  191. return;
  192. ret = BIO_read(bio, buf->data + buf->used, buffer_unused(buf));
  193. if (ret > 0) {
  194. buf->used += ret;
  195. buf->total_in += ret;
  196. }
  197. }
  198. void buffer_to_BIO(buffer_t * buf, BIO *bio)
  199. {
  200. int ret;
  201. if (!bio || buffer_empty(buf))
  202. return;
  203. ret = BIO_write(bio, buf->data, buf->used);
  204. if (ret > 0) {
  205. buffer_takedata(buf, NULL, ret);
  206. buf->total_out += ret;
  207. }
  208. }
  209. # endif /* !defined(NO_OPENSSL) */
  210. #endif /* !defined(NO_BUFFER) */