A clone of btpd with my configuration changes.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

457 lignes
9.7 KiB

  1. /*
  2. * Copyright (c) 2002, 2003 Niels Provos <provos@citi.umich.edu>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. The name of the author may not be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  18. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  19. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  20. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  21. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  25. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #ifdef HAVE_CONFIG_H
  28. #include "config.h"
  29. #endif
  30. #ifdef HAVE_VASPRINTF
  31. /* If we have vasprintf, we need to define this before we include stdio.h. */
  32. #define _GNU_SOURCE
  33. #endif
  34. #include <sys/types.h>
  35. #ifdef HAVE_SYS_TIME_H
  36. #include <sys/time.h>
  37. #endif
  38. #ifdef HAVE_SYS_IOCTL_H
  39. #include <sys/ioctl.h>
  40. #endif
  41. #include <errno.h>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #ifdef HAVE_STDARG_H
  46. #include <stdarg.h>
  47. #endif
  48. #ifdef HAVE_UNISTD_H
  49. #include <unistd.h>
  50. #endif
  51. #include "event.h"
  52. struct evbuffer *
  53. evbuffer_new(void)
  54. {
  55. struct evbuffer *buffer;
  56. buffer = calloc(1, sizeof(struct evbuffer));
  57. return (buffer);
  58. }
  59. void
  60. evbuffer_free(struct evbuffer *buffer)
  61. {
  62. if (buffer->orig_buffer != NULL)
  63. free(buffer->orig_buffer);
  64. free(buffer);
  65. }
  66. /*
  67. * This is a destructive add. The data from one buffer moves into
  68. * the other buffer.
  69. */
  70. #define SWAP(x,y) do { \
  71. (x)->buffer = (y)->buffer; \
  72. (x)->orig_buffer = (y)->orig_buffer; \
  73. (x)->misalign = (y)->misalign; \
  74. (x)->totallen = (y)->totallen; \
  75. (x)->off = (y)->off; \
  76. } while (0)
  77. int
  78. evbuffer_add_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf)
  79. {
  80. int res;
  81. /* Short cut for better performance */
  82. if (outbuf->off == 0) {
  83. struct evbuffer tmp;
  84. size_t oldoff = inbuf->off;
  85. /* Swap them directly */
  86. SWAP(&tmp, outbuf);
  87. SWAP(outbuf, inbuf);
  88. SWAP(inbuf, &tmp);
  89. /*
  90. * Optimization comes with a price; we need to notify the
  91. * buffer if necessary of the changes. oldoff is the amount
  92. * of data that we tranfered from inbuf to outbuf
  93. */
  94. if (inbuf->off != oldoff && inbuf->cb != NULL)
  95. (*inbuf->cb)(inbuf, oldoff, inbuf->off, inbuf->cbarg);
  96. if (oldoff && outbuf->cb != NULL)
  97. (*outbuf->cb)(outbuf, 0, oldoff, outbuf->cbarg);
  98. return (0);
  99. }
  100. res = evbuffer_add(outbuf, inbuf->buffer, inbuf->off);
  101. if (res == 0) {
  102. /* We drain the input buffer on success */
  103. evbuffer_drain(inbuf, inbuf->off);
  104. }
  105. return (res);
  106. }
  107. int
  108. evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap)
  109. {
  110. char *buffer;
  111. size_t space;
  112. size_t oldoff = buf->off;
  113. int sz;
  114. va_list aq;
  115. for (;;) {
  116. buffer = (char *)buf->buffer + buf->off;
  117. space = buf->totallen - buf->misalign - buf->off;
  118. #ifndef va_copy
  119. #define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list))
  120. #endif
  121. va_copy(aq, ap);
  122. #ifdef WIN32
  123. sz = vsnprintf(buffer, space - 1, fmt, aq);
  124. buffer[space - 1] = '\0';
  125. #else
  126. sz = vsnprintf(buffer, space, fmt, aq);
  127. #endif
  128. va_end(aq);
  129. if (sz == -1)
  130. return (-1);
  131. if (sz < space) {
  132. buf->off += sz;
  133. if (buf->cb != NULL)
  134. (*buf->cb)(buf, oldoff, buf->off, buf->cbarg);
  135. return (sz);
  136. }
  137. if (evbuffer_expand(buf, sz + 1) == -1)
  138. return (-1);
  139. }
  140. /* NOTREACHED */
  141. }
  142. int
  143. evbuffer_add_printf(struct evbuffer *buf, const char *fmt, ...)
  144. {
  145. int res = -1;
  146. va_list ap;
  147. va_start(ap, fmt);
  148. res = evbuffer_add_vprintf(buf, fmt, ap);
  149. va_end(ap);
  150. return (res);
  151. }
  152. /* Reads data from an event buffer and drains the bytes read */
  153. int
  154. evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen)
  155. {
  156. size_t nread = datlen;
  157. if (nread >= buf->off)
  158. nread = buf->off;
  159. memcpy(data, buf->buffer, nread);
  160. evbuffer_drain(buf, nread);
  161. return (nread);
  162. }
  163. /*
  164. * Reads a line terminated by either '\r\n', '\n\r' or '\r' or '\n'.
  165. * The returned buffer needs to be freed by the called.
  166. */
  167. char *
  168. evbuffer_readline(struct evbuffer *buffer)
  169. {
  170. u_char *data = EVBUFFER_DATA(buffer);
  171. size_t len = EVBUFFER_LENGTH(buffer);
  172. char *line;
  173. unsigned int i;
  174. for (i = 0; i < len; i++) {
  175. if (data[i] == '\r' || data[i] == '\n')
  176. break;
  177. }
  178. if (i == len)
  179. return (NULL);
  180. if ((line = malloc(i + 1)) == NULL) {
  181. fprintf(stderr, "%s: out of memory\n", __func__);
  182. evbuffer_drain(buffer, i);
  183. return (NULL);
  184. }
  185. memcpy(line, data, i);
  186. line[i] = '\0';
  187. /*
  188. * Some protocols terminate a line with '\r\n', so check for
  189. * that, too.
  190. */
  191. if ( i < len - 1 ) {
  192. char fch = data[i], sch = data[i+1];
  193. /* Drain one more character if needed */
  194. if ( (sch == '\r' || sch == '\n') && sch != fch )
  195. i += 1;
  196. }
  197. evbuffer_drain(buffer, i + 1);
  198. return (line);
  199. }
  200. /* Adds data to an event buffer */
  201. static inline void
  202. evbuffer_align(struct evbuffer *buf)
  203. {
  204. memmove(buf->orig_buffer, buf->buffer, buf->off);
  205. buf->buffer = buf->orig_buffer;
  206. buf->misalign = 0;
  207. }
  208. /* Expands the available space in the event buffer to at least datlen */
  209. int
  210. evbuffer_expand(struct evbuffer *buf, size_t datlen)
  211. {
  212. size_t need = buf->misalign + buf->off + datlen;
  213. /* If we can fit all the data, then we don't have to do anything */
  214. if (buf->totallen >= need)
  215. return (0);
  216. /*
  217. * If the misalignment fulfills our data needs, we just force an
  218. * alignment to happen. Afterwards, we have enough space.
  219. */
  220. if (buf->misalign >= datlen) {
  221. evbuffer_align(buf);
  222. } else {
  223. void *newbuf;
  224. size_t length = buf->totallen;
  225. if (length < 256)
  226. length = 256;
  227. while (length < need)
  228. length <<= 1;
  229. if (buf->orig_buffer != buf->buffer)
  230. evbuffer_align(buf);
  231. if ((newbuf = realloc(buf->buffer, length)) == NULL)
  232. return (-1);
  233. buf->orig_buffer = buf->buffer = newbuf;
  234. buf->totallen = length;
  235. }
  236. return (0);
  237. }
  238. int
  239. evbuffer_add(struct evbuffer *buf, const void *data, size_t datlen)
  240. {
  241. size_t need = buf->misalign + buf->off + datlen;
  242. size_t oldoff = buf->off;
  243. if (buf->totallen < need) {
  244. if (evbuffer_expand(buf, datlen) == -1)
  245. return (-1);
  246. }
  247. memcpy(buf->buffer + buf->off, data, datlen);
  248. buf->off += datlen;
  249. if (datlen && buf->cb != NULL)
  250. (*buf->cb)(buf, oldoff, buf->off, buf->cbarg);
  251. return (0);
  252. }
  253. void
  254. evbuffer_drain(struct evbuffer *buf, size_t len)
  255. {
  256. size_t oldoff = buf->off;
  257. if (len >= buf->off) {
  258. buf->off = 0;
  259. buf->buffer = buf->orig_buffer;
  260. buf->misalign = 0;
  261. goto done;
  262. }
  263. buf->buffer += len;
  264. buf->misalign += len;
  265. buf->off -= len;
  266. done:
  267. /* Tell someone about changes in this buffer */
  268. if (buf->off != oldoff && buf->cb != NULL)
  269. (*buf->cb)(buf, oldoff, buf->off, buf->cbarg);
  270. }
  271. /*
  272. * Reads data from a file descriptor into a buffer.
  273. */
  274. #define EVBUFFER_MAX_READ 4096
  275. int
  276. evbuffer_read(struct evbuffer *buf, int fd, int howmuch)
  277. {
  278. u_char *p;
  279. size_t oldoff = buf->off;
  280. int n = EVBUFFER_MAX_READ;
  281. #ifdef WIN32
  282. DWORD dwBytesRead;
  283. #endif
  284. #ifdef FIONREAD
  285. if (ioctl(fd, FIONREAD, &n) == -1 || n == 0) {
  286. n = EVBUFFER_MAX_READ;
  287. } else if (n > EVBUFFER_MAX_READ && n > howmuch) {
  288. /*
  289. * It's possible that a lot of data is available for
  290. * reading. We do not want to exhaust resources
  291. * before the reader has a chance to do something
  292. * about it. If the reader does not tell us how much
  293. * data we should read, we artifically limit it.
  294. */
  295. if (n > buf->totallen << 2)
  296. n = buf->totallen << 2;
  297. if (n < EVBUFFER_MAX_READ)
  298. n = EVBUFFER_MAX_READ;
  299. }
  300. #endif
  301. if (howmuch < 0 || howmuch > n)
  302. howmuch = n;
  303. /* If we don't have FIONREAD, we might waste some space here */
  304. if (evbuffer_expand(buf, howmuch) == -1)
  305. return (-1);
  306. /* We can append new data at this point */
  307. p = buf->buffer + buf->off;
  308. #ifndef WIN32
  309. n = read(fd, p, howmuch);
  310. if (n == -1)
  311. return (-1);
  312. if (n == 0)
  313. return (0);
  314. #else
  315. n = ReadFile((HANDLE)fd, p, howmuch, &dwBytesRead, NULL);
  316. if (n == 0)
  317. return (-1);
  318. if (dwBytesRead == 0)
  319. return (0);
  320. n = dwBytesRead;
  321. #endif
  322. buf->off += n;
  323. /* Tell someone about changes in this buffer */
  324. if (buf->off != oldoff && buf->cb != NULL)
  325. (*buf->cb)(buf, oldoff, buf->off, buf->cbarg);
  326. return (n);
  327. }
  328. int
  329. evbuffer_write(struct evbuffer *buffer, int fd)
  330. {
  331. int n;
  332. #ifdef WIN32
  333. DWORD dwBytesWritten;
  334. #endif
  335. #ifndef WIN32
  336. n = write(fd, buffer->buffer, buffer->off);
  337. if (n == -1)
  338. return (-1);
  339. if (n == 0)
  340. return (0);
  341. #else
  342. n = WriteFile((HANDLE)fd, buffer->buffer, buffer->off, &dwBytesWritten, NULL);
  343. if (n == 0)
  344. return (-1);
  345. if (dwBytesWritten == 0)
  346. return (0);
  347. n = dwBytesWritten;
  348. #endif
  349. evbuffer_drain(buffer, n);
  350. return (n);
  351. }
  352. u_char *
  353. evbuffer_find(struct evbuffer *buffer, const u_char *what, size_t len)
  354. {
  355. size_t remain = buffer->off;
  356. u_char *search = buffer->buffer;
  357. u_char *p;
  358. while ((p = memchr(search, *what, remain)) != NULL) {
  359. remain = buffer->off - (size_t)(search - buffer->buffer);
  360. if (remain < len)
  361. break;
  362. if (memcmp(p, what, len) == 0)
  363. return (p);
  364. search = p + 1;
  365. }
  366. return (NULL);
  367. }
  368. void evbuffer_setcb(struct evbuffer *buffer,
  369. void (*cb)(struct evbuffer *, size_t, size_t, void *),
  370. void *cbarg)
  371. {
  372. buffer->cb = cb;
  373. buffer->cbarg = cbarg;
  374. }