xref: /libevent-2.1.12/buffer.c (revision e5cf9879)
1 /*
2  * Copyright (c) 2002-2007 Niels Provos <[email protected]>
3  * Copyright (c) 2007-2009 Niels Provos and Nick Mathewson
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 
28 #include "event-config.h"
29 
30 #ifdef WIN32
31 #include <winsock2.h>
32 #include <windows.h>
33 #include <io.h>
34 #endif
35 
36 #ifdef _EVENT_HAVE_VASPRINTF
37 /* If we have vasprintf, we need to define this before we include stdio.h. */
38 #define _GNU_SOURCE
39 #endif
40 
41 #include <sys/types.h>
42 
43 #ifdef _EVENT_HAVE_SYS_TIME_H
44 #include <sys/time.h>
45 #endif
46 
47 #ifdef _EVENT_HAVE_SYS_SOCKET_H
48 #include <sys/socket.h>
49 #endif
50 
51 #ifdef _EVENT_HAVE_SYS_UIO_H
52 #include <sys/uio.h>
53 #endif
54 
55 #ifdef _EVENT_HAVE_SYS_IOCTL_H
56 #include <sys/ioctl.h>
57 #endif
58 
59 #ifdef _EVENT_HAVE_SYS_MMAN_H
60 #include <sys/mman.h>
61 #endif
62 
63 #ifdef _EVENT_HAVE_SYS_SENDFILE_H
64 #include <sys/sendfile.h>
65 #endif
66 
67 #include <errno.h>
68 #include <stdio.h>
69 #include <stdlib.h>
70 #include <string.h>
71 #ifdef _EVENT_HAVE_STDARG_H
72 #include <stdarg.h>
73 #endif
74 #ifdef _EVENT_HAVE_UNISTD_H
75 #include <unistd.h>
76 #endif
77 
78 #include "event2/event.h"
79 #include "event2/buffer.h"
80 #include "event2/buffer_compat.h"
81 #include "event2/bufferevent.h"
82 #include "event2/bufferevent_compat.h"
83 #include "event2/bufferevent_struct.h"
84 #include "event2/thread.h"
85 #include "event-config.h"
86 #include "log-internal.h"
87 #include "mm-internal.h"
88 #include "util-internal.h"
89 #include "evthread-internal.h"
90 #include "evbuffer-internal.h"
91 #include "bufferevent-internal.h"
92 
93 /* some systems do not have MAP_FAILED */
94 #ifndef MAP_FAILED
95 #define MAP_FAILED	((void *)-1)
96 #endif
97 
98 /* send file support */
99 #if defined(_EVENT_HAVE_SYS_SENDFILE_H) && defined(_EVENT_HAVE_SENDFILE) && defined(__linux__)
100 #define USE_SENDFILE		1
101 #define SENDFILE_IS_LINUX	1
102 #elif defined(_EVENT_HAVE_SENDFILE) && defined(__FreeBSD__)
103 #define USE_SENDFILE		1
104 #define SENDFILE_IS_FREEBSD	1
105 #elif defined(_EVENT_HAVE_SENDFILE) && defined(__APPLE__)
106 #define USE_SENDFILE		1
107 #define SENDFILE_IS_MACOSX	1
108 #elif defined(_EVENT_HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__)
109 #define USE_SENDFILE		1
110 #define SENDFILE_IS_SOLARIS	1
111 #endif
112 
113 #ifdef USE_SENDFILE
114 static int use_sendfile = 1;
115 #endif
116 #ifdef _EVENT_HAVE_MMAP
117 static int use_mmap = 1;
118 #endif
119 
120 
121 /* Mask of user-selectable callback flags. */
122 #define EVBUFFER_CB_USER_FLAGS	    0xffff
123 /* Mask of all internal-use-only flags. */
124 #define EVBUFFER_CB_INTERNAL_FLAGS  0xffff0000
125 
126 /* Flag set if the callback is using the cb_obsolete function pointer  */
127 #define EVBUFFER_CB_OBSOLETE	       0x00040000
128 
129 /* evbuffer_chain support */
130 #define CHAIN_SPACE_PTR(ch) ((ch)->buffer + (ch)->misalign + (ch)->off)
131 #define CHAIN_SPACE_LEN(ch) ((ch)->flags & EVBUFFER_IMMUTABLE ? \
132 	    0 : (ch)->buffer_len - ((ch)->misalign + (ch)->off))
133 
134 #define CHAIN_PINNED(ch)  (((ch)->flags & EVBUFFER_MEM_PINNED_ANY) != 0)
135 #define CHAIN_PINNED_R(ch)  (((ch)->flags & EVBUFFER_MEM_PINNED_R) != 0)
136 
137 static void evbuffer_chain_align(struct evbuffer_chain *chain);
138 static void evbuffer_deferred_callback(struct deferred_cb *cb, void *arg);
139 static int evbuffer_ptr_memcmp(const struct evbuffer *buf,
140     const struct evbuffer_ptr *pos, const char *mem, size_t len);
141 
142 static struct evbuffer_chain *
143 evbuffer_chain_new(size_t size)
144 {
145 	struct evbuffer_chain *chain;
146 	size_t to_alloc;
147 
148 	size += EVBUFFER_CHAIN_SIZE;
149 
150 	/* get the next largest memory that can hold the buffer */
151 	to_alloc = MIN_BUFFER_SIZE;
152 	while (to_alloc < size)
153 		to_alloc <<= 1;
154 
155 	/* we get everything in one chunk */
156 	if ((chain = mm_malloc(to_alloc)) == NULL)
157 		return (NULL);
158 
159 	memset(chain, 0, EVBUFFER_CHAIN_SIZE);
160 
161 	chain->buffer_len = to_alloc - EVBUFFER_CHAIN_SIZE;
162 
163 	/* this way we can manipulate the buffer to different addresses,
164 	 * which is required for mmap for example.
165 	 */
166 	chain->buffer = EVBUFFER_CHAIN_EXTRA(u_char, chain);
167 
168 	return (chain);
169 }
170 
171 static inline void
172 evbuffer_chain_free(struct evbuffer_chain *chain)
173 {
174 	if (CHAIN_PINNED(chain)) {
175 		chain->flags |= EVBUFFER_DANGLING;
176 		return;
177 	}
178 	if (chain->flags & (EVBUFFER_MMAP|EVBUFFER_SENDFILE|
179 		EVBUFFER_REFERENCE)) {
180 		if (chain->flags & EVBUFFER_REFERENCE) {
181 			struct evbuffer_chain_reference *info =
182 			    EVBUFFER_CHAIN_EXTRA(
183 				    struct evbuffer_chain_reference,
184 				    chain);
185 			if (info->cleanupfn)
186 				(*info->cleanupfn)(chain->buffer,
187 				    chain->buffer_len,
188 				    info->extra);
189 		}
190 #ifdef _EVENT_HAVE_MMAP
191 		if (chain->flags & EVBUFFER_MMAP) {
192 			struct evbuffer_chain_fd *info =
193 			    EVBUFFER_CHAIN_EXTRA(struct evbuffer_chain_fd,
194 				chain);
195 			if (munmap(chain->buffer, chain->buffer_len) == -1)
196 				event_warn("%s: munmap failed", __func__);
197 			if (close(info->fd) == -1)
198 				event_warn("%s: close(%d) failed",
199 				    __func__, info->fd);
200 		}
201 #endif
202 #ifdef USE_SENDFILE
203 		if (chain->flags & EVBUFFER_SENDFILE) {
204 			struct evbuffer_chain_fd *info =
205 			    EVBUFFER_CHAIN_EXTRA(struct evbuffer_chain_fd,
206 				chain);
207 			if (close(info->fd) == -1)
208 				event_warn("%s: close(%d) failed",
209 				    __func__, info->fd);
210 		}
211 #endif
212 	}
213 	mm_free(chain);
214 }
215 
216 static inline void
217 evbuffer_chain_insert(struct evbuffer *buf, struct evbuffer_chain *chain)
218 {
219 	ASSERT_EVBUFFER_LOCKED(buf);
220 	if (buf->first == NULL) {
221 		buf->first = buf->last = chain;
222 		buf->previous_to_last = NULL;
223 	} else {
224 		/* the last chain is empty so we can just drop it */
225 		if (buf->last->off == 0 && !CHAIN_PINNED(buf->last)) {
226 			evbuffer_chain_free(buf->last);
227 			buf->previous_to_last->next = chain;
228 			buf->last = chain;
229 		} else {
230 			buf->previous_to_last = buf->last;
231 			buf->last->next = chain;
232 			buf->last = chain;
233 		}
234 	}
235 
236 	buf->total_len += chain->off;
237 }
238 
239 void
240 _evbuffer_chain_pin(struct evbuffer_chain *chain, unsigned flag)
241 {
242 	EVUTIL_ASSERT((chain->flags & flag) == 0);
243 	chain->flags |= flag;
244 }
245 
246 void
247 _evbuffer_chain_unpin(struct evbuffer_chain *chain, unsigned flag)
248 {
249 	EVUTIL_ASSERT((chain->flags & flag) != 0);
250 	chain->flags &= ~flag;
251 	if (chain->flags & EVBUFFER_DANGLING)
252 		evbuffer_chain_free(chain);
253 }
254 
255 struct evbuffer *
256 evbuffer_new(void)
257 {
258 	struct evbuffer *buffer;
259 
260 	buffer = mm_calloc(1, sizeof(struct evbuffer));
261 	if (buffer == NULL)
262 		return (NULL);
263 
264 	TAILQ_INIT(&buffer->callbacks);
265 	buffer->refcnt = 1;
266 
267 	return (buffer);
268 }
269 
270 void
271 _evbuffer_incref(struct evbuffer *buf)
272 {
273 	EVBUFFER_LOCK(buf);
274 	++buf->refcnt;
275 	EVBUFFER_UNLOCK(buf);
276 }
277 
278 void
279 _evbuffer_incref_and_lock(struct evbuffer *buf)
280 {
281 	EVBUFFER_LOCK(buf);
282 	++buf->refcnt;
283 }
284 
285 int
286 evbuffer_defer_callbacks(struct evbuffer *buffer, struct event_base *base)
287 {
288 	EVBUFFER_LOCK(buffer);
289 	buffer->cb_queue = event_base_get_deferred_cb_queue(base);
290 	buffer->deferred_cbs = 1;
291 	event_deferred_cb_init(&buffer->deferred,
292 	    evbuffer_deferred_callback, buffer);
293 	EVBUFFER_UNLOCK(buffer);
294 	return 0;
295 }
296 
297 int
298 evbuffer_enable_locking(struct evbuffer *buf, void *lock)
299 {
300 #ifdef _EVENT_DISABLE_THREAD_SUPPORT
301 	return -1;
302 #else
303 	if (buf->lock)
304 		return -1;
305 
306 	if (!lock) {
307 		EVTHREAD_ALLOC_LOCK(lock, EVTHREAD_LOCKTYPE_RECURSIVE);
308 		if (!lock)
309 			return -1;
310 		buf->lock = lock;
311 		buf->own_lock = 1;
312 	} else {
313 		buf->lock = lock;
314 		buf->own_lock = 0;
315 	}
316 
317 	return 0;
318 #endif
319 }
320 
321 void
322 evbuffer_set_parent(struct evbuffer *buf, struct bufferevent *bev)
323 {
324 	EVBUFFER_LOCK(buf);
325 	buf->parent = bev;
326 	EVBUFFER_UNLOCK(buf);
327 }
328 
329 static void
330 evbuffer_run_callbacks(struct evbuffer *buffer, int running_deferred)
331 {
332 	struct evbuffer_cb_entry *cbent, *next;
333 	struct evbuffer_cb_info info;
334 	size_t new_size;
335 	ev_uint32_t mask, masked_val;
336 	int clear = 1;
337 
338 	if (running_deferred) {
339 		mask = EVBUFFER_CB_NODEFER|EVBUFFER_CB_ENABLED;
340 		masked_val = EVBUFFER_CB_ENABLED;
341 	} else if (buffer->deferred_cbs) {
342 		mask = EVBUFFER_CB_NODEFER|EVBUFFER_CB_ENABLED;
343 		masked_val = EVBUFFER_CB_NODEFER|EVBUFFER_CB_ENABLED;
344 		/* Don't zero-out n_add/n_del, since the deferred callbacks
345 		   will want to see them. */
346 		clear = 0;
347 	} else {
348 		mask = EVBUFFER_CB_ENABLED;
349 		masked_val = EVBUFFER_CB_ENABLED;
350 	}
351 
352 	ASSERT_EVBUFFER_LOCKED(buffer);
353 
354 	if (TAILQ_EMPTY(&buffer->callbacks)) {
355 		buffer->n_add_for_cb = buffer->n_del_for_cb = 0;
356 		return;
357 	}
358 	if (buffer->n_add_for_cb == 0 && buffer->n_del_for_cb == 0)
359 		return;
360 
361 	new_size = buffer->total_len;
362 	info.orig_size = new_size + buffer->n_del_for_cb - buffer->n_add_for_cb;
363 	info.n_added = buffer->n_add_for_cb;
364 	info.n_deleted = buffer->n_del_for_cb;
365 	if (clear) {
366 		buffer->n_add_for_cb = 0;
367 		buffer->n_del_for_cb = 0;
368 	}
369 	for (cbent = TAILQ_FIRST(&buffer->callbacks);
370 	     cbent != TAILQ_END(&buffer->callbacks);
371 	     cbent = next) {
372 		/* Get the 'next' pointer now in case this callback decides
373 		 * to remove itself or something. */
374 		next = TAILQ_NEXT(cbent, next);
375 
376 		if ((cbent->flags & mask) != masked_val)
377 			continue;
378 
379 		if ((cbent->flags & EVBUFFER_CB_OBSOLETE))
380 			cbent->cb.cb_obsolete(buffer,
381 			    info.orig_size, new_size, cbent->cbarg);
382 		else
383 			cbent->cb.cb_func(buffer, &info, cbent->cbarg);
384 	}
385 }
386 
387 static inline void
388 evbuffer_invoke_callbacks(struct evbuffer *buffer)
389 {
390 	if (buffer->deferred_cbs) {
391 		if (buffer->deferred.queued)
392 			return;
393 		_evbuffer_incref_and_lock(buffer);
394 		if (buffer->parent)
395 			bufferevent_incref(buffer->parent);
396 		EVBUFFER_UNLOCK(buffer);
397 		event_deferred_cb_schedule(buffer->cb_queue, &buffer->deferred);
398 	}
399 
400 	evbuffer_run_callbacks(buffer, 0);
401 }
402 
403 static void
404 evbuffer_deferred_callback(struct deferred_cb *cb, void *arg)
405 {
406 	struct bufferevent *parent = NULL;
407 	struct evbuffer *buffer = arg;
408 
409 	/* XXXX It would be better to run these callbacks without holding the
410 	 * lock */
411 	EVBUFFER_LOCK(buffer);
412 	parent = buffer->parent;
413 	evbuffer_run_callbacks(buffer, 1);
414 	_evbuffer_decref_and_unlock(buffer);
415 	if (parent)
416 		bufferevent_free(parent);
417 }
418 
419 static void
420 evbuffer_remove_all_callbacks(struct evbuffer *buffer)
421 {
422 	struct evbuffer_cb_entry *cbent;
423 
424 	while ((cbent = TAILQ_FIRST(&buffer->callbacks))) {
425 	    TAILQ_REMOVE(&buffer->callbacks, cbent, next);
426 	    mm_free(cbent);
427 	}
428 }
429 
430 void
431 _evbuffer_decref_and_unlock(struct evbuffer *buffer)
432 {
433 	struct evbuffer_chain *chain, *next;
434 	ASSERT_EVBUFFER_LOCKED(buffer);
435 
436 	if (--buffer->refcnt > 0) {
437 		EVBUFFER_UNLOCK(buffer);
438 		return;
439 	}
440 
441 	for (chain = buffer->first; chain != NULL; chain = next) {
442 		next = chain->next;
443 		evbuffer_chain_free(chain);
444 	}
445 	evbuffer_remove_all_callbacks(buffer);
446 	if (buffer->deferred_cbs)
447 		event_deferred_cb_cancel(buffer->cb_queue, &buffer->deferred);
448 
449 	EVBUFFER_UNLOCK(buffer);
450 	if (buffer->own_lock)
451 		EVTHREAD_FREE_LOCK(buffer->lock, EVTHREAD_LOCKTYPE_RECURSIVE);
452 	mm_free(buffer);
453 }
454 
455 void
456 evbuffer_free(struct evbuffer *buffer)
457 {
458 	EVBUFFER_LOCK(buffer);
459 	_evbuffer_decref_and_unlock(buffer);
460 }
461 
462 void
463 evbuffer_lock(struct evbuffer *buf)
464 {
465 	EVBUFFER_LOCK(buf);
466 }
467 
468 void
469 evbuffer_unlock(struct evbuffer *buf)
470 {
471 	EVBUFFER_UNLOCK(buf);
472 }
473 
474 size_t
475 evbuffer_get_length(const struct evbuffer *buffer)
476 {
477 	size_t result;
478 
479 	EVBUFFER_LOCK(buffer);
480 
481 	result = (buffer->total_len);
482 
483 	EVBUFFER_UNLOCK(buffer);
484 
485 	return result;
486 }
487 
488 size_t
489 evbuffer_get_contiguous_space(const struct evbuffer *buf)
490 {
491 	struct evbuffer_chain *chain;
492 	size_t result;
493 
494 	EVBUFFER_LOCK(buf);
495 	chain = buf->first;
496 	result = (chain != NULL ? chain->off : 0);
497 	EVBUFFER_UNLOCK(buf);
498 
499 	return result;
500 }
501 
502 int
503 evbuffer_reserve_space(struct evbuffer *buf, ev_ssize_t size,
504     struct evbuffer_iovec *vec, int n_vecs)
505 {
506 	struct evbuffer_chain *chain;
507 	int n = -1;
508 
509 	EVBUFFER_LOCK(buf);
510 	if (buf->freeze_end)
511 		goto done;
512 	if (n_vecs < 1)
513 		goto done;
514 	if (n_vecs == 1) {
515 		if (evbuffer_expand(buf, size) == -1)
516 			goto done;
517 		chain = buf->last;
518 
519 		vec[0].iov_base = CHAIN_SPACE_PTR(chain);
520 		vec[0].iov_len = CHAIN_SPACE_LEN(chain);
521 		n = 1;
522 	} else {
523 		if (_evbuffer_expand_fast(buf, size)<0)
524 			goto done;
525 		n = _evbuffer_read_setup_vecs(buf, size, vec, &chain, 0);
526 	}
527 
528 done:
529 	EVBUFFER_UNLOCK(buf);
530 	return n;
531 
532 }
533 
534 int
535 evbuffer_commit_space(struct evbuffer *buf,
536     struct evbuffer_iovec *vec, int n_vecs)
537 {
538 	struct evbuffer_chain *last, *prev;
539 	int result = -1;
540 	size_t added;
541 
542 	EVBUFFER_LOCK(buf);
543 
544 	prev = buf->previous_to_last;
545 	last = buf->last;
546 
547 	if (buf->freeze_end)
548 		goto done;
549 	if (n_vecs < 1 || n_vecs > 2)
550 		goto done;
551 	if (n_vecs == 2) {
552 		if (!prev || !last ||
553 		    vec[0].iov_base != CHAIN_SPACE_PTR(prev) ||
554 		    vec[1].iov_base != CHAIN_SPACE_PTR(last) ||
555 		    vec[0].iov_len > CHAIN_SPACE_LEN(prev) ||
556 		    vec[1].iov_len > CHAIN_SPACE_LEN(last))
557 			goto done;
558 
559 		prev->off += vec[0].iov_len;
560 		last->off += vec[1].iov_len;
561 		added = vec[0].iov_len + vec[1].iov_len;
562 	} else {
563 		/* n_vecs == 1 */
564 		struct evbuffer_chain *chain;
565 		if (prev && vec[0].iov_base == CHAIN_SPACE_PTR(prev))
566 			chain = prev;
567 		else if (last && vec[0].iov_base == CHAIN_SPACE_PTR(last))
568 			chain = last;
569 		else
570 			goto done;
571 		if (vec[0].iov_len > CHAIN_SPACE_LEN(chain))
572 			goto done;
573 
574 		chain->off += vec[0].iov_len;
575 		added = vec[0].iov_len;
576 	}
577 
578 	buf->total_len += added;
579 	buf->n_add_for_cb += added;
580 	result = 0;
581 	evbuffer_invoke_callbacks(buf);
582 
583 done:
584 	EVBUFFER_UNLOCK(buf);
585 	return result;
586 }
587 
588 #define ZERO_CHAIN(dst) do { \
589 		ASSERT_EVBUFFER_LOCKED(dst);	\
590 		(dst)->first = NULL;		\
591 		(dst)->last = NULL;		\
592 		(dst)->previous_to_last = NULL; \
593 		(dst)->total_len = 0;		\
594 	} while (0)
595 
596 #define COPY_CHAIN(dst, src) do { \
597 		ASSERT_EVBUFFER_LOCKED(dst);			   \
598 		ASSERT_EVBUFFER_LOCKED(src);			   \
599 		(dst)->first = (src)->first;			   \
600 		(dst)->previous_to_last = (src)->previous_to_last; \
601 		(dst)->last = (src)->last;			   \
602 		(dst)->total_len = (src)->total_len;		   \
603 	} while (0)
604 
605 #define APPEND_CHAIN(dst, src) do {					\
606 		ASSERT_EVBUFFER_LOCKED(dst);				\
607 		ASSERT_EVBUFFER_LOCKED(src);				\
608 		(dst)->last->next = (src)->first;			\
609 		(dst)->previous_to_last = (src)->previous_to_last ?	\
610 		    (src)->previous_to_last : (dst)->last;		\
611 		(dst)->last = (src)->last;				\
612 		(dst)->total_len += (src)->total_len;			\
613 	} while (0)
614 
615 #define PREPEND_CHAIN(dst, src) do {				   \
616 		ASSERT_EVBUFFER_LOCKED(dst);			   \
617 		ASSERT_EVBUFFER_LOCKED(src);			   \
618 		(src)->last->next = (dst)->first;		   \
619 		(dst)->first = (src)->first;			   \
620 		(dst)->total_len += (src)->total_len;		   \
621 		if ((dst)->previous_to_last == NULL)		   \
622 			(dst)->previous_to_last = (src)->last;	   \
623 	} while (0)
624 
625 
626 int
627 evbuffer_add_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf)
628 {
629 	size_t in_total_len, out_total_len;
630 	int result = 0;
631 
632 	EVBUFFER_LOCK2(inbuf, outbuf);
633 	in_total_len = inbuf->total_len;
634 	out_total_len = outbuf->total_len;
635 
636 	if (in_total_len == 0 || outbuf == inbuf)
637 		goto done;
638 
639 	if (outbuf->freeze_end || inbuf->freeze_start) {
640 		result = -1;
641 		goto done;
642 	}
643 
644 	if (out_total_len == 0) {
645 		COPY_CHAIN(outbuf, inbuf);
646 	} else {
647 		APPEND_CHAIN(outbuf, inbuf);
648 	}
649 
650 	/* remove everything from inbuf */
651 	ZERO_CHAIN(inbuf);
652 	inbuf->n_del_for_cb += in_total_len;
653 	outbuf->n_add_for_cb += in_total_len;
654 
655 	evbuffer_invoke_callbacks(inbuf);
656 	evbuffer_invoke_callbacks(outbuf);
657 
658 done:
659 	EVBUFFER_UNLOCK2(inbuf, outbuf);
660 	return result;
661 }
662 
663 int
664 evbuffer_prepend_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf)
665 {
666 	size_t in_total_len, out_total_len;
667 	int result = 0;
668 
669 	EVBUFFER_LOCK2(inbuf, outbuf);
670 
671 	in_total_len = inbuf->total_len;
672 	out_total_len = outbuf->total_len;
673 
674 	if (!in_total_len || inbuf == outbuf)
675 		goto done;
676 
677 	if (outbuf->freeze_start || inbuf->freeze_start) {
678 		result = -1;
679 		goto done;
680 	}
681 
682 	if (out_total_len == 0) {
683 		COPY_CHAIN(outbuf, inbuf);
684 	} else {
685 		PREPEND_CHAIN(outbuf, inbuf);
686 	}
687 
688 	/* remove everything from inbuf */
689 	ZERO_CHAIN(inbuf);
690 	inbuf->n_del_for_cb += in_total_len;
691 	outbuf->n_add_for_cb += in_total_len;
692 
693 	evbuffer_invoke_callbacks(inbuf);
694 	evbuffer_invoke_callbacks(outbuf);
695 done:
696 	EVBUFFER_UNLOCK2(inbuf, outbuf);
697 	return result;
698 }
699 
700 int
701 evbuffer_drain(struct evbuffer *buf, size_t len)
702 {
703 	struct evbuffer_chain *chain, *next;
704 	size_t old_len;
705 	int result = 0;
706 
707 	EVBUFFER_LOCK(buf);
708 	old_len = buf->total_len;
709 
710 	if (old_len == 0)
711 		goto done;
712 
713 	if (buf->freeze_start) {
714 		result = -1;
715 		goto done;
716 	}
717 
718 
719 	if (len >= old_len && !(buf->last && CHAIN_PINNED_R(buf->last))) {
720 		len = old_len;
721 		for (chain = buf->first; chain != NULL; chain = next) {
722 			next = chain->next;
723 
724 			evbuffer_chain_free(chain);
725 		}
726 
727 		ZERO_CHAIN(buf);
728 	} else {
729 		if (len >= old_len)
730 			len = old_len;
731 
732 		buf->total_len -= len;
733 
734 		for (chain = buf->first; len >= chain->off; chain = next) {
735 			next = chain->next;
736 			len -= chain->off;
737 
738 			if (len == 0 && CHAIN_PINNED_R(chain))
739 				break;
740 			evbuffer_chain_free(chain);
741 		}
742 
743 		buf->first = chain;
744 		if (buf->first == buf->last)
745 			buf->previous_to_last = NULL;
746 		chain->misalign += len;
747 		chain->off -= len;
748 	}
749 
750 	buf->n_del_for_cb += len;
751 	/* Tell someone about changes in this buffer */
752 	evbuffer_invoke_callbacks(buf);
753 
754 done:
755 	EVBUFFER_UNLOCK(buf);
756 	return result;
757 }
758 
759 /* Reads data from an event buffer and drains the bytes read */
760 
761 int
762 evbuffer_remove(struct evbuffer *buf, void *data_out, size_t datlen)
763 {
764 	/*XXX fails badly on sendfile case. */
765 	struct evbuffer_chain *chain, *tmp;
766 	char *data = data_out;
767 	size_t nread;
768 	int result = 0;
769 
770 	EVBUFFER_LOCK(buf);
771 
772 	chain = buf->first;
773 
774 	if (datlen >= buf->total_len)
775 		datlen = buf->total_len;
776 
777 	if (datlen == 0)
778 		goto done;
779 
780 	if (buf->freeze_start) {
781 		result = -1;
782 		goto done;
783 	}
784 
785 	nread = datlen;
786 
787 	while (datlen && datlen >= chain->off) {
788 		memcpy(data, chain->buffer + chain->misalign, chain->off);
789 		data += chain->off;
790 		datlen -= chain->off;
791 
792 		tmp = chain;
793 		chain = chain->next;
794 		evbuffer_chain_free(tmp);
795 	}
796 
797 	buf->first = chain;
798 	if (chain == NULL)
799 		buf->last = NULL;
800 	if (buf->first == buf->last)
801 		buf->previous_to_last = NULL;
802 
803 	if (datlen) {
804 		memcpy(data, chain->buffer + chain->misalign, datlen);
805 		chain->misalign += datlen;
806 		chain->off -= datlen;
807 	}
808 
809 	buf->total_len -= nread;
810 
811 	buf->n_del_for_cb += nread;
812 	if (nread)
813 		evbuffer_invoke_callbacks(buf);
814 
815 	result = nread;
816 done:
817 	EVBUFFER_UNLOCK(buf);
818 	return result;
819 }
820 
821 /* reads data from the src buffer to the dst buffer, avoids memcpy as
822  * possible. */
823 int
824 evbuffer_remove_buffer(struct evbuffer *src, struct evbuffer *dst,
825     size_t datlen)
826 {
827 	/*XXX We should have an option to force this to be zero-copy.*/
828 
829 	/*XXX can fail badly on sendfile case. */
830 	struct evbuffer_chain *chain, *previous, *previous_to_previous = NULL;
831 	size_t nread = 0;
832 	int result;
833 
834 	EVBUFFER_LOCK2(src, dst);
835 
836 	chain = previous = src->first;
837 
838 	if (datlen == 0 || dst == src) {
839 		result = 0;
840 		goto done;
841 	}
842 
843 	if (dst->freeze_end || src->freeze_start) {
844 		result = -1;
845 		goto done;
846 	}
847 
848 	/* short-cut if there is no more data buffered */
849 	if (datlen >= src->total_len) {
850 		datlen = src->total_len;
851 		evbuffer_add_buffer(dst, src);
852 		result = datlen;
853 		goto done;
854 	}
855 
856 	/* removes chains if possible */
857 	while (chain->off <= datlen) {
858 		nread += chain->off;
859 		datlen -= chain->off;
860 		previous_to_previous = previous;
861 		previous = chain;
862 		chain = chain->next;
863 	}
864 
865 	if (nread) {
866 		/* we can remove the chain */
867 		if (dst->first == NULL) {
868 			dst->first = src->first;
869 		} else {
870 			dst->last->next = src->first;
871 		}
872 		dst->previous_to_last = previous_to_previous;
873 		dst->last = previous;
874 		previous->next = NULL;
875 		src->first = chain;
876 		if (src->first == src->last)
877 			src->previous_to_last = NULL;
878 
879 		dst->total_len += nread;
880 		dst->n_add_for_cb += nread;
881 	}
882 
883 	/* we know that there is more data in the src buffer than
884 	 * we want to read, so we manually drain the chain */
885 	evbuffer_add(dst, chain->buffer + chain->misalign, datlen);
886 	chain->misalign += datlen;
887 	chain->off -= datlen;
888 	nread += datlen;
889 
890 	src->total_len -= nread;
891 	src->n_del_for_cb += nread;
892 
893 	if (nread) {
894 		evbuffer_invoke_callbacks(dst);
895 		evbuffer_invoke_callbacks(src);
896 	}
897 	result = nread;
898 
899 done:
900 	EVBUFFER_UNLOCK2(src, dst);
901 	return result;
902 }
903 
904 unsigned char *
905 evbuffer_pullup(struct evbuffer *buf, ev_ssize_t size)
906 {
907 	struct evbuffer_chain *chain, *next, *tmp;
908 	unsigned char *buffer, *result = NULL;
909 	ev_ssize_t remaining;
910 
911 	EVBUFFER_LOCK(buf);
912 
913 	chain = buf->first;
914 
915 	if (size < 0)
916 		size = buf->total_len;
917 	/* if size > buf->total_len, we cannot guarantee to the user that she
918 	 * is going to have a long enough buffer afterwards; so we return
919 	 * NULL */
920 	if (size == 0 || (size_t)size > buf->total_len)
921 		goto done;
922 
923 	/* No need to pull up anything; the first size bytes are
924 	 * already here. */
925 	if (chain->off >= (size_t)size) {
926 		result = chain->buffer + chain->misalign;
927 		goto done;
928 	}
929 
930 	/* Make sure that none of the chains we need to copy from is pinned. */
931 	remaining = size - chain->off;
932 	EVUTIL_ASSERT(remaining >= 0);
933 	for (tmp=chain->next; tmp; tmp=tmp->next) {
934 		if (CHAIN_PINNED(tmp))
935 			goto done;
936 		if (tmp->off >= (size_t)remaining)
937 			break;
938 		remaining -= tmp->off;
939 	}
940 
941 	if (CHAIN_PINNED(chain)) {
942 		size_t old_off = chain->off;
943 		if (CHAIN_SPACE_LEN(chain) < size - chain->off) {
944 			/* not enough room at end of chunk. */
945 			goto done;
946 		}
947 		buffer = CHAIN_SPACE_PTR(chain);
948 		tmp = chain;
949 		tmp->off = size;
950 		size -= old_off;
951 		chain = chain->next;
952 	} else if (chain->buffer_len - chain->misalign >= (size_t)size) {
953 		/* already have enough space in the first chain */
954 		size_t old_off = chain->off;
955 		buffer = chain->buffer + chain->misalign + chain->off;
956 		tmp = chain;
957 		tmp->off = size;
958 		size -= old_off;
959 		chain = chain->next;
960 	} else {
961 		if ((tmp = evbuffer_chain_new(size)) == NULL) {
962 			event_warn("%s: out of memory", __func__);
963 			goto done;
964 		}
965 		buffer = tmp->buffer;
966 		tmp->off = size;
967 		buf->first = tmp;
968 	}
969 
970 	/* TODO(niels): deal with buffers that point to NULL like sendfile */
971 
972 	/* Copy and free every chunk that will be entirely pulled into tmp */
973 	for (; chain != NULL && (size_t)size >= chain->off; chain = next) {
974 		next = chain->next;
975 
976 		memcpy(buffer, chain->buffer + chain->misalign, chain->off);
977 		size -= chain->off;
978 		buffer += chain->off;
979 
980 		evbuffer_chain_free(chain);
981 	}
982 
983 	if (chain != NULL) {
984 		memcpy(buffer, chain->buffer + chain->misalign, size);
985 		chain->misalign += size;
986 		chain->off -= size;
987 		if (chain == buf->last)
988 			buf->previous_to_last = tmp;
989 	} else {
990 		buf->last = tmp;
991 		/* the last is already the first, so we have no previous */
992 		buf->previous_to_last = NULL;
993 	}
994 
995 	tmp->next = chain;
996 
997 	result = (tmp->buffer + tmp->misalign);
998 
999 done:
1000 	EVBUFFER_UNLOCK(buf);
1001 	return result;
1002 }
1003 
1004 /*
1005  * Reads a line terminated by either '\r\n', '\n\r' or '\r' or '\n'.
1006  * The returned buffer needs to be freed by the called.
1007  */
1008 char *
1009 evbuffer_readline(struct evbuffer *buffer)
1010 {
1011 	return evbuffer_readln(buffer, NULL, EVBUFFER_EOL_ANY);
1012 }
1013 
1014 static inline int
1015 evbuffer_strchr(struct evbuffer_ptr *it, const char chr)
1016 {
1017 	struct evbuffer_chain *chain = it->_internal.chain;
1018 	unsigned i = it->_internal.pos_in_chain;
1019 	int count = 0;
1020 	while (chain != NULL) {
1021 		char *buffer = (char *)chain->buffer + chain->misalign;
1022 		for (; i < chain->off; ++i, ++count) {
1023 			if (buffer[i] == chr) {
1024 				it->_internal.chain = chain;
1025 				it->_internal.pos_in_chain = i;
1026 				it->pos += count;
1027 				return (count);
1028 			}
1029 		}
1030 		i = 0;
1031 		chain = chain->next;
1032 	}
1033 
1034 	return (-1);
1035 }
1036 
1037 static inline int
1038 evbuffer_strpbrk(struct evbuffer_ptr *it, const char *chrset)
1039 {
1040 	struct evbuffer_chain *chain = it->_internal.chain;
1041 	unsigned i = it->_internal.pos_in_chain;
1042 	int count = 0;
1043 	while (chain != NULL) {
1044 		char *buffer = (char *)chain->buffer + chain->misalign;
1045 		for (; i < chain->off; ++i, ++count) {
1046 			const char *p = chrset;
1047 			while (*p) {
1048 				if (buffer[i] == *p++) {
1049 					it->_internal.chain = chain;
1050 					it->_internal.pos_in_chain = i;
1051 					it->pos += count;
1052 					return (count);
1053 				}
1054 			}
1055 		}
1056 		i = 0;
1057 		chain = chain->next;
1058 	}
1059 
1060 	return (-1);
1061 }
1062 
1063 static inline int
1064 evbuffer_strspn(
1065 	struct evbuffer_ptr *ptr, const char *chrset)
1066 {
1067 	int count = 0;
1068 	struct evbuffer_chain *chain = ptr->_internal.chain;
1069 	unsigned i = ptr->_internal.pos_in_chain;
1070 
1071 	if (!chain)
1072 		return -1;
1073 
1074 	while (1) {
1075 		char *buffer = (char *)chain->buffer + chain->misalign;
1076 		for (; i < chain->off; ++i) {
1077 			const char *p = chrset;
1078 			while (*p) {
1079 				if (buffer[i] == *p++)
1080 					goto next;
1081 			}
1082 			ptr->_internal.chain = chain;
1083 			ptr->_internal.pos_in_chain = i;
1084 			ptr->pos += count;
1085 			return count;
1086 		next:
1087 			++count;
1088 		}
1089 		i = 0;
1090 
1091 		if (! chain->next) {
1092 			ptr->_internal.chain = chain;
1093 			ptr->_internal.pos_in_chain = i;
1094 			ptr->pos += count;
1095 			return count;
1096 		}
1097 
1098 		chain = chain->next;
1099 	}
1100 }
1101 
1102 
1103 static inline char
1104 evbuffer_getchr(struct evbuffer_ptr *it)
1105 {
1106 	struct evbuffer_chain *chain = it->_internal.chain;
1107 	int off = it->_internal.pos_in_chain;
1108 
1109 	return chain->buffer[chain->misalign + off];
1110 }
1111 
1112 struct evbuffer_ptr
1113 evbuffer_search_eol(struct evbuffer *buffer,
1114     struct evbuffer_ptr *start, size_t *eol_len_out,
1115     enum evbuffer_eol_style eol_style)
1116 {
1117 	struct evbuffer_ptr it, it2;
1118 	size_t extra_drain = 0;
1119 	int ok = 0;
1120 
1121 	EVBUFFER_LOCK(buffer);
1122 
1123 	if (start) {
1124 		memcpy(&it, start, sizeof(it));
1125 	} else {
1126 		it.pos = 0;
1127 		it._internal.chain = buffer->first;
1128 		it._internal.pos_in_chain = 0;
1129 	}
1130 
1131 	/* the eol_style determines our first stop character and how many
1132 	 * characters we are going to drain afterwards. */
1133 	switch (eol_style) {
1134 	case EVBUFFER_EOL_ANY:
1135 		if (evbuffer_strpbrk(&it, "\r\n") < 0)
1136 			goto done;
1137 		memcpy(&it2, &it, sizeof(it));
1138 		extra_drain = evbuffer_strspn(&it2, "\r\n");
1139 		break;
1140 	case EVBUFFER_EOL_CRLF_STRICT: {
1141 		it = evbuffer_search(buffer, "\r\n", 2, &it);
1142 		if (it.pos < 0)
1143 			goto done;
1144 		extra_drain = 2;
1145 		break;
1146 	}
1147 	case EVBUFFER_EOL_CRLF:
1148 		while (1) {
1149 			if (evbuffer_strpbrk(&it, "\r\n") < 0)
1150 				goto done;
1151 			if (evbuffer_getchr(&it) == '\n') {
1152 				extra_drain = 1;
1153 				break;
1154 			} else if (!evbuffer_ptr_memcmp(
1155 				    buffer, &it, "\r\n", 2)) {
1156 				extra_drain = 2;
1157 				break;
1158 			} else {
1159 				if (evbuffer_ptr_set(buffer, &it, 1,
1160 					EVBUFFER_PTR_ADD)<0)
1161 					goto done;
1162 			}
1163 		}
1164 		break;
1165 	case EVBUFFER_EOL_LF:
1166 		if (evbuffer_strchr(&it, '\n') < 0)
1167 			goto done;
1168 		extra_drain = 1;
1169 		break;
1170 	default:
1171 		goto done;
1172 	}
1173 
1174 	ok = 1;
1175 done:
1176 	EVBUFFER_UNLOCK(buffer);
1177 
1178 	if (!ok) {
1179 		it.pos = -1;
1180 	}
1181 	if (eol_len_out)
1182 		*eol_len_out = extra_drain;
1183 
1184 	return it;
1185 }
1186 
1187 char *
1188 evbuffer_readln(struct evbuffer *buffer, size_t *n_read_out,
1189 		enum evbuffer_eol_style eol_style)
1190 {
1191 	struct evbuffer_ptr it;
1192 	char *line;
1193 	size_t n_to_copy=0, extra_drain=0;
1194 	char *result = NULL;
1195 
1196 	EVBUFFER_LOCK(buffer);
1197 
1198 	if (buffer->freeze_start) {
1199 		goto done;
1200 	}
1201 
1202 	it = evbuffer_search_eol(buffer, NULL, &extra_drain, eol_style);
1203 	if (it.pos < 0)
1204 		goto done;
1205 	n_to_copy = it.pos;
1206 
1207 	if ((line = mm_malloc(n_to_copy+1)) == NULL) {
1208 		event_warn("%s: out of memory", __func__);
1209 		goto done;
1210 	}
1211 
1212 	evbuffer_remove(buffer, line, n_to_copy);
1213 	line[n_to_copy] = '\0';
1214 
1215 	evbuffer_drain(buffer, extra_drain);
1216 	result = line;
1217 done:
1218 	EVBUFFER_UNLOCK(buffer);
1219 
1220 	if (n_read_out)
1221 		*n_read_out = result ? n_to_copy : 0;
1222 
1223 	return result;
1224 }
1225 
1226 #define EVBUFFER_CHAIN_MAX_AUTO_SIZE 4096
1227 
1228 /* Adds data to an event buffer */
1229 
1230 int
1231 evbuffer_add(struct evbuffer *buf, const void *data_in, size_t datlen)
1232 {
1233 	struct evbuffer_chain *chain, *tmp;
1234 	const unsigned char *data = data_in;
1235 	size_t remain, to_alloc;
1236 	int result = -1;
1237 
1238 	EVBUFFER_LOCK(buf);
1239 
1240 	if (buf->freeze_end) {
1241 		goto done;
1242 	}
1243 
1244 	chain = buf->last;
1245 
1246 	/* If there are no chains allocated for this buffer, allocate one
1247 	 * big enough to hold all the data. */
1248 	if (chain == NULL) {
1249 		if (evbuffer_expand(buf, datlen) == -1)
1250 			goto done;
1251 		chain = buf->last;
1252 	}
1253 
1254 	if ((chain->flags & EVBUFFER_IMMUTABLE) == 0) {
1255 		remain = chain->buffer_len - chain->misalign - chain->off;
1256 		if (remain >= datlen) {
1257 			/* there's enough space to hold all the data in the
1258 			 * current last chain */
1259 			memcpy(chain->buffer + chain->misalign + chain->off,
1260 			    data, datlen);
1261 			chain->off += datlen;
1262 			buf->total_len += datlen;
1263 			buf->n_add_for_cb += datlen;
1264 			goto out;
1265 		} else if ((size_t)chain->misalign >= datlen && !CHAIN_PINNED(chain)) {
1266 			/* we can fit the data into the misalignment */
1267 			evbuffer_chain_align(chain);
1268 
1269 			memcpy(chain->buffer + chain->off, data, datlen);
1270 			chain->off += datlen;
1271 			buf->total_len += datlen;
1272 			buf->n_add_for_cb += datlen;
1273 			goto out;
1274 		}
1275 	} else {
1276 		/* we cannot write any data to the last chain */
1277 		remain = 0;
1278 	}
1279 
1280 	/* we need to add another chain */
1281 	to_alloc = chain->buffer_len;
1282 	if (to_alloc <= EVBUFFER_CHAIN_MAX_AUTO_SIZE/2)
1283 		to_alloc <<= 1;
1284 	if (datlen > to_alloc)
1285 		to_alloc = datlen;
1286 	tmp = evbuffer_chain_new(to_alloc);
1287 	if (tmp == NULL)
1288 		goto done;
1289 
1290 	if (remain) {
1291 		memcpy(chain->buffer + chain->misalign + chain->off,
1292 		    data, remain);
1293 		chain->off += remain;
1294 		buf->total_len += remain;
1295 		buf->n_add_for_cb += remain;
1296 	}
1297 
1298 	data += remain;
1299 	datlen -= remain;
1300 
1301 	memcpy(tmp->buffer, data, datlen);
1302 	tmp->off = datlen;
1303 	evbuffer_chain_insert(buf, tmp);
1304 
1305 out:
1306 	evbuffer_invoke_callbacks(buf);
1307 	result = 0;
1308 done:
1309 	EVBUFFER_UNLOCK(buf);
1310 	return result;
1311 }
1312 
1313 int
1314 evbuffer_prepend(struct evbuffer *buf, const void *data, size_t datlen)
1315 {
1316 	struct evbuffer_chain *chain, *tmp;
1317 	int result = -1;
1318 
1319 	EVBUFFER_LOCK(buf);
1320 
1321 	if (buf->freeze_start) {
1322 		goto done;
1323 	}
1324 
1325 	chain = buf->first;
1326 
1327 	if (chain == NULL) {
1328 		if (evbuffer_expand(buf, datlen) == -1)
1329 			goto done;
1330 		chain = buf->first;
1331 		chain->misalign = chain->buffer_len;
1332 	}
1333 
1334 	/* we cannot touch immutable buffers */
1335 	if ((chain->flags & EVBUFFER_IMMUTABLE) == 0) {
1336 		if ((size_t)chain->misalign >= datlen) {
1337 			/* we have enough space */
1338 			memcpy(chain->buffer + chain->misalign - datlen,
1339 			    data, datlen);
1340 			chain->off += datlen;
1341 			chain->misalign -= datlen;
1342 			buf->total_len += datlen;
1343 			buf->n_add_for_cb += datlen;
1344 			goto out;
1345 		} else if (chain->misalign) {
1346 			memcpy(chain->buffer,
1347 			    (char*)data + datlen - chain->misalign,
1348 			    chain->misalign);
1349 			chain->off += chain->misalign;
1350 			buf->total_len += chain->misalign;
1351 			buf->n_add_for_cb += chain->misalign;
1352 			datlen -= chain->misalign;
1353 			chain->misalign = 0;
1354 		}
1355 	}
1356 
1357 	/* we need to add another chain */
1358 	if ((tmp = evbuffer_chain_new(datlen)) == NULL)
1359 		goto done;
1360 	buf->first = tmp;
1361 	if (buf->previous_to_last == NULL)
1362 		buf->previous_to_last = tmp;
1363 	tmp->next = chain;
1364 
1365 	tmp->off = datlen;
1366 	tmp->misalign = tmp->buffer_len - datlen;
1367 
1368 	memcpy(tmp->buffer + tmp->misalign, data, datlen);
1369 	buf->total_len += datlen;
1370 	buf->n_add_for_cb += chain->misalign;
1371 
1372 out:
1373 	evbuffer_invoke_callbacks(buf);
1374 	result = 0;
1375 done:
1376 	EVBUFFER_UNLOCK(buf);
1377 	return result;
1378 }
1379 
1380 /** Helper: realigns the memory in chain->buffer so that misalign is 0. */
1381 static void
1382 evbuffer_chain_align(struct evbuffer_chain *chain)
1383 {
1384 	EVUTIL_ASSERT(!(chain->flags & EVBUFFER_IMMUTABLE));
1385 	EVUTIL_ASSERT(!(chain->flags & EVBUFFER_MEM_PINNED_ANY));
1386 	memmove(chain->buffer, chain->buffer + chain->misalign, chain->off);
1387 	chain->misalign = 0;
1388 }
1389 
1390 /* Expands the available space in the event buffer to at least datlen */
1391 
1392 int
1393 evbuffer_expand(struct evbuffer *buf, size_t datlen)
1394 {
1395 	/* XXX we should either make this function less costly, or call it
1396 	 * less often.	*/
1397 	struct evbuffer_chain *chain, *tmp;
1398 	size_t need, length;
1399 	int result = -1;
1400 
1401 	EVBUFFER_LOCK(buf);
1402 
1403 	chain = buf->last;
1404 
1405 	if (chain == NULL ||
1406 	    (chain->flags & (EVBUFFER_IMMUTABLE|EVBUFFER_MEM_PINNED_ANY))) {
1407 		chain = evbuffer_chain_new(datlen);
1408 		if (chain == NULL)
1409 			goto err;
1410 
1411 		evbuffer_chain_insert(buf, chain);
1412 		goto ok;
1413 	}
1414 
1415 	need = chain->misalign + chain->off + datlen;
1416 
1417 	/* If we can fit all the data, then we don't have to do anything */
1418 	if (chain->buffer_len >= need)
1419 		goto ok;
1420 
1421 	/* If the misalignment plus the remaining space fulfills our
1422 	 * data needs, we just force an alignment to happen.
1423 	 * Afterwards, we have enough space.
1424 	 */
1425 	if (chain->buffer_len - chain->off >= datlen) {
1426 		evbuffer_chain_align(chain);
1427 		goto ok;
1428 	}
1429 
1430 	/* figure out how much space we need */
1431 	length = chain->buffer_len - chain->misalign + datlen;
1432 	tmp = evbuffer_chain_new(length);
1433 	if (tmp == NULL)
1434 		goto err;
1435 	/* copy the data over that we had so far */
1436 	tmp->off = chain->off;
1437 	tmp->misalign = 0;
1438 	memcpy(tmp->buffer, chain->buffer + chain->misalign, chain->off);
1439 
1440 	/* fix up the chain */
1441 	if (buf->first == chain)
1442 		buf->first = tmp;
1443 	if (buf->previous_to_last)
1444 		buf->previous_to_last->next = tmp;
1445 	buf->last = tmp;
1446 
1447 	evbuffer_chain_free(chain);
1448 
1449 ok:
1450 	result = 0;
1451 err:
1452 	EVBUFFER_UNLOCK(buf);
1453 	return result;
1454 }
1455 
1456 /* Make sure that datlen bytes are available for writing in the last two
1457  * chains.  Never copies or moves data. */
1458 int
1459 _evbuffer_expand_fast(struct evbuffer *buf, size_t datlen)
1460 {
1461 	struct evbuffer_chain *chain = buf->last, *tmp;
1462 	size_t avail, avail_in_prev = 0;
1463 
1464 	ASSERT_EVBUFFER_LOCKED(buf);
1465 
1466 	if (chain == NULL || (chain->flags & EVBUFFER_IMMUTABLE)) {
1467 		chain = evbuffer_chain_new(datlen);
1468 		if (chain == NULL)
1469 			return (-1);
1470 
1471 		evbuffer_chain_insert(buf, chain);
1472 		return (0);
1473 	}
1474 
1475 	/* How many bytes can we stick at the end of chain? */
1476 
1477 	if (chain->off) {
1478 		avail = chain->buffer_len - (chain->off + chain->misalign);
1479 		avail_in_prev = 0;
1480 	} else {
1481 		/* No data in chain; realign it. */
1482 		chain->misalign = 0;
1483 		avail = chain->buffer_len;
1484 		/* Can we stick some data in the penultimate chain? */
1485 		if (buf->previous_to_last) {
1486 			struct evbuffer_chain *prev = buf->previous_to_last;
1487 			avail_in_prev = CHAIN_SPACE_LEN(prev);
1488 		}
1489 	}
1490 
1491 	/* If we can fit all the data, then we don't have to do anything */
1492 	if (avail+avail_in_prev >= datlen)
1493 		return (0);
1494 
1495 	/* Otherwise, we need a bigger chunk. */
1496 	if (chain->off == 0) {
1497 		/* If there are no bytes on this chain, free it and
1498 		   replace it with a better one. */
1499 		/* XXX round up. */
1500 		tmp = evbuffer_chain_new(datlen-avail_in_prev);
1501 		if (tmp == NULL)
1502 			return -1;
1503 		/* XXX write functions to in new chains */
1504 		if (buf->first == chain)
1505 			buf->first = tmp;
1506 		if (buf->previous_to_last)
1507 			buf->previous_to_last->next = tmp;
1508 		buf->last = tmp;
1509 		evbuffer_chain_free(chain);
1510 
1511 	} else {
1512 		/* Add a new chunk big enough to hold what won't fit
1513 		 * in chunk. */
1514 		/*XXX round this up. */
1515 		tmp = evbuffer_chain_new(datlen-avail);
1516 		if (tmp == NULL)
1517 			return (-1);
1518 
1519 		buf->previous_to_last = chain;
1520 		chain->next = tmp;
1521 		buf->last = tmp;
1522 	}
1523 
1524 	return (0);
1525 }
1526 
1527 /*
1528  * Reads data from a file descriptor into a buffer.
1529  */
1530 
1531 #if defined(_EVENT_HAVE_SYS_UIO_H) || defined(WIN32)
1532 #define USE_IOVEC_IMPL
1533 #endif
1534 
1535 #ifdef USE_IOVEC_IMPL
1536 
1537 #ifdef _EVENT_HAVE_SYS_UIO_H
1538 /* number of iovec we use for writev, fragmentation is going to determine
1539  * how much we end up writing */
1540 #define NUM_IOVEC 128
1541 #define IOV_TYPE struct iovec
1542 #define IOV_PTR_FIELD iov_base
1543 #define IOV_LEN_FIELD iov_len
1544 #else
1545 #define NUM_IOVEC 16
1546 #define IOV_TYPE WSABUF
1547 #define IOV_PTR_FIELD buf
1548 #define IOV_LEN_FIELD len
1549 #endif
1550 #endif
1551 
1552 #define EVBUFFER_MAX_READ	4096
1553 
1554 /** Helper function to figure out which space to use for reading data into
1555     an evbuffer.  Internal use only.
1556 
1557     @param buf The buffer to read into
1558     @param howmuch How much we want to read.
1559     @param vecs An array of two iovecs or WSABUFs.
1560     @param chainp A pointer to a variable to hold the first chain we're
1561       reading into.
1562     @param exact Boolean: if true, we do not provide more than 'howmuch'
1563       space in the vectors, even if more space is available.
1564     @return The number of buffers we're using.
1565  */
1566 int
1567 _evbuffer_read_setup_vecs(struct evbuffer *buf, ev_ssize_t howmuch,
1568     struct evbuffer_iovec *vecs, struct evbuffer_chain **chainp, int exact)
1569 {
1570 	struct evbuffer_chain *chain;
1571 	int nvecs;
1572 
1573 	if (howmuch < 0)
1574 		return -1;
1575 
1576 	chain = buf->last;
1577 
1578 	if (chain->off == 0 && buf->previous_to_last &&
1579 	    CHAIN_SPACE_LEN(buf->previous_to_last)) {
1580 		/* The last chain is empty, so it's safe to
1581 		   use the space in the next-to-last chain.
1582 		*/
1583 		struct evbuffer_chain *prev = buf->previous_to_last;
1584 		vecs[0].iov_base = CHAIN_SPACE_PTR(prev);
1585 		vecs[0].iov_len = CHAIN_SPACE_LEN(prev);
1586 		vecs[1].iov_base = CHAIN_SPACE_PTR(chain);
1587 		vecs[1].iov_len = CHAIN_SPACE_LEN(chain);
1588 		if (vecs[0].iov_len >= (size_t)howmuch) {
1589 			/* The next-to-last chain has enough
1590 			 * space on its own. */
1591 			chain = prev;
1592 			nvecs = 1;
1593 		} else {
1594 			/* We'll need both chains. */
1595 			chain = prev;
1596 			nvecs = 2;
1597 			if (exact &&
1598 			    (vecs[0].iov_len + vecs[1].iov_len > (size_t)howmuch)) {
1599 				vecs[1].iov_len = howmuch - vecs[0].iov_len;
1600 			}
1601 		}
1602 	} else {
1603 		/* There's data in the last chain, so we're
1604 		 * not allowed to use the next-to-last. */
1605 		nvecs = 1;
1606 		vecs[0].iov_base = CHAIN_SPACE_PTR(chain);
1607 		vecs[0].iov_len = CHAIN_SPACE_LEN(chain);
1608 		if (exact && (vecs[0].iov_len > (size_t)howmuch))
1609 			vecs[0].iov_len = howmuch;
1610 	}
1611 
1612 	*chainp = chain;
1613 	return nvecs;
1614 }
1615 
1616 /* TODO(niels): should this function return ev_ssize_t and take ev_ssize_t
1617  * as howmuch? */
1618 int
1619 evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch)
1620 {
1621 	struct evbuffer_chain *chain;
1622 	int n = EVBUFFER_MAX_READ;
1623 	int result;
1624 
1625 #ifdef USE_IOVEC_IMPL
1626 	int nvecs;
1627 #else
1628 	unsigned char *p;
1629 #endif
1630 #if defined(FIONREAD) && defined(WIN32)
1631 	long lng = n;
1632 #endif
1633 
1634 	EVBUFFER_LOCK(buf);
1635 
1636 	chain = buf->last;
1637 
1638 	if (buf->freeze_end) {
1639 		result = -1;
1640 		goto done;
1641 	}
1642 
1643 #if defined(FIONREAD)
1644 #ifdef WIN32
1645 	if (ioctlsocket(fd, FIONREAD, &lng) == -1 || (n=lng) <= 0) {
1646 #else
1647 	if (ioctl(fd, FIONREAD, &n) == -1 || n <= 0) {
1648 #endif
1649 		n = EVBUFFER_MAX_READ;
1650 	} else if (n > EVBUFFER_MAX_READ && n > howmuch) {
1651 		/*
1652 		 * It's possible that a lot of data is available for
1653 		 * reading.  We do not want to exhaust resources
1654 		 * before the reader has a chance to do something
1655 		 * about it.  If the reader does not tell us how much
1656 		 * data we should read, we artificially limit it.
1657 		 */
1658 		if (chain == NULL || n < EVBUFFER_MAX_READ)
1659 			n = EVBUFFER_MAX_READ;
1660 		else if ((size_t)n > chain->buffer_len << 2)
1661 			n = chain->buffer_len << 2;
1662 	}
1663 #endif
1664 	if (howmuch < 0 || howmuch > n)
1665 		howmuch = n;
1666 
1667 #ifdef USE_IOVEC_IMPL
1668 	/* Since we can use iovecs, we're willing to use the last
1669 	 * _two_ chains. */
1670 	if (_evbuffer_expand_fast(buf, howmuch) == -1) {
1671 		result = -1;
1672 		goto done;
1673 	} else {
1674 		IOV_TYPE vecs[2];
1675 #ifdef _EVBUFFER_IOVEC_IS_NATIVE
1676 		nvecs = _evbuffer_read_setup_vecs(buf, howmuch, vecs,
1677 		    &chain, 1);
1678 #else
1679 		/* We aren't using the native struct iovec.  Therefore,
1680 		   we are on win32. */
1681 		struct evbuffer_iovec ev_vecs[2];
1682 		nvecs = _evbuffer_read_setup_vecs(buf, howmuch, ev_vecs,
1683 		    &chain, 1);
1684 
1685 		if (nvecs == 2) {
1686 			WSABUF_FROM_EVBUFFER_IOV(&vecs[1], &ev_vecs[1]);
1687 			WSABUF_FROM_EVBUFFER_IOV(&vecs[0], &ev_vecs[0]);
1688 		} else if (nvecs == 1) {
1689 			WSABUF_FROM_EVBUFFER_IOV(&vecs[0], &ev_vecs[0]);
1690 		}
1691 #endif
1692 
1693 #ifdef WIN32
1694 		{
1695 			DWORD bytesRead;
1696 			DWORD flags=0;
1697 			if (WSARecv(fd, vecs, nvecs, &bytesRead, &flags, NULL, NULL)) {
1698 				/* The read failed. It might be a close,
1699 				 * or it might be an error. */
1700 				if (WSAGetLastError() == WSAECONNABORTED)
1701 					n = 0;
1702 				else
1703 					n = -1;
1704 			} else
1705 				n = bytesRead;
1706 		}
1707 #else
1708 		n = readv(fd, vecs, nvecs);
1709 #endif
1710 	}
1711 
1712 #else /*!USE_IOVEC_IMPL*/
1713 	/* If we don't have FIONREAD, we might waste some space here */
1714 	/* XXX we _will_ waste some space here if there is any space left
1715 	 * over on buf->last. */
1716 	if (evbuffer_expand(buf, howmuch) == -1) {
1717 		result = -1;
1718 		goto done;
1719 	}
1720 
1721 	chain = buf->last;
1722 
1723 	/* We can append new data at this point */
1724 	p = chain->buffer + chain->misalign + chain->off;
1725 
1726 #ifndef WIN32
1727 	n = read(fd, p, howmuch);
1728 #else
1729 	n = recv(fd, p, howmuch, 0);
1730 #endif
1731 #endif /* USE_IOVEC_IMPL */
1732 
1733 	if (n == -1) {
1734 		result = -1;
1735 		goto done;
1736 	}
1737 	if (n == 0) {
1738 		result = 0;
1739 		goto done;
1740 	}
1741 
1742 #ifdef USE_IOVEC_IMPL
1743 	if (nvecs == 2) {
1744 		ev_ssize_t space = CHAIN_SPACE_LEN(chain);
1745 		if (space < n) {
1746 			chain->off += space;
1747 			chain->next->off += n-space;
1748 		} else {
1749 			chain->off += n;
1750 		}
1751 	} else {
1752 		chain->off += n;
1753 	}
1754 #else
1755 	chain->off += n;
1756 #endif
1757 	buf->total_len += n;
1758 	buf->n_add_for_cb += n;
1759 
1760 	/* Tell someone about changes in this buffer */
1761 	evbuffer_invoke_callbacks(buf);
1762 	result = n;
1763 done:
1764 	EVBUFFER_UNLOCK(buf);
1765 	return result;
1766 }
1767 
1768 #ifdef USE_IOVEC_IMPL
1769 static inline int
1770 evbuffer_write_iovec(struct evbuffer *buffer, evutil_socket_t fd,
1771     ev_ssize_t howmuch)
1772 {
1773 	IOV_TYPE iov[NUM_IOVEC];
1774 	struct evbuffer_chain *chain = buffer->first;
1775 	int n, i = 0;
1776 
1777 	if (howmuch < 0)
1778 		return -1;
1779 
1780 	ASSERT_EVBUFFER_LOCKED(buffer);
1781 	/* XXX make this top out at some maximal data length?  if the
1782 	 * buffer has (say) 1MB in it, split over 128 chains, there's
1783 	 * no way it all gets written in one go. */
1784 	while (chain != NULL && i < NUM_IOVEC && howmuch) {
1785 #ifdef USE_SENDFILE
1786 		/* we cannot write the file info via writev */
1787 		if (chain->flags & EVBUFFER_SENDFILE)
1788 			break;
1789 #endif
1790 		iov[i].IOV_PTR_FIELD = chain->buffer + chain->misalign;
1791 		if ((size_t)howmuch >= chain->off) {
1792 			iov[i++].IOV_LEN_FIELD = chain->off;
1793 			howmuch -= chain->off;
1794 		} else {
1795 			iov[i++].IOV_LEN_FIELD = howmuch;
1796 			break;
1797 		}
1798 		chain = chain->next;
1799 	}
1800 #ifdef WIN32
1801 	{
1802 		DWORD bytesSent;
1803 		if (WSASend(fd, iov, i, &bytesSent, 0, NULL, NULL))
1804 			n = -1;
1805 		else
1806 			n = bytesSent;
1807 	}
1808 #else
1809 	n = writev(fd, iov, i);
1810 #endif
1811 	return (n);
1812 }
1813 #endif
1814 
1815 #ifdef USE_SENDFILE
1816 static inline int
1817 evbuffer_write_sendfile(struct evbuffer *buffer, evutil_socket_t fd,
1818     ev_ssize_t howmuch)
1819 {
1820 	struct evbuffer_chain *chain = buffer->first;
1821 	struct evbuffer_chain_fd *info =
1822 	    EVBUFFER_CHAIN_EXTRA(struct evbuffer_chain_fd, chain);
1823 #if defined(SENDFILE_IS_MACOSX) || defined(SENDFILE_IS_FREEBSD)
1824 	int res;
1825 	off_t len = chain->off;
1826 #elif defined(SENDFILE_IS_LINUX) || defined(SENDFILE_IS_SOLARIS)
1827 	ev_ssize_t res;
1828 	off_t offset = chain->misalign;
1829 #endif
1830 
1831 	ASSERT_EVBUFFER_LOCKED(buffer);
1832 
1833 #if defined(SENDFILE_IS_MACOSX)
1834 	res = sendfile(info->fd, fd, chain->misalign, &len, NULL, 0);
1835 	if (res == -1 && !EVUTIL_ERR_RW_RETRIABLE(errno))
1836 		return (-1);
1837 
1838 	return (len);
1839 #elif defined(SENDFILE_IS_FREEBSD)
1840 	res = sendfile(info->fd, fd, chain->misalign, chain->off, NULL, &len, 0);
1841 	if (res == -1 && !EVUTIL_ERR_RW_RETRIABLE(errno))
1842 		return (-1);
1843 
1844 	return (len);
1845 #elif defined(SENDFILE_IS_LINUX)
1846 	/* TODO(niels): implement splice */
1847 	res = sendfile(fd, info->fd, &offset, chain->off);
1848 	if (res == -1 && EVUTIL_ERR_RW_RETRIABLE(errno)) {
1849 		/* if this is EAGAIN or EINTR return 0; otherwise, -1 */
1850 		return (0);
1851 	}
1852 	return (res);
1853 #elif defined(SENDFILE_IS_SOLARIS)
1854 	res = sendfile(fd, info->fd, &offset, chain->off);
1855 	if (res == -1 && EVUTIL_ERR_RW_RETRIABLE(errno)) {
1856 		/* if this is EAGAIN or EINTR return 0; otherwise, -1 */
1857 		return (0);
1858 	}
1859 	return (res);
1860 #endif
1861 }
1862 #endif
1863 
1864 int
1865 evbuffer_write_atmost(struct evbuffer *buffer, evutil_socket_t fd,
1866     ev_ssize_t howmuch)
1867 {
1868 	int n = -1;
1869 
1870 	EVBUFFER_LOCK(buffer);
1871 
1872 	if (buffer->freeze_start) {
1873 		goto done;
1874 	}
1875 
1876 	if (howmuch < 0)
1877 		howmuch = buffer->total_len;
1878 
1879 	{
1880 #ifdef USE_SENDFILE
1881 		struct evbuffer_chain *chain = buffer->first;
1882 		if (chain != NULL && (chain->flags & EVBUFFER_SENDFILE))
1883 			n = evbuffer_write_sendfile(buffer, fd, howmuch);
1884 		else
1885 #endif
1886 #ifdef USE_IOVEC_IMPL
1887 		n = evbuffer_write_iovec(buffer, fd, howmuch);
1888 #elif defined(WIN32)
1889 		/* XXX(nickm) Don't disable this code until we know if
1890 		 * the WSARecv code above works. */
1891 		void *p = evbuffer_pullup(buffer, howmuch);
1892 		n = send(fd, p, howmuch, 0);
1893 #else
1894 		void *p = evbuffer_pullup(buffer, howmuch);
1895 		n = write(fd, p, howmuch);
1896 #endif
1897 	}
1898 
1899 	if (n > 0)
1900 		evbuffer_drain(buffer, n);
1901 
1902 done:
1903 	EVBUFFER_UNLOCK(buffer);
1904 	return (n);
1905 }
1906 
1907 int
1908 evbuffer_write(struct evbuffer *buffer, evutil_socket_t fd)
1909 {
1910 	return evbuffer_write_atmost(buffer, fd, -1);
1911 }
1912 
1913 unsigned char *
1914 evbuffer_find(struct evbuffer *buffer, const unsigned char *what, size_t len)
1915 {
1916 	unsigned char *search;
1917 	struct evbuffer_ptr ptr;
1918 
1919 	EVBUFFER_LOCK(buffer);
1920 
1921 	ptr = evbuffer_search(buffer, (const char *)what, len, NULL);
1922 	if (ptr.pos < 0) {
1923 		search = NULL;
1924 	} else {
1925 		search = evbuffer_pullup(buffer, ptr.pos + len);
1926 		if (search)
1927 			search += ptr.pos;
1928 	}
1929 	EVBUFFER_UNLOCK(buffer);
1930 	return search;
1931 }
1932 
1933 int
1934 evbuffer_ptr_set(struct evbuffer *buf, struct evbuffer_ptr *pos,
1935     size_t position, enum evbuffer_ptr_how how)
1936 {
1937 	size_t left = position;
1938 	struct evbuffer_chain *chain = NULL;
1939 
1940 	EVBUFFER_LOCK(buf);
1941 
1942 	switch (how) {
1943 	case EVBUFFER_PTR_SET:
1944 		chain = buf->first;
1945 		pos->pos = position;
1946 		position = 0;
1947 		break;
1948 	case EVBUFFER_PTR_ADD:
1949 		/* this avoids iterating over all previous chains if
1950 		   we just want to advance the position */
1951 		chain = pos->_internal.chain;
1952 		pos->pos += position;
1953 		position = pos->_internal.pos_in_chain;
1954 		break;
1955 	}
1956 
1957 	while (chain && position + left >= chain->off) {
1958 		left -= chain->off - position;
1959 		chain = chain->next;
1960 		position = 0;
1961 	}
1962 	if (chain) {
1963 		pos->_internal.chain = chain;
1964 		pos->_internal.pos_in_chain = position + left;
1965 	} else {
1966 		pos->_internal.chain = NULL;
1967 		pos->pos = -1;
1968 	}
1969 
1970 	EVBUFFER_UNLOCK(buf);
1971 
1972 	return chain != NULL ? 0 : -1;
1973 }
1974 
1975 /**
1976    Compare the bytes in buf at position pos to the len bytes in mem.  Return
1977    less than 0, 0, or greater than 0 as memcmp.
1978  */
1979 static int
1980 evbuffer_ptr_memcmp(const struct evbuffer *buf, const struct evbuffer_ptr *pos,
1981     const char *mem, size_t len)
1982 {
1983 	struct evbuffer_chain *chain;
1984 	size_t position;
1985 	int r;
1986 
1987 	ASSERT_EVBUFFER_LOCKED(buf);
1988 
1989 	if (pos->pos + len > buf->total_len)
1990 		return -1;
1991 
1992 	chain = pos->_internal.chain;
1993 	position = pos->_internal.pos_in_chain;
1994 	while (len && chain) {
1995 		size_t n_comparable;
1996 		if (len + position > chain->off)
1997 			n_comparable = chain->off - position;
1998 		else
1999 			n_comparable = len;
2000 		r = memcmp(chain->buffer + chain->misalign + position, mem,
2001 		    n_comparable);
2002 		if (r)
2003 			return r;
2004 		mem += n_comparable;
2005 		len -= n_comparable;
2006 		position = 0;
2007 		chain = chain->next;
2008 	}
2009 
2010 	return 0;
2011 }
2012 
2013 struct evbuffer_ptr
2014 evbuffer_search(struct evbuffer *buffer, const char *what, size_t len, const struct evbuffer_ptr *start)
2015 {
2016 	return evbuffer_search_range(buffer, what, len, start, NULL);
2017 }
2018 
2019 struct evbuffer_ptr
2020 evbuffer_search_range(struct evbuffer *buffer, const char *what, size_t len, const struct evbuffer_ptr *start, const struct evbuffer_ptr *end)
2021 {
2022 	struct evbuffer_ptr pos;
2023 	struct evbuffer_chain *chain, *last_chain = NULL;
2024 	const unsigned char *p;
2025 	char first;
2026 
2027 	EVBUFFER_LOCK(buffer);
2028 
2029 	if (start) {
2030 		memcpy(&pos, start, sizeof(pos));
2031 		chain = pos._internal.chain;
2032 	} else {
2033 		pos.pos = 0;
2034 		chain = pos._internal.chain = buffer->first;
2035 		pos._internal.pos_in_chain = 0;
2036 	}
2037 
2038 	if (end)
2039 		last_chain = end->_internal.chain;
2040 
2041 	if (!len)
2042 		goto done;
2043 
2044 	first = what[0];
2045 
2046 	while (chain) {
2047 		const unsigned char *start_at =
2048 		    chain->buffer + chain->misalign +
2049 		    pos._internal.pos_in_chain;
2050 		p = memchr(start_at, first,
2051 		    chain->off - pos._internal.pos_in_chain);
2052 		if (p) {
2053 			pos.pos += p - start_at;
2054 			pos._internal.pos_in_chain += p - start_at;
2055 			if (!evbuffer_ptr_memcmp(buffer, &pos, what, len)) {
2056 				if (end && pos.pos + len > end->pos)
2057 					goto not_found;
2058 				else
2059 					goto done;
2060 			}
2061 			++pos.pos;
2062 			++pos._internal.pos_in_chain;
2063 			if (pos._internal.pos_in_chain == chain->off) {
2064 				chain = pos._internal.chain = chain->next;
2065 				pos._internal.pos_in_chain = 0;
2066 			}
2067 		} else {
2068 			if (chain == last_chain)
2069 				goto not_found;
2070 			pos.pos += chain->off - pos._internal.pos_in_chain;
2071 			chain = pos._internal.chain = chain->next;
2072 			pos._internal.pos_in_chain = 0;
2073 		}
2074 	}
2075 
2076 not_found:
2077 	pos.pos = -1;
2078 	pos._internal.chain = NULL;
2079 done:
2080 	EVBUFFER_UNLOCK(buffer);
2081 	return pos;
2082 }
2083 
2084 int
2085 evbuffer_peek(struct evbuffer *buffer, ev_ssize_t len,
2086     struct evbuffer_ptr *start_at,
2087     struct evbuffer_iovec *vec, int n_vec)
2088 {
2089 	struct evbuffer_chain *chain;
2090 	int idx = 0;
2091 	ev_ssize_t len_so_far = 0;
2092 
2093 	EVBUFFER_LOCK(buffer);
2094 
2095 	if (start_at) {
2096 		chain = start_at->_internal.chain;
2097 		len_so_far = chain->off
2098 		    - start_at->_internal.pos_in_chain;
2099 		idx = 1;
2100 		if (n_vec > 0) {
2101 			vec[0].iov_base = chain->buffer + chain->misalign
2102 			    + start_at->_internal.pos_in_chain;
2103 			vec[0].iov_len = len_so_far;
2104 		}
2105 		chain = chain->next;
2106 	} else {
2107 		chain = buffer->first;
2108 	}
2109 
2110 	while (chain) {
2111 		if (len >= 0 && len_so_far >= len)
2112 			break;
2113 		if (idx<n_vec) {
2114 			vec[idx].iov_base = chain->buffer + chain->misalign;
2115 			vec[idx].iov_len = chain->off;
2116 		} else if (len<0)
2117 			break;
2118 		++idx;
2119 		len_so_far += chain->off;
2120 		chain = chain->next;
2121 	}
2122 
2123 	EVBUFFER_UNLOCK(buffer);
2124 
2125 	return idx;
2126 }
2127 
2128 
2129 int
2130 evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap)
2131 {
2132 	char *buffer;
2133 	size_t space;
2134 	int sz, result = -1;
2135 	va_list aq;
2136 
2137 	EVBUFFER_LOCK(buf);
2138 
2139 	if (buf->freeze_end) {
2140 		goto done;
2141 	}
2142 
2143 	/* make sure that at least some space is available */
2144 	if (evbuffer_expand(buf, 64) == -1)
2145 		goto done;
2146 
2147 	for (;;) {
2148 		struct evbuffer_chain *chain = buf->last;
2149 		size_t used = chain->misalign + chain->off;
2150 		buffer = (char *)chain->buffer + chain->misalign + chain->off;
2151 		EVUTIL_ASSERT(chain->buffer_len >= used);
2152 		space = chain->buffer_len - used;
2153 
2154 #ifndef va_copy
2155 #define	va_copy(dst, src)	memcpy(&(dst), &(src), sizeof(va_list))
2156 #endif
2157 		va_copy(aq, ap);
2158 
2159 		sz = evutil_vsnprintf(buffer, space, fmt, aq);
2160 
2161 		va_end(aq);
2162 
2163 		if (sz < 0)
2164 			goto done;
2165 		if ((size_t)sz < space) {
2166 			chain->off += sz;
2167 			buf->total_len += sz;
2168 			buf->n_add_for_cb += sz;
2169 
2170 			evbuffer_invoke_callbacks(buf);
2171 			result = sz;
2172 			goto done;
2173 		}
2174 		if (evbuffer_expand(buf, sz + 1) == -1)
2175 			goto done;
2176 	}
2177 	/* NOTREACHED */
2178 
2179 done:
2180 	EVBUFFER_UNLOCK(buf);
2181 	return result;
2182 }
2183 
2184 int
2185 evbuffer_add_printf(struct evbuffer *buf, const char *fmt, ...)
2186 {
2187 	int res = -1;
2188 	va_list ap;
2189 
2190 	va_start(ap, fmt);
2191 	res = evbuffer_add_vprintf(buf, fmt, ap);
2192 	va_end(ap);
2193 
2194 	return (res);
2195 }
2196 
2197 int
2198 evbuffer_add_reference(struct evbuffer *outbuf,
2199     const void *data, size_t datlen,
2200     evbuffer_ref_cleanup_cb cleanupfn, void *extra)
2201 {
2202 	struct evbuffer_chain *chain;
2203 	struct evbuffer_chain_reference *info;
2204 	int result = -1;
2205 
2206 	chain = evbuffer_chain_new(sizeof(struct evbuffer_chain_reference));
2207 	if (!chain)
2208 		return (-1);
2209 	chain->flags |= EVBUFFER_REFERENCE | EVBUFFER_IMMUTABLE;
2210 	chain->buffer = (u_char *)data;
2211 	chain->buffer_len = datlen;
2212 	chain->off = datlen;
2213 
2214 	info = EVBUFFER_CHAIN_EXTRA(struct evbuffer_chain_reference, chain);
2215 	info->cleanupfn = cleanupfn;
2216 	info->extra = extra;
2217 
2218 	EVBUFFER_LOCK(outbuf);
2219 	if (outbuf->freeze_end) {
2220 		/* don't call chain_free; we do not want to actually invoke
2221 		 * the cleanup function */
2222 		mm_free(chain);
2223 		goto done;
2224 	}
2225 	evbuffer_chain_insert(outbuf, chain);
2226 	outbuf->n_add_for_cb += datlen;
2227 
2228 	evbuffer_invoke_callbacks(outbuf);
2229 
2230 	result = 0;
2231 done:
2232 	EVBUFFER_UNLOCK(outbuf);
2233 
2234 	return result;
2235 }
2236 
2237 /* TODO(niels): maybe we don't want to own the fd, however, in that
2238  * case, we should dup it - dup is cheap.  Perhaps, we should use a
2239  * callback instead?
2240  */
2241 /* TODO(niels): we may want to add to automagically convert to mmap, in
2242  * case evbuffer_remove() or evbuffer_pullup() are being used.
2243  */
2244 int
2245 evbuffer_add_file(struct evbuffer *outbuf, int fd,
2246     off_t offset, off_t length)
2247 {
2248 #if defined(USE_SENDFILE) || defined(_EVENT_HAVE_MMAP)
2249 	struct evbuffer_chain *chain;
2250 	struct evbuffer_chain_fd *info;
2251 #endif
2252 	int ok = 1;
2253 
2254 #if defined(USE_SENDFILE)
2255 	if (use_sendfile) {
2256 		chain = evbuffer_chain_new(sizeof(struct evbuffer_chain_fd));
2257 		if (chain == NULL) {
2258 			event_warn("%s: out of memory", __func__);
2259 			return (-1);
2260 		}
2261 
2262 		chain->flags |= EVBUFFER_SENDFILE | EVBUFFER_IMMUTABLE;
2263 		chain->buffer = NULL;	/* no reading possible */
2264 		chain->buffer_len = length + offset;
2265 		chain->off = length;
2266 		chain->misalign = offset;
2267 
2268 		info = EVBUFFER_CHAIN_EXTRA(struct evbuffer_chain_fd, chain);
2269 		info->fd = fd;
2270 
2271 		EVBUFFER_LOCK(outbuf);
2272 		if (outbuf->freeze_end) {
2273 			mm_free(chain);
2274 			ok = 0;
2275 		} else {
2276 			outbuf->n_add_for_cb += length;
2277 			evbuffer_chain_insert(outbuf, chain);
2278 		}
2279 	} else
2280 #endif
2281 #if defined(_EVENT_HAVE_MMAP)
2282 	if (use_mmap) {
2283 		void *mapped = mmap(NULL, length + offset, PROT_READ,
2284 #ifdef MAP_NOCACHE
2285 		    MAP_NOCACHE |
2286 #endif
2287 #ifdef MAP_FILE
2288 		    MAP_FILE |
2289 #endif
2290 		    MAP_PRIVATE,
2291 		    fd, 0);
2292 		/* some mmap implementations require offset to be a multiple of
2293 		 * the page size.  most users of this api, are likely to use 0
2294 		 * so mapping everything is not likely to be a problem.
2295 		 * TODO(niels): determine page size and round offset to that
2296 		 * page size to avoid mapping too much memory.
2297 		 */
2298 		if (mapped == MAP_FAILED) {
2299 			event_warn("%s: mmap(%d, %d, %zu) failed",
2300 			    __func__, fd, 0, (size_t)(offset + length));
2301 			return (-1);
2302 		}
2303 		chain = evbuffer_chain_new(sizeof(struct evbuffer_chain_fd));
2304 		if (chain == NULL) {
2305 			event_warn("%s: out of memory", __func__);
2306 			munmap(mapped, length);
2307 			return (-1);
2308 		}
2309 
2310 		chain->flags |= EVBUFFER_MMAP | EVBUFFER_IMMUTABLE;
2311 		chain->buffer = mapped;
2312 		chain->buffer_len = length + offset;
2313 		chain->off = length + offset;
2314 
2315 		info = EVBUFFER_CHAIN_EXTRA(struct evbuffer_chain_fd, chain);
2316 		info->fd = fd;
2317 
2318 		EVBUFFER_LOCK(outbuf);
2319 		if (outbuf->freeze_end) {
2320 			info->fd = -1;
2321 			evbuffer_chain_free(chain);
2322 			ok = 0;
2323 		} else {
2324 			outbuf->n_add_for_cb += length;
2325 
2326 			evbuffer_chain_insert(outbuf, chain);
2327 
2328 			/* we need to subtract whatever we don't need */
2329 			evbuffer_drain(outbuf, offset);
2330 		}
2331 	} else
2332 #endif
2333 	{
2334 		/* the default implementation */
2335 		struct evbuffer *tmp = evbuffer_new();
2336 		ev_ssize_t read;
2337 
2338 		if (tmp == NULL)
2339 			return (-1);
2340 
2341 #ifdef WIN32
2342 #define lseek _lseek
2343 #endif
2344 		if (lseek(fd, offset, SEEK_SET) == -1) {
2345 			evbuffer_free(tmp);
2346 			return (-1);
2347 		}
2348 
2349 		/* we add everything to a temporary buffer, so that we
2350 		 * can abort without side effects if the read fails.
2351 		 */
2352 		while (length) {
2353 			read = evbuffer_read(tmp, fd, length);
2354 			if (read == -1) {
2355 				evbuffer_free(tmp);
2356 				return (-1);
2357 			}
2358 
2359 			length -= read;
2360 		}
2361 
2362 		EVBUFFER_LOCK(outbuf);
2363 		if (outbuf->freeze_end) {
2364 			evbuffer_free(tmp);
2365 			ok = 0;
2366 		} else {
2367 			evbuffer_add_buffer(outbuf, tmp);
2368 			evbuffer_free(tmp);
2369 
2370 #ifdef WIN32
2371 #define close _close
2372 #endif
2373 			close(fd);
2374 		}
2375 	}
2376 
2377 	if (ok)
2378 		evbuffer_invoke_callbacks(outbuf);
2379 	EVBUFFER_UNLOCK(outbuf);
2380 
2381 	return ok ? 0 : -1;
2382 }
2383 
2384 
2385 void
2386 evbuffer_setcb(struct evbuffer *buffer, evbuffer_cb cb, void *cbarg)
2387 {
2388 	EVBUFFER_LOCK(buffer);
2389 
2390 	if (!TAILQ_EMPTY(&buffer->callbacks))
2391 		evbuffer_remove_all_callbacks(buffer);
2392 
2393 	if (cb) {
2394 		struct evbuffer_cb_entry *ent =
2395 		    evbuffer_add_cb(buffer, NULL, cbarg);
2396 		ent->cb.cb_obsolete = cb;
2397 		ent->flags |= EVBUFFER_CB_OBSOLETE;
2398 	}
2399 	EVBUFFER_UNLOCK(buffer);
2400 }
2401 
2402 struct evbuffer_cb_entry *
2403 evbuffer_add_cb(struct evbuffer *buffer, evbuffer_cb_func cb, void *cbarg)
2404 {
2405 	struct evbuffer_cb_entry *e;
2406 	if (! (e = mm_calloc(1, sizeof(struct evbuffer_cb_entry))))
2407 		return NULL;
2408 	EVBUFFER_LOCK(buffer);
2409 	e->cb.cb_func = cb;
2410 	e->cbarg = cbarg;
2411 	e->flags = EVBUFFER_CB_ENABLED;
2412 	TAILQ_INSERT_HEAD(&buffer->callbacks, e, next);
2413 	EVBUFFER_UNLOCK(buffer);
2414 	return e;
2415 }
2416 
2417 int
2418 evbuffer_remove_cb_entry(struct evbuffer *buffer,
2419 			 struct evbuffer_cb_entry *ent)
2420 {
2421 	EVBUFFER_LOCK(buffer);
2422 	TAILQ_REMOVE(&buffer->callbacks, ent, next);
2423 	EVBUFFER_UNLOCK(buffer);
2424 	mm_free(ent);
2425 	return 0;
2426 }
2427 
2428 int
2429 evbuffer_remove_cb(struct evbuffer *buffer, evbuffer_cb_func cb, void *cbarg)
2430 {
2431 	struct evbuffer_cb_entry *cbent;
2432 	int result = -1;
2433 	EVBUFFER_LOCK(buffer);
2434 	TAILQ_FOREACH(cbent, &buffer->callbacks, next) {
2435 		if (cb == cbent->cb.cb_func && cbarg == cbent->cbarg) {
2436 			result = evbuffer_remove_cb_entry(buffer, cbent);
2437 			goto done;
2438 		}
2439 	}
2440 done:
2441 	EVBUFFER_UNLOCK(buffer);
2442 	return result;
2443 }
2444 
2445 int
2446 evbuffer_cb_set_flags(struct evbuffer *buffer,
2447 		      struct evbuffer_cb_entry *cb, ev_uint32_t flags)
2448 {
2449 	/* the user isn't allowed to mess with these. */
2450 	flags &= ~EVBUFFER_CB_INTERNAL_FLAGS;
2451 	EVBUFFER_LOCK(buffer);
2452 	cb->flags |= flags;
2453 	EVBUFFER_UNLOCK(buffer);
2454 	return 0;
2455 }
2456 
2457 int
2458 evbuffer_cb_clear_flags(struct evbuffer *buffer,
2459 		      struct evbuffer_cb_entry *cb, ev_uint32_t flags)
2460 {
2461 	/* the user isn't allowed to mess with these. */
2462 	flags &= ~EVBUFFER_CB_INTERNAL_FLAGS;
2463 	EVBUFFER_LOCK(buffer);
2464 	cb->flags &= ~flags;
2465 	EVBUFFER_UNLOCK(buffer);
2466 	return 0;
2467 }
2468 
2469 int
2470 evbuffer_freeze(struct evbuffer *buffer, int start)
2471 {
2472 	EVBUFFER_LOCK(buffer);
2473 	if (start)
2474 		buffer->freeze_start = 1;
2475 	else
2476 		buffer->freeze_end = 1;
2477 	EVBUFFER_UNLOCK(buffer);
2478 	return 0;
2479 }
2480 
2481 int
2482 evbuffer_unfreeze(struct evbuffer *buffer, int start)
2483 {
2484 	EVBUFFER_LOCK(buffer);
2485 	if (start)
2486 		buffer->freeze_start = 0;
2487 	else
2488 		buffer->freeze_end = 0;
2489 	EVBUFFER_UNLOCK(buffer);
2490 	return 0;
2491 }
2492 
2493 #if 0
2494 void
2495 evbuffer_cb_suspend(struct evbuffer *buffer, struct evbuffer_cb_entry *cb)
2496 {
2497 	if (!(cb->flags & EVBUFFER_CB_SUSPENDED)) {
2498 		cb->size_before_suspend = evbuffer_get_length(buffer);
2499 		cb->flags |= EVBUFFER_CB_SUSPENDED;
2500 	}
2501 }
2502 
2503 void
2504 evbuffer_cb_unsuspend(struct evbuffer *buffer, struct evbuffer_cb_entry *cb)
2505 {
2506 	if ((cb->flags & EVBUFFER_CB_SUSPENDED)) {
2507 		unsigned call = (cb->flags & EVBUFFER_CB_CALL_ON_UNSUSPEND);
2508 		size_t sz = cb->size_before_suspend;
2509 		cb->flags &= ~(EVBUFFER_CB_SUSPENDED|
2510 			       EVBUFFER_CB_CALL_ON_UNSUSPEND);
2511 		cb->size_before_suspend = 0;
2512 		if (call && (cb->flags & EVBUFFER_CB_ENABLED)) {
2513 			cb->cb(buffer, sz, evbuffer_get_length(buffer), cb->cbarg);
2514 		}
2515 	}
2516 }
2517 #endif
2518