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