1 /* $NetBSD: buffer.c,v 1.3 2015/01/29 07:26:02 spz Exp $ */ 2 /* 3 * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu> 4 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "event2/event-config.h" 30 #include <sys/cdefs.h> 31 __RCSID("$NetBSD: buffer.c,v 1.3 2015/01/29 07:26:02 spz Exp $"); 32 33 #ifdef WIN32 34 #include <winsock2.h> 35 #include <windows.h> 36 #include <io.h> 37 #endif 38 39 #ifdef _EVENT_HAVE_VASPRINTF 40 /* If we have vasprintf, we need to define this before we include stdio.h. */ 41 #define _GNU_SOURCE 42 #endif 43 44 #include <sys/types.h> 45 46 #ifdef _EVENT_HAVE_SYS_TIME_H 47 #include <sys/time.h> 48 #endif 49 50 #ifdef _EVENT_HAVE_SYS_SOCKET_H 51 #include <sys/socket.h> 52 #endif 53 54 #ifdef _EVENT_HAVE_SYS_UIO_H 55 #include <sys/uio.h> 56 #endif 57 58 #ifdef _EVENT_HAVE_SYS_IOCTL_H 59 #include <sys/ioctl.h> 60 #endif 61 62 #ifdef _EVENT_HAVE_SYS_MMAN_H 63 #include <sys/mman.h> 64 #endif 65 66 #ifdef _EVENT_HAVE_SYS_SENDFILE_H 67 #include <sys/sendfile.h> 68 #endif 69 70 #include <errno.h> 71 #include <stdio.h> 72 #include <stdlib.h> 73 #include <string.h> 74 #ifdef _EVENT_HAVE_STDARG_H 75 #include <stdarg.h> 76 #endif 77 #ifdef _EVENT_HAVE_UNISTD_H 78 #include <unistd.h> 79 #endif 80 #include <limits.h> 81 82 #include "event2/event.h" 83 #include "event2/buffer.h" 84 #include "event2/buffer_compat.h" 85 #include "event2/bufferevent.h" 86 #include "event2/bufferevent_compat.h" 87 #include "event2/bufferevent_struct.h" 88 #include "event2/thread.h" 89 #include "event2/event-config.h" 90 #include <sys/cdefs.h> 91 __RCSID("$NetBSD: buffer.c,v 1.3 2015/01/29 07:26:02 spz Exp $"); 92 #include "log-internal.h" 93 #include "mm-internal.h" 94 #include "util-internal.h" 95 #include "evthread-internal.h" 96 #include "evbuffer-internal.h" 97 #include "bufferevent-internal.h" 98 99 /* some systems do not have MAP_FAILED */ 100 #ifndef MAP_FAILED 101 #define MAP_FAILED ((void *)-1) 102 #endif 103 104 /* send file support */ 105 #if defined(_EVENT_HAVE_SYS_SENDFILE_H) && defined(_EVENT_HAVE_SENDFILE) && defined(__linux__) 106 #define USE_SENDFILE 1 107 #define SENDFILE_IS_LINUX 1 108 #elif defined(_EVENT_HAVE_SENDFILE) && defined(__FreeBSD__) 109 #define USE_SENDFILE 1 110 #define SENDFILE_IS_FREEBSD 1 111 #elif defined(_EVENT_HAVE_SENDFILE) && defined(__APPLE__) 112 #define USE_SENDFILE 1 113 #define SENDFILE_IS_MACOSX 1 114 #elif defined(_EVENT_HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__) 115 #define USE_SENDFILE 1 116 #define SENDFILE_IS_SOLARIS 1 117 #endif 118 119 #ifdef USE_SENDFILE 120 static int use_sendfile = 1; 121 #endif 122 #ifdef _EVENT_HAVE_MMAP 123 static int use_mmap = 1; 124 #endif 125 126 127 /* Mask of user-selectable callback flags. */ 128 #define EVBUFFER_CB_USER_FLAGS 0xffff 129 /* Mask of all internal-use-only flags. */ 130 #define EVBUFFER_CB_INTERNAL_FLAGS 0xffff0000 131 132 /* Flag set if the callback is using the cb_obsolete function pointer */ 133 #define EVBUFFER_CB_OBSOLETE 0x00040000 134 135 /* evbuffer_chain support */ 136 #define CHAIN_SPACE_PTR(ch) ((ch)->buffer + (ch)->misalign + (ch)->off) 137 #define CHAIN_SPACE_LEN(ch) ((ch)->flags & EVBUFFER_IMMUTABLE ? \ 138 0 : (ch)->buffer_len - ((ch)->misalign + (ch)->off)) 139 140 #define CHAIN_PINNED(ch) (((ch)->flags & EVBUFFER_MEM_PINNED_ANY) != 0) 141 #define CHAIN_PINNED_R(ch) (((ch)->flags & EVBUFFER_MEM_PINNED_R) != 0) 142 143 static void evbuffer_chain_align(struct evbuffer_chain *chain); 144 static int evbuffer_chain_should_realign(struct evbuffer_chain *chain, 145 size_t datalen); 146 static void evbuffer_deferred_callback(struct deferred_cb *cb, void *arg); 147 static int evbuffer_ptr_memcmp(const struct evbuffer *buf, 148 const struct evbuffer_ptr *pos, const char *mem, size_t len); 149 static struct evbuffer_chain *evbuffer_expand_singlechain(struct evbuffer *buf, 150 size_t datlen); 151 152 #ifdef WIN32 153 static int evbuffer_readfile(struct evbuffer *buf, evutil_socket_t fd, 154 ev_ssize_t howmuch); 155 #else 156 #define evbuffer_readfile evbuffer_read 157 #endif 158 159 static struct evbuffer_chain * 160 evbuffer_chain_new(size_t size) 161 { 162 struct evbuffer_chain *chain; 163 size_t to_alloc; 164 165 if (size > EVBUFFER_CHAIN_MAX - EVBUFFER_CHAIN_SIZE) 166 return (NULL); 167 168 size += EVBUFFER_CHAIN_SIZE; 169 170 /* get the next largest memory that can hold the buffer */ 171 if (size < EVBUFFER_CHAIN_MAX / 2) { 172 to_alloc = MIN_BUFFER_SIZE; 173 while (to_alloc < size) { 174 to_alloc <<= 1; 175 } 176 } else { 177 to_alloc = size; 178 } 179 180 /* we get everything in one chunk */ 181 if ((chain = mm_malloc(to_alloc)) == NULL) 182 return (NULL); 183 184 memset(chain, 0, EVBUFFER_CHAIN_SIZE); 185 186 chain->buffer_len = to_alloc - EVBUFFER_CHAIN_SIZE; 187 188 /* this way we can manipulate the buffer to different addresses, 189 * which is required for mmap for example. 190 */ 191 chain->buffer = EVBUFFER_CHAIN_EXTRA(u_char, chain); 192 193 return (chain); 194 } 195 196 static inline void 197 evbuffer_chain_free(struct evbuffer_chain *chain) 198 { 199 if (CHAIN_PINNED(chain)) { 200 chain->flags |= EVBUFFER_DANGLING; 201 return; 202 } 203 if (chain->flags & (EVBUFFER_MMAP|EVBUFFER_SENDFILE| 204 EVBUFFER_REFERENCE)) { 205 if (chain->flags & EVBUFFER_REFERENCE) { 206 struct evbuffer_chain_reference *info = 207 EVBUFFER_CHAIN_EXTRA( 208 struct evbuffer_chain_reference, 209 chain); 210 if (info->cleanupfn) 211 (*info->cleanupfn)(chain->buffer, 212 chain->buffer_len, 213 info->extra); 214 } 215 #ifdef _EVENT_HAVE_MMAP 216 if (chain->flags & EVBUFFER_MMAP) { 217 struct evbuffer_chain_fd *info = 218 EVBUFFER_CHAIN_EXTRA(struct evbuffer_chain_fd, 219 chain); 220 if (munmap(chain->buffer, chain->buffer_len) == -1) 221 event_warn("%s: munmap failed", __func__); 222 if (close(info->fd) == -1) 223 event_warn("%s: close(%d) failed", 224 __func__, info->fd); 225 } 226 #endif 227 #ifdef USE_SENDFILE 228 if (chain->flags & EVBUFFER_SENDFILE) { 229 struct evbuffer_chain_fd *info = 230 EVBUFFER_CHAIN_EXTRA(struct evbuffer_chain_fd, 231 chain); 232 if (close(info->fd) == -1) 233 event_warn("%s: close(%d) failed", 234 __func__, info->fd); 235 } 236 #endif 237 } 238 239 mm_free(chain); 240 } 241 242 static void 243 evbuffer_free_all_chains(struct evbuffer_chain *chain) 244 { 245 struct evbuffer_chain *next; 246 for (; chain; chain = next) { 247 next = chain->next; 248 evbuffer_chain_free(chain); 249 } 250 } 251 252 #ifndef NDEBUG 253 static int 254 evbuffer_chains_all_empty(struct evbuffer_chain *chain) 255 { 256 for (; chain; chain = chain->next) { 257 if (chain->off) 258 return 0; 259 } 260 return 1; 261 } 262 #else 263 /* The definition is needed for EVUTIL_ASSERT, which uses sizeof to avoid 264 "unused variable" warnings. */ 265 static inline int evbuffer_chains_all_empty(struct evbuffer_chain *chain) { 266 return 1; 267 } 268 #endif 269 270 /* Free all trailing chains in 'buf' that are neither pinned nor empty, prior 271 * to replacing them all with a new chain. Return a pointer to the place 272 * where the new chain will go. 273 * 274 * Internal; requires lock. The caller must fix up buf->last and buf->first 275 * as needed; they might have been freed. 276 */ 277 static struct evbuffer_chain ** 278 evbuffer_free_trailing_empty_chains(struct evbuffer *buf) 279 { 280 struct evbuffer_chain **ch = buf->last_with_datap; 281 /* Find the first victim chain. It might be *last_with_datap */ 282 while ((*ch) && ((*ch)->off != 0 || CHAIN_PINNED(*ch))) 283 ch = &(*ch)->next; 284 if (*ch) { 285 EVUTIL_ASSERT(evbuffer_chains_all_empty(*ch)); 286 evbuffer_free_all_chains(*ch); 287 *ch = NULL; 288 } 289 return ch; 290 } 291 292 /* Add a single chain 'chain' to the end of 'buf', freeing trailing empty 293 * chains as necessary. Requires lock. Does not schedule callbacks. 294 */ 295 static void 296 evbuffer_chain_insert(struct evbuffer *buf, 297 struct evbuffer_chain *chain) 298 { 299 ASSERT_EVBUFFER_LOCKED(buf); 300 if (*buf->last_with_datap == NULL) { 301 /* There are no chains data on the buffer at all. */ 302 EVUTIL_ASSERT(buf->last_with_datap == &buf->first); 303 EVUTIL_ASSERT(buf->first == NULL); 304 buf->first = buf->last = chain; 305 } else { 306 struct evbuffer_chain **ch = buf->last_with_datap; 307 /* Find the first victim chain. It might be *last_with_datap */ 308 while ((*ch) && ((*ch)->off != 0 || CHAIN_PINNED(*ch))) 309 ch = &(*ch)->next; 310 if (*ch == NULL) { 311 /* There is no victim; just append this new chain. */ 312 buf->last->next = chain; 313 if (chain->off) 314 buf->last_with_datap = &buf->last->next; 315 } else { 316 /* Replace all victim chains with this chain. */ 317 EVUTIL_ASSERT(evbuffer_chains_all_empty(*ch)); 318 evbuffer_free_all_chains(*ch); 319 *ch = chain; 320 } 321 buf->last = chain; 322 } 323 buf->total_len += chain->off; 324 } 325 326 static inline struct evbuffer_chain * 327 evbuffer_chain_insert_new(struct evbuffer *buf, size_t datlen) 328 { 329 struct evbuffer_chain *chain; 330 if ((chain = evbuffer_chain_new(datlen)) == NULL) 331 return NULL; 332 evbuffer_chain_insert(buf, chain); 333 return chain; 334 } 335 336 void 337 _evbuffer_chain_pin(struct evbuffer_chain *chain, unsigned flag) 338 { 339 EVUTIL_ASSERT((chain->flags & flag) == 0); 340 chain->flags |= flag; 341 } 342 343 void 344 _evbuffer_chain_unpin(struct evbuffer_chain *chain, unsigned flag) 345 { 346 EVUTIL_ASSERT((chain->flags & flag) != 0); 347 chain->flags &= ~flag; 348 if (chain->flags & EVBUFFER_DANGLING) 349 evbuffer_chain_free(chain); 350 } 351 352 struct evbuffer * 353 evbuffer_new(void) 354 { 355 struct evbuffer *buffer; 356 357 buffer = mm_calloc(1, sizeof(struct evbuffer)); 358 if (buffer == NULL) 359 return (NULL); 360 361 TAILQ_INIT(&buffer->callbacks); 362 buffer->refcnt = 1; 363 buffer->last_with_datap = &buffer->first; 364 365 return (buffer); 366 } 367 368 int 369 evbuffer_set_flags(struct evbuffer *buf, ev_uint64_t flags) 370 { 371 EVBUFFER_LOCK(buf); 372 buf->flags |= (ev_uint32_t)flags; 373 EVBUFFER_UNLOCK(buf); 374 return 0; 375 } 376 377 int 378 evbuffer_clear_flags(struct evbuffer *buf, ev_uint64_t flags) 379 { 380 EVBUFFER_LOCK(buf); 381 buf->flags &= ~(ev_uint32_t)flags; 382 EVBUFFER_UNLOCK(buf); 383 return 0; 384 } 385 386 void 387 _evbuffer_incref(struct evbuffer *buf) 388 { 389 EVBUFFER_LOCK(buf); 390 ++buf->refcnt; 391 EVBUFFER_UNLOCK(buf); 392 } 393 394 void 395 _evbuffer_incref_and_lock(struct evbuffer *buf) 396 { 397 EVBUFFER_LOCK(buf); 398 ++buf->refcnt; 399 } 400 401 int 402 evbuffer_defer_callbacks(struct evbuffer *buffer, struct event_base *base) 403 { 404 EVBUFFER_LOCK(buffer); 405 buffer->cb_queue = event_base_get_deferred_cb_queue(base); 406 buffer->deferred_cbs = 1; 407 event_deferred_cb_init(&buffer->deferred, 408 evbuffer_deferred_callback, buffer); 409 EVBUFFER_UNLOCK(buffer); 410 return 0; 411 } 412 413 int 414 evbuffer_enable_locking(struct evbuffer *buf, void *lock) 415 { 416 #ifdef _EVENT_DISABLE_THREAD_SUPPORT 417 return -1; 418 #else 419 if (buf->lock) 420 return -1; 421 422 if (!lock) { 423 EVTHREAD_ALLOC_LOCK(lock, EVTHREAD_LOCKTYPE_RECURSIVE); 424 if (!lock) 425 return -1; 426 buf->lock = lock; 427 buf->own_lock = 1; 428 } else { 429 buf->lock = lock; 430 buf->own_lock = 0; 431 } 432 433 return 0; 434 #endif 435 } 436 437 void 438 evbuffer_set_parent(struct evbuffer *buf, struct bufferevent *bev) 439 { 440 EVBUFFER_LOCK(buf); 441 buf->parent = bev; 442 EVBUFFER_UNLOCK(buf); 443 } 444 445 static void 446 evbuffer_run_callbacks(struct evbuffer *buffer, int running_deferred) 447 { 448 struct evbuffer_cb_entry *cbent, *next; 449 struct evbuffer_cb_info info; 450 size_t new_size; 451 ev_uint32_t mask, masked_val; 452 int clear = 1; 453 454 if (running_deferred) { 455 mask = EVBUFFER_CB_NODEFER|EVBUFFER_CB_ENABLED; 456 masked_val = EVBUFFER_CB_ENABLED; 457 } else if (buffer->deferred_cbs) { 458 mask = EVBUFFER_CB_NODEFER|EVBUFFER_CB_ENABLED; 459 masked_val = EVBUFFER_CB_NODEFER|EVBUFFER_CB_ENABLED; 460 /* Don't zero-out n_add/n_del, since the deferred callbacks 461 will want to see them. */ 462 clear = 0; 463 } else { 464 mask = EVBUFFER_CB_ENABLED; 465 masked_val = EVBUFFER_CB_ENABLED; 466 } 467 468 ASSERT_EVBUFFER_LOCKED(buffer); 469 470 if (TAILQ_EMPTY(&buffer->callbacks)) { 471 buffer->n_add_for_cb = buffer->n_del_for_cb = 0; 472 return; 473 } 474 if (buffer->n_add_for_cb == 0 && buffer->n_del_for_cb == 0) 475 return; 476 477 new_size = buffer->total_len; 478 info.orig_size = new_size + buffer->n_del_for_cb - buffer->n_add_for_cb; 479 info.n_added = buffer->n_add_for_cb; 480 info.n_deleted = buffer->n_del_for_cb; 481 if (clear) { 482 buffer->n_add_for_cb = 0; 483 buffer->n_del_for_cb = 0; 484 } 485 for (cbent = TAILQ_FIRST(&buffer->callbacks); 486 cbent != TAILQ_END(&buffer->callbacks); 487 cbent = next) { 488 /* Get the 'next' pointer now in case this callback decides 489 * to remove itself or something. */ 490 next = TAILQ_NEXT(cbent, next); 491 492 if ((cbent->flags & mask) != masked_val) 493 continue; 494 495 if ((cbent->flags & EVBUFFER_CB_OBSOLETE)) 496 cbent->cb.cb_obsolete(buffer, 497 info.orig_size, new_size, cbent->cbarg); 498 else 499 cbent->cb.cb_func(buffer, &info, cbent->cbarg); 500 } 501 } 502 503 void 504 evbuffer_invoke_callbacks(struct evbuffer *buffer) 505 { 506 if (TAILQ_EMPTY(&buffer->callbacks)) { 507 buffer->n_add_for_cb = buffer->n_del_for_cb = 0; 508 return; 509 } 510 511 if (buffer->deferred_cbs) { 512 if (buffer->deferred.queued) 513 return; 514 _evbuffer_incref_and_lock(buffer); 515 if (buffer->parent) 516 bufferevent_incref(buffer->parent); 517 EVBUFFER_UNLOCK(buffer); 518 event_deferred_cb_schedule(buffer->cb_queue, &buffer->deferred); 519 } 520 521 evbuffer_run_callbacks(buffer, 0); 522 } 523 524 static void 525 evbuffer_deferred_callback(struct deferred_cb *cb, void *arg) 526 { 527 struct bufferevent *parent = NULL; 528 struct evbuffer *buffer = arg; 529 530 /* XXXX It would be better to run these callbacks without holding the 531 * lock */ 532 EVBUFFER_LOCK(buffer); 533 parent = buffer->parent; 534 evbuffer_run_callbacks(buffer, 1); 535 _evbuffer_decref_and_unlock(buffer); 536 if (parent) 537 bufferevent_decref(parent); 538 } 539 540 static void 541 evbuffer_remove_all_callbacks(struct evbuffer *buffer) 542 { 543 struct evbuffer_cb_entry *cbent; 544 545 while ((cbent = TAILQ_FIRST(&buffer->callbacks))) { 546 TAILQ_REMOVE(&buffer->callbacks, cbent, next); 547 mm_free(cbent); 548 } 549 } 550 551 void 552 _evbuffer_decref_and_unlock(struct evbuffer *buffer) 553 { 554 struct evbuffer_chain *chain, *next; 555 ASSERT_EVBUFFER_LOCKED(buffer); 556 557 EVUTIL_ASSERT(buffer->refcnt > 0); 558 559 if (--buffer->refcnt > 0) { 560 EVBUFFER_UNLOCK(buffer); 561 return; 562 } 563 564 for (chain = buffer->first; chain != NULL; chain = next) { 565 next = chain->next; 566 evbuffer_chain_free(chain); 567 } 568 evbuffer_remove_all_callbacks(buffer); 569 if (buffer->deferred_cbs) 570 event_deferred_cb_cancel(buffer->cb_queue, &buffer->deferred); 571 572 EVBUFFER_UNLOCK(buffer); 573 if (buffer->own_lock) 574 EVTHREAD_FREE_LOCK(buffer->lock, EVTHREAD_LOCKTYPE_RECURSIVE); 575 mm_free(buffer); 576 } 577 578 void 579 evbuffer_free(struct evbuffer *buffer) 580 { 581 EVBUFFER_LOCK(buffer); 582 _evbuffer_decref_and_unlock(buffer); 583 } 584 585 void 586 evbuffer_lock(struct evbuffer *buf) 587 { 588 EVBUFFER_LOCK(buf); 589 } 590 591 void 592 evbuffer_unlock(struct evbuffer *buf) 593 { 594 EVBUFFER_UNLOCK(buf); 595 } 596 597 size_t 598 evbuffer_get_length(const struct evbuffer *buffer) 599 { 600 size_t result; 601 602 EVBUFFER_LOCK(buffer); 603 604 result = (buffer->total_len); 605 606 EVBUFFER_UNLOCK(buffer); 607 608 return result; 609 } 610 611 size_t 612 evbuffer_get_contiguous_space(const struct evbuffer *buf) 613 { 614 struct evbuffer_chain *chain; 615 size_t result; 616 617 EVBUFFER_LOCK(buf); 618 chain = buf->first; 619 result = (chain != NULL ? chain->off : 0); 620 EVBUFFER_UNLOCK(buf); 621 622 return result; 623 } 624 625 int 626 evbuffer_reserve_space(struct evbuffer *buf, ev_ssize_t size, 627 struct evbuffer_iovec *vec, int n_vecs) 628 { 629 struct evbuffer_chain *chain, **chainp; 630 int n = -1; 631 632 EVBUFFER_LOCK(buf); 633 if (buf->freeze_end) 634 goto done; 635 if (n_vecs < 1) 636 goto done; 637 if (n_vecs == 1) { 638 if ((chain = evbuffer_expand_singlechain(buf, size)) == NULL) 639 goto done; 640 641 vec[0].iov_base = CHAIN_SPACE_PTR(chain); 642 vec[0].iov_len = (size_t) CHAIN_SPACE_LEN(chain); 643 EVUTIL_ASSERT(size<0 || (size_t)vec[0].iov_len >= (size_t)size); 644 n = 1; 645 } else { 646 if (_evbuffer_expand_fast(buf, size, n_vecs)<0) 647 goto done; 648 n = _evbuffer_read_setup_vecs(buf, size, vec, n_vecs, 649 &chainp, 0); 650 } 651 652 done: 653 EVBUFFER_UNLOCK(buf); 654 return n; 655 656 } 657 658 static int 659 advance_last_with_data(struct evbuffer *buf) 660 { 661 int n = 0; 662 ASSERT_EVBUFFER_LOCKED(buf); 663 664 if (!*buf->last_with_datap) 665 return 0; 666 667 while ((*buf->last_with_datap)->next && (*buf->last_with_datap)->next->off) { 668 buf->last_with_datap = &(*buf->last_with_datap)->next; 669 ++n; 670 } 671 return n; 672 } 673 674 int 675 evbuffer_commit_space(struct evbuffer *buf, 676 struct evbuffer_iovec *vec, int n_vecs) 677 { 678 struct evbuffer_chain *chain, **firstchainp, **chainp; 679 int result = -1; 680 size_t added = 0; 681 int i; 682 683 EVBUFFER_LOCK(buf); 684 685 if (buf->freeze_end) 686 goto done; 687 if (n_vecs == 0) { 688 result = 0; 689 goto done; 690 } else if (n_vecs == 1 && 691 (buf->last && vec[0].iov_base == (void*)CHAIN_SPACE_PTR(buf->last))) { 692 /* The user only got or used one chain; it might not 693 * be the first one with space in it. */ 694 if ((size_t)vec[0].iov_len > (size_t)CHAIN_SPACE_LEN(buf->last)) 695 goto done; 696 buf->last->off += vec[0].iov_len; 697 added = vec[0].iov_len; 698 if (added) 699 advance_last_with_data(buf); 700 goto okay; 701 } 702 703 /* Advance 'firstchain' to the first chain with space in it. */ 704 firstchainp = buf->last_with_datap; 705 if (!*firstchainp) 706 goto done; 707 if (CHAIN_SPACE_LEN(*firstchainp) == 0) { 708 firstchainp = &(*firstchainp)->next; 709 } 710 711 chain = *firstchainp; 712 /* pass 1: make sure that the pointers and lengths of vecs[] are in 713 * bounds before we try to commit anything. */ 714 for (i=0; i<n_vecs; ++i) { 715 if (!chain) 716 goto done; 717 if (vec[i].iov_base != (void*)CHAIN_SPACE_PTR(chain) || 718 (size_t)vec[i].iov_len > CHAIN_SPACE_LEN(chain)) 719 goto done; 720 chain = chain->next; 721 } 722 /* pass 2: actually adjust all the chains. */ 723 chainp = firstchainp; 724 for (i=0; i<n_vecs; ++i) { 725 (*chainp)->off += vec[i].iov_len; 726 added += vec[i].iov_len; 727 if (vec[i].iov_len) { 728 buf->last_with_datap = chainp; 729 } 730 chainp = &(*chainp)->next; 731 } 732 733 okay: 734 buf->total_len += added; 735 buf->n_add_for_cb += added; 736 result = 0; 737 evbuffer_invoke_callbacks(buf); 738 739 done: 740 EVBUFFER_UNLOCK(buf); 741 return result; 742 } 743 744 static inline int 745 HAS_PINNED_R(struct evbuffer *buf) 746 { 747 return (buf->last && CHAIN_PINNED_R(buf->last)); 748 } 749 750 static inline void 751 ZERO_CHAIN(struct evbuffer *dst) 752 { 753 ASSERT_EVBUFFER_LOCKED(dst); 754 dst->first = NULL; 755 dst->last = NULL; 756 dst->last_with_datap = &(dst)->first; 757 dst->total_len = 0; 758 } 759 760 /* Prepares the contents of src to be moved to another buffer by removing 761 * read-pinned chains. The first pinned chain is saved in first, and the 762 * last in last. If src has no read-pinned chains, first and last are set 763 * to NULL. */ 764 static int 765 PRESERVE_PINNED(struct evbuffer *src, struct evbuffer_chain **first, 766 struct evbuffer_chain **last) 767 { 768 struct evbuffer_chain *chain, **pinned; 769 770 ASSERT_EVBUFFER_LOCKED(src); 771 772 if (!HAS_PINNED_R(src)) { 773 *first = *last = NULL; 774 return 0; 775 } 776 777 pinned = src->last_with_datap; 778 if (!CHAIN_PINNED_R(*pinned)) 779 pinned = &(*pinned)->next; 780 EVUTIL_ASSERT(CHAIN_PINNED_R(*pinned)); 781 chain = *first = *pinned; 782 *last = src->last; 783 784 /* If there's data in the first pinned chain, we need to allocate 785 * a new chain and copy the data over. */ 786 if (chain->off) { 787 struct evbuffer_chain *tmp; 788 789 EVUTIL_ASSERT(pinned == src->last_with_datap); 790 tmp = evbuffer_chain_new(chain->off); 791 if (!tmp) 792 return -1; 793 memcpy(tmp->buffer, chain->buffer + chain->misalign, 794 chain->off); 795 tmp->off = chain->off; 796 *src->last_with_datap = tmp; 797 src->last = tmp; 798 chain->misalign += chain->off; 799 chain->off = 0; 800 } else { 801 src->last = *src->last_with_datap; 802 *pinned = NULL; 803 } 804 805 return 0; 806 } 807 808 static inline void 809 RESTORE_PINNED(struct evbuffer *src, struct evbuffer_chain *pinned, 810 struct evbuffer_chain *last) 811 { 812 ASSERT_EVBUFFER_LOCKED(src); 813 814 if (!pinned) { 815 ZERO_CHAIN(src); 816 return; 817 } 818 819 src->first = pinned; 820 src->last = last; 821 src->last_with_datap = &src->first; 822 src->total_len = 0; 823 } 824 825 static inline void 826 COPY_CHAIN(struct evbuffer *dst, struct evbuffer *src) 827 { 828 ASSERT_EVBUFFER_LOCKED(dst); 829 ASSERT_EVBUFFER_LOCKED(src); 830 dst->first = src->first; 831 if (src->last_with_datap == &src->first) 832 dst->last_with_datap = &dst->first; 833 else 834 dst->last_with_datap = src->last_with_datap; 835 dst->last = src->last; 836 dst->total_len = src->total_len; 837 } 838 839 static void 840 APPEND_CHAIN(struct evbuffer *dst, struct evbuffer *src) 841 { 842 ASSERT_EVBUFFER_LOCKED(dst); 843 ASSERT_EVBUFFER_LOCKED(src); 844 dst->last->next = src->first; 845 if (src->last_with_datap == &src->first) 846 dst->last_with_datap = &dst->last->next; 847 else 848 dst->last_with_datap = src->last_with_datap; 849 dst->last = src->last; 850 dst->total_len += src->total_len; 851 } 852 853 static void 854 PREPEND_CHAIN(struct evbuffer *dst, struct evbuffer *src) 855 { 856 ASSERT_EVBUFFER_LOCKED(dst); 857 ASSERT_EVBUFFER_LOCKED(src); 858 src->last->next = dst->first; 859 dst->first = src->first; 860 dst->total_len += src->total_len; 861 if (*dst->last_with_datap == NULL) { 862 if (src->last_with_datap == &(src)->first) 863 dst->last_with_datap = &dst->first; 864 else 865 dst->last_with_datap = src->last_with_datap; 866 } else if (dst->last_with_datap == &dst->first) { 867 dst->last_with_datap = &src->last->next; 868 } 869 } 870 871 int 872 evbuffer_add_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf) 873 { 874 struct evbuffer_chain *pinned, *last; 875 size_t in_total_len, out_total_len; 876 int result = 0; 877 878 EVBUFFER_LOCK2(inbuf, outbuf); 879 in_total_len = inbuf->total_len; 880 out_total_len = outbuf->total_len; 881 882 if (in_total_len == 0 || outbuf == inbuf) 883 goto done; 884 885 if (outbuf->freeze_end || inbuf->freeze_start) { 886 result = -1; 887 goto done; 888 } 889 890 if (PRESERVE_PINNED(inbuf, &pinned, &last) < 0) { 891 result = -1; 892 goto done; 893 } 894 895 if (out_total_len == 0) { 896 /* There might be an empty chain at the start of outbuf; free 897 * it. */ 898 evbuffer_free_all_chains(outbuf->first); 899 COPY_CHAIN(outbuf, inbuf); 900 } else { 901 APPEND_CHAIN(outbuf, inbuf); 902 } 903 904 RESTORE_PINNED(inbuf, pinned, last); 905 906 inbuf->n_del_for_cb += in_total_len; 907 outbuf->n_add_for_cb += in_total_len; 908 909 evbuffer_invoke_callbacks(inbuf); 910 evbuffer_invoke_callbacks(outbuf); 911 912 done: 913 EVBUFFER_UNLOCK2(inbuf, outbuf); 914 return result; 915 } 916 917 int 918 evbuffer_prepend_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf) 919 { 920 struct evbuffer_chain *pinned, *last; 921 size_t in_total_len, out_total_len; 922 int result = 0; 923 924 EVBUFFER_LOCK2(inbuf, outbuf); 925 926 in_total_len = inbuf->total_len; 927 out_total_len = outbuf->total_len; 928 929 if (!in_total_len || inbuf == outbuf) 930 goto done; 931 932 if (outbuf->freeze_start || inbuf->freeze_start) { 933 result = -1; 934 goto done; 935 } 936 937 if (PRESERVE_PINNED(inbuf, &pinned, &last) < 0) { 938 result = -1; 939 goto done; 940 } 941 942 if (out_total_len == 0) { 943 /* There might be an empty chain at the start of outbuf; free 944 * it. */ 945 evbuffer_free_all_chains(outbuf->first); 946 COPY_CHAIN(outbuf, inbuf); 947 } else { 948 PREPEND_CHAIN(outbuf, inbuf); 949 } 950 951 RESTORE_PINNED(inbuf, pinned, last); 952 953 inbuf->n_del_for_cb += in_total_len; 954 outbuf->n_add_for_cb += in_total_len; 955 956 evbuffer_invoke_callbacks(inbuf); 957 evbuffer_invoke_callbacks(outbuf); 958 done: 959 EVBUFFER_UNLOCK2(inbuf, outbuf); 960 return result; 961 } 962 963 int 964 evbuffer_drain(struct evbuffer *buf, size_t len) 965 { 966 struct evbuffer_chain *chain, *next; 967 size_t remaining, old_len; 968 int result = 0; 969 970 EVBUFFER_LOCK(buf); 971 old_len = buf->total_len; 972 973 if (old_len == 0) 974 goto done; 975 976 if (buf->freeze_start) { 977 result = -1; 978 goto done; 979 } 980 981 if (len >= old_len && !HAS_PINNED_R(buf)) { 982 len = old_len; 983 for (chain = buf->first; chain != NULL; chain = next) { 984 next = chain->next; 985 evbuffer_chain_free(chain); 986 } 987 988 ZERO_CHAIN(buf); 989 } else { 990 if (len >= old_len) 991 len = old_len; 992 993 buf->total_len -= len; 994 remaining = len; 995 for (chain = buf->first; 996 remaining >= chain->off; 997 chain = next) { 998 next = chain->next; 999 remaining -= chain->off; 1000 1001 if (chain == *buf->last_with_datap) { 1002 buf->last_with_datap = &buf->first; 1003 } 1004 if (&chain->next == buf->last_with_datap) 1005 buf->last_with_datap = &buf->first; 1006 1007 if (CHAIN_PINNED_R(chain)) { 1008 EVUTIL_ASSERT(remaining == 0); 1009 chain->misalign += chain->off; 1010 chain->off = 0; 1011 break; 1012 } else 1013 evbuffer_chain_free(chain); 1014 } 1015 1016 buf->first = chain; 1017 if (chain) { 1018 EVUTIL_ASSERT(remaining <= chain->off); 1019 chain->misalign += remaining; 1020 chain->off -= remaining; 1021 } 1022 } 1023 1024 buf->n_del_for_cb += len; 1025 /* Tell someone about changes in this buffer */ 1026 evbuffer_invoke_callbacks(buf); 1027 1028 done: 1029 EVBUFFER_UNLOCK(buf); 1030 return result; 1031 } 1032 1033 /* Reads data from an event buffer and drains the bytes read */ 1034 int 1035 evbuffer_remove(struct evbuffer *buf, void *data_out, size_t datlen) 1036 { 1037 ev_ssize_t n; 1038 EVBUFFER_LOCK(buf); 1039 n = evbuffer_copyout(buf, data_out, datlen); 1040 if (n > 0) { 1041 if (evbuffer_drain(buf, n)<0) 1042 n = -1; 1043 } 1044 EVBUFFER_UNLOCK(buf); 1045 return (int)n; 1046 } 1047 1048 ev_ssize_t 1049 evbuffer_copyout(struct evbuffer *buf, void *data_out, size_t datlen) 1050 { 1051 /*XXX fails badly on sendfile case. */ 1052 struct evbuffer_chain *chain; 1053 char *data = data_out; 1054 size_t nread; 1055 ev_ssize_t result = 0; 1056 1057 EVBUFFER_LOCK(buf); 1058 1059 chain = buf->first; 1060 1061 if (datlen >= buf->total_len) 1062 datlen = buf->total_len; 1063 1064 if (datlen == 0) 1065 goto done; 1066 1067 if (buf->freeze_start) { 1068 result = -1; 1069 goto done; 1070 } 1071 1072 nread = datlen; 1073 1074 while (datlen && datlen >= chain->off) { 1075 memcpy(data, chain->buffer + chain->misalign, chain->off); 1076 data += chain->off; 1077 datlen -= chain->off; 1078 1079 chain = chain->next; 1080 EVUTIL_ASSERT(chain || datlen==0); 1081 } 1082 1083 if (datlen) { 1084 EVUTIL_ASSERT(chain); 1085 EVUTIL_ASSERT(datlen <= chain->off); 1086 memcpy(data, chain->buffer + chain->misalign, datlen); 1087 } 1088 1089 result = nread; 1090 done: 1091 EVBUFFER_UNLOCK(buf); 1092 return result; 1093 } 1094 1095 /* reads data from the src buffer to the dst buffer, avoids memcpy as 1096 * possible. */ 1097 /* XXXX should return ev_ssize_t */ 1098 int 1099 evbuffer_remove_buffer(struct evbuffer *src, struct evbuffer *dst, 1100 size_t datlen) 1101 { 1102 /*XXX We should have an option to force this to be zero-copy.*/ 1103 1104 /*XXX can fail badly on sendfile case. */ 1105 struct evbuffer_chain *chain, *previous; 1106 size_t nread = 0; 1107 int result; 1108 1109 EVBUFFER_LOCK2(src, dst); 1110 1111 chain = previous = src->first; 1112 1113 if (datlen == 0 || dst == src) { 1114 result = 0; 1115 goto done; 1116 } 1117 1118 if (dst->freeze_end || src->freeze_start) { 1119 result = -1; 1120 goto done; 1121 } 1122 1123 /* short-cut if there is no more data buffered */ 1124 if (datlen >= src->total_len) { 1125 datlen = src->total_len; 1126 evbuffer_add_buffer(dst, src); 1127 result = (int)datlen; /*XXXX should return ev_ssize_t*/ 1128 goto done; 1129 } 1130 1131 /* removes chains if possible */ 1132 while (chain->off <= datlen) { 1133 /* We can't remove the last with data from src unless we 1134 * remove all chains, in which case we would have done the if 1135 * block above */ 1136 EVUTIL_ASSERT(chain != *src->last_with_datap); 1137 nread += chain->off; 1138 datlen -= chain->off; 1139 previous = chain; 1140 if (src->last_with_datap == &chain->next) 1141 src->last_with_datap = &src->first; 1142 chain = chain->next; 1143 } 1144 1145 if (nread) { 1146 /* we can remove the chain */ 1147 struct evbuffer_chain **chp; 1148 chp = evbuffer_free_trailing_empty_chains(dst); 1149 1150 if (dst->first == NULL) { 1151 dst->first = src->first; 1152 } else { 1153 *chp = src->first; 1154 } 1155 dst->last = previous; 1156 previous->next = NULL; 1157 src->first = chain; 1158 advance_last_with_data(dst); 1159 1160 dst->total_len += nread; 1161 dst->n_add_for_cb += nread; 1162 } 1163 1164 /* we know that there is more data in the src buffer than 1165 * we want to read, so we manually drain the chain */ 1166 evbuffer_add(dst, chain->buffer + chain->misalign, datlen); 1167 chain->misalign += datlen; 1168 chain->off -= datlen; 1169 nread += datlen; 1170 1171 /* You might think we would want to increment dst->n_add_for_cb 1172 * here too. But evbuffer_add above already took care of that. 1173 */ 1174 src->total_len -= nread; 1175 src->n_del_for_cb += nread; 1176 1177 if (nread) { 1178 evbuffer_invoke_callbacks(dst); 1179 evbuffer_invoke_callbacks(src); 1180 } 1181 result = (int)nread;/*XXXX should change return type */ 1182 1183 done: 1184 EVBUFFER_UNLOCK2(src, dst); 1185 return result; 1186 } 1187 1188 unsigned char * 1189 evbuffer_pullup(struct evbuffer *buf, ev_ssize_t size) 1190 { 1191 struct evbuffer_chain *chain, *next, *tmp, *last_with_data; 1192 unsigned char *buffer, *result = NULL; 1193 ev_ssize_t remaining; 1194 int removed_last_with_data = 0; 1195 int removed_last_with_datap = 0; 1196 1197 EVBUFFER_LOCK(buf); 1198 1199 chain = buf->first; 1200 1201 if (size < 0) 1202 size = buf->total_len; 1203 /* if size > buf->total_len, we cannot guarantee to the user that she 1204 * is going to have a long enough buffer afterwards; so we return 1205 * NULL */ 1206 if (size == 0 || (size_t)size > buf->total_len) 1207 goto done; 1208 1209 /* No need to pull up anything; the first size bytes are 1210 * already here. */ 1211 if (chain->off >= (size_t)size) { 1212 result = chain->buffer + chain->misalign; 1213 goto done; 1214 } 1215 1216 /* Make sure that none of the chains we need to copy from is pinned. */ 1217 remaining = size - chain->off; 1218 EVUTIL_ASSERT(remaining >= 0); 1219 for (tmp=chain->next; tmp; tmp=tmp->next) { 1220 if (CHAIN_PINNED(tmp)) 1221 goto done; 1222 if (tmp->off >= (size_t)remaining) 1223 break; 1224 remaining -= tmp->off; 1225 } 1226 1227 if (CHAIN_PINNED(chain)) { 1228 size_t old_off = chain->off; 1229 if (CHAIN_SPACE_LEN(chain) < size - chain->off) { 1230 /* not enough room at end of chunk. */ 1231 goto done; 1232 } 1233 buffer = CHAIN_SPACE_PTR(chain); 1234 tmp = chain; 1235 tmp->off = size; 1236 size -= old_off; 1237 chain = chain->next; 1238 } else if (chain->buffer_len - chain->misalign >= (size_t)size) { 1239 /* already have enough space in the first chain */ 1240 size_t old_off = chain->off; 1241 buffer = chain->buffer + chain->misalign + chain->off; 1242 tmp = chain; 1243 tmp->off = size; 1244 size -= old_off; 1245 chain = chain->next; 1246 } else { 1247 if ((tmp = evbuffer_chain_new(size)) == NULL) { 1248 event_warn("%s: out of memory", __func__); 1249 goto done; 1250 } 1251 buffer = tmp->buffer; 1252 tmp->off = size; 1253 buf->first = tmp; 1254 } 1255 1256 /* TODO(niels): deal with buffers that point to NULL like sendfile */ 1257 1258 /* Copy and free every chunk that will be entirely pulled into tmp */ 1259 last_with_data = *buf->last_with_datap; 1260 for (; chain != NULL && (size_t)size >= chain->off; chain = next) { 1261 next = chain->next; 1262 1263 memcpy(buffer, chain->buffer + chain->misalign, chain->off); 1264 size -= chain->off; 1265 buffer += chain->off; 1266 if (chain == last_with_data) 1267 removed_last_with_data = 1; 1268 if (&chain->next == buf->last_with_datap) 1269 removed_last_with_datap = 1; 1270 1271 evbuffer_chain_free(chain); 1272 } 1273 1274 if (chain != NULL) { 1275 memcpy(buffer, chain->buffer + chain->misalign, size); 1276 chain->misalign += size; 1277 chain->off -= size; 1278 } else { 1279 buf->last = tmp; 1280 } 1281 1282 tmp->next = chain; 1283 1284 if (removed_last_with_data) { 1285 buf->last_with_datap = &buf->first; 1286 } else if (removed_last_with_datap) { 1287 if (buf->first->next && buf->first->next->off) 1288 buf->last_with_datap = &buf->first->next; 1289 else 1290 buf->last_with_datap = &buf->first; 1291 } 1292 1293 result = (tmp->buffer + tmp->misalign); 1294 1295 done: 1296 EVBUFFER_UNLOCK(buf); 1297 return result; 1298 } 1299 1300 /* 1301 * Reads a line terminated by either '\r\n', '\n\r' or '\r' or '\n'. 1302 * The returned buffer needs to be freed by the called. 1303 */ 1304 char * 1305 evbuffer_readline(struct evbuffer *buffer) 1306 { 1307 return evbuffer_readln(buffer, NULL, EVBUFFER_EOL_ANY); 1308 } 1309 1310 static inline ev_ssize_t 1311 evbuffer_strchr(struct evbuffer_ptr *it, const char chr) 1312 { 1313 struct evbuffer_chain *chain = it->_internal.chain; 1314 size_t i = it->_internal.pos_in_chain; 1315 while (chain != NULL) { 1316 char *buffer = (char *)chain->buffer + chain->misalign; 1317 char *cp = memchr(buffer+i, chr, chain->off-i); 1318 if (cp) { 1319 it->_internal.chain = chain; 1320 it->_internal.pos_in_chain = cp - buffer; 1321 it->pos += (cp - buffer - i); 1322 return it->pos; 1323 } 1324 it->pos += chain->off - i; 1325 i = 0; 1326 chain = chain->next; 1327 } 1328 1329 return (-1); 1330 } 1331 1332 static inline char * 1333 find_eol_char(char *s, size_t len) 1334 { 1335 #define CHUNK_SZ 128 1336 /* Lots of benchmarking found this approach to be faster in practice 1337 * than doing two memchrs over the whole buffer, doin a memchr on each 1338 * char of the buffer, or trying to emulate memchr by hand. */ 1339 char *s_end, *cr, *lf; 1340 s_end = s+len; 1341 while (s < s_end) { 1342 size_t chunk = (s + CHUNK_SZ < s_end) ? CHUNK_SZ : (s_end - s); 1343 cr = memchr(s, '\r', chunk); 1344 lf = memchr(s, '\n', chunk); 1345 if (cr) { 1346 if (lf && lf < cr) 1347 return lf; 1348 return cr; 1349 } else if (lf) { 1350 return lf; 1351 } 1352 s += CHUNK_SZ; 1353 } 1354 1355 return NULL; 1356 #undef CHUNK_SZ 1357 } 1358 1359 static ev_ssize_t 1360 evbuffer_find_eol_char(struct evbuffer_ptr *it) 1361 { 1362 struct evbuffer_chain *chain = it->_internal.chain; 1363 size_t i = it->_internal.pos_in_chain; 1364 while (chain != NULL) { 1365 char *buffer = (char *)chain->buffer + chain->misalign; 1366 char *cp = find_eol_char(buffer+i, chain->off-i); 1367 if (cp) { 1368 it->_internal.chain = chain; 1369 it->_internal.pos_in_chain = cp - buffer; 1370 it->pos += (cp - buffer) - i; 1371 return it->pos; 1372 } 1373 it->pos += chain->off - i; 1374 i = 0; 1375 chain = chain->next; 1376 } 1377 1378 return (-1); 1379 } 1380 1381 static inline int 1382 evbuffer_strspn( 1383 struct evbuffer_ptr *ptr, const char *chrset) 1384 { 1385 int count = 0; 1386 struct evbuffer_chain *chain = ptr->_internal.chain; 1387 size_t i = ptr->_internal.pos_in_chain; 1388 1389 if (!chain) 1390 return -1; 1391 1392 while (1) { 1393 char *buffer = (char *)chain->buffer + chain->misalign; 1394 for (; i < chain->off; ++i) { 1395 const char *p = chrset; 1396 while (*p) { 1397 if (buffer[i] == *p++) 1398 goto next; 1399 } 1400 ptr->_internal.chain = chain; 1401 ptr->_internal.pos_in_chain = i; 1402 ptr->pos += count; 1403 return count; 1404 next: 1405 ++count; 1406 } 1407 i = 0; 1408 1409 if (! chain->next) { 1410 ptr->_internal.chain = chain; 1411 ptr->_internal.pos_in_chain = i; 1412 ptr->pos += count; 1413 return count; 1414 } 1415 1416 chain = chain->next; 1417 } 1418 } 1419 1420 1421 static inline char 1422 evbuffer_getchr(struct evbuffer_ptr *it) 1423 { 1424 struct evbuffer_chain *chain = it->_internal.chain; 1425 size_t off = it->_internal.pos_in_chain; 1426 1427 return chain->buffer[chain->misalign + off]; 1428 } 1429 1430 struct evbuffer_ptr 1431 evbuffer_search_eol(struct evbuffer *buffer, 1432 struct evbuffer_ptr *start, size_t *eol_len_out, 1433 enum evbuffer_eol_style eol_style) 1434 { 1435 struct evbuffer_ptr it, it2; 1436 size_t extra_drain = 0; 1437 int ok = 0; 1438 1439 EVBUFFER_LOCK(buffer); 1440 1441 if (start) { 1442 memcpy(&it, start, sizeof(it)); 1443 } else { 1444 it.pos = 0; 1445 it._internal.chain = buffer->first; 1446 it._internal.pos_in_chain = 0; 1447 } 1448 1449 /* the eol_style determines our first stop character and how many 1450 * characters we are going to drain afterwards. */ 1451 switch (eol_style) { 1452 case EVBUFFER_EOL_ANY: 1453 if (evbuffer_find_eol_char(&it) < 0) 1454 goto done; 1455 memcpy(&it2, &it, sizeof(it)); 1456 extra_drain = evbuffer_strspn(&it2, "\r\n"); 1457 break; 1458 case EVBUFFER_EOL_CRLF_STRICT: { 1459 it = evbuffer_search(buffer, "\r\n", 2, &it); 1460 if (it.pos < 0) 1461 goto done; 1462 extra_drain = 2; 1463 break; 1464 } 1465 case EVBUFFER_EOL_CRLF: 1466 while (1) { 1467 if (evbuffer_find_eol_char(&it) < 0) 1468 goto done; 1469 if (evbuffer_getchr(&it) == '\n') { 1470 extra_drain = 1; 1471 break; 1472 } else if (!evbuffer_ptr_memcmp( 1473 buffer, &it, "\r\n", 2)) { 1474 extra_drain = 2; 1475 break; 1476 } else { 1477 if (evbuffer_ptr_set(buffer, &it, 1, 1478 EVBUFFER_PTR_ADD)<0) 1479 goto done; 1480 } 1481 } 1482 break; 1483 case EVBUFFER_EOL_LF: 1484 if (evbuffer_strchr(&it, '\n') < 0) 1485 goto done; 1486 extra_drain = 1; 1487 break; 1488 default: 1489 goto done; 1490 } 1491 1492 ok = 1; 1493 done: 1494 EVBUFFER_UNLOCK(buffer); 1495 1496 if (!ok) { 1497 it.pos = -1; 1498 } 1499 if (eol_len_out) 1500 *eol_len_out = extra_drain; 1501 1502 return it; 1503 } 1504 1505 char * 1506 evbuffer_readln(struct evbuffer *buffer, size_t *n_read_out, 1507 enum evbuffer_eol_style eol_style) 1508 { 1509 struct evbuffer_ptr it; 1510 char *line; 1511 size_t n_to_copy=0, extra_drain=0; 1512 char *result = NULL; 1513 1514 EVBUFFER_LOCK(buffer); 1515 1516 if (buffer->freeze_start) { 1517 goto done; 1518 } 1519 1520 it = evbuffer_search_eol(buffer, NULL, &extra_drain, eol_style); 1521 if (it.pos < 0) 1522 goto done; 1523 n_to_copy = it.pos; 1524 1525 if ((line = mm_malloc(n_to_copy+1)) == NULL) { 1526 event_warn("%s: out of memory", __func__); 1527 goto done; 1528 } 1529 1530 evbuffer_remove(buffer, line, n_to_copy); 1531 line[n_to_copy] = '\0'; 1532 1533 evbuffer_drain(buffer, extra_drain); 1534 result = line; 1535 done: 1536 EVBUFFER_UNLOCK(buffer); 1537 1538 if (n_read_out) 1539 *n_read_out = result ? n_to_copy : 0; 1540 1541 return result; 1542 } 1543 1544 #define EVBUFFER_CHAIN_MAX_AUTO_SIZE 4096 1545 1546 /* Adds data to an event buffer */ 1547 1548 int 1549 evbuffer_add(struct evbuffer *buf, const void *data_in, size_t datlen) 1550 { 1551 struct evbuffer_chain *chain, *tmp; 1552 const unsigned char *data = data_in; 1553 size_t remain, to_alloc; 1554 int result = -1; 1555 1556 EVBUFFER_LOCK(buf); 1557 1558 if (buf->freeze_end) { 1559 goto done; 1560 } 1561 /* Prevent buf->total_len overflow */ 1562 if (datlen > EV_SIZE_MAX - buf->total_len) { 1563 goto done; 1564 } 1565 1566 chain = buf->last; 1567 1568 /* If there are no chains allocated for this buffer, allocate one 1569 * big enough to hold all the data. */ 1570 if (chain == NULL) { 1571 chain = evbuffer_chain_new(datlen); 1572 if (!chain) 1573 goto done; 1574 evbuffer_chain_insert(buf, chain); 1575 } 1576 1577 if ((chain->flags & EVBUFFER_IMMUTABLE) == 0) { 1578 /* Always true for mutable buffers */ 1579 EVUTIL_ASSERT(chain->misalign >= 0 && 1580 (ev_uint64_t)chain->misalign <= EVBUFFER_CHAIN_MAX); 1581 remain = chain->buffer_len - (size_t)chain->misalign - chain->off; 1582 if (remain >= datlen) { 1583 /* there's enough space to hold all the data in the 1584 * current last chain */ 1585 memcpy(chain->buffer + chain->misalign + chain->off, 1586 data, datlen); 1587 chain->off += datlen; 1588 buf->total_len += datlen; 1589 buf->n_add_for_cb += datlen; 1590 goto out; 1591 } else if (!CHAIN_PINNED(chain) && 1592 evbuffer_chain_should_realign(chain, datlen)) { 1593 /* we can fit the data into the misalignment */ 1594 evbuffer_chain_align(chain); 1595 1596 memcpy(chain->buffer + chain->off, data, datlen); 1597 chain->off += datlen; 1598 buf->total_len += datlen; 1599 buf->n_add_for_cb += datlen; 1600 goto out; 1601 } 1602 } else { 1603 /* we cannot write any data to the last chain */ 1604 remain = 0; 1605 } 1606 1607 /* we need to add another chain */ 1608 to_alloc = chain->buffer_len; 1609 if (to_alloc <= EVBUFFER_CHAIN_MAX_AUTO_SIZE/2) 1610 to_alloc <<= 1; 1611 if (datlen > to_alloc) 1612 to_alloc = datlen; 1613 tmp = evbuffer_chain_new(to_alloc); 1614 if (tmp == NULL) 1615 goto done; 1616 1617 if (remain) { 1618 memcpy(chain->buffer + chain->misalign + chain->off, 1619 data, remain); 1620 chain->off += remain; 1621 buf->total_len += remain; 1622 buf->n_add_for_cb += remain; 1623 } 1624 1625 data += remain; 1626 datlen -= remain; 1627 1628 memcpy(tmp->buffer, data, datlen); 1629 tmp->off = datlen; 1630 evbuffer_chain_insert(buf, tmp); 1631 buf->n_add_for_cb += datlen; 1632 1633 out: 1634 evbuffer_invoke_callbacks(buf); 1635 result = 0; 1636 done: 1637 EVBUFFER_UNLOCK(buf); 1638 return result; 1639 } 1640 1641 int 1642 evbuffer_prepend(struct evbuffer *buf, const void *data, size_t datlen) 1643 { 1644 struct evbuffer_chain *chain, *tmp; 1645 int result = -1; 1646 1647 EVBUFFER_LOCK(buf); 1648 1649 if (buf->freeze_start) { 1650 goto done; 1651 } 1652 if (datlen > EV_SIZE_MAX - buf->total_len) { 1653 goto done; 1654 } 1655 1656 chain = buf->first; 1657 1658 if (chain == NULL) { 1659 chain = evbuffer_chain_new(datlen); 1660 if (!chain) 1661 goto done; 1662 evbuffer_chain_insert(buf, chain); 1663 } 1664 1665 /* we cannot touch immutable buffers */ 1666 if ((chain->flags & EVBUFFER_IMMUTABLE) == 0) { 1667 /* Always true for mutable buffers */ 1668 EVUTIL_ASSERT(chain->misalign >= 0 && 1669 (ev_uint64_t)chain->misalign <= EVBUFFER_CHAIN_MAX); 1670 1671 /* If this chain is empty, we can treat it as 1672 * 'empty at the beginning' rather than 'empty at the end' */ 1673 if (chain->off == 0) 1674 chain->misalign = chain->buffer_len; 1675 1676 if ((size_t)chain->misalign >= datlen) { 1677 /* we have enough space to fit everything */ 1678 memcpy(chain->buffer + chain->misalign - datlen, 1679 data, datlen); 1680 chain->off += datlen; 1681 chain->misalign -= datlen; 1682 buf->total_len += datlen; 1683 buf->n_add_for_cb += datlen; 1684 goto out; 1685 } else if (chain->misalign) { 1686 /* we can only fit some of the data. */ 1687 memcpy(chain->buffer, 1688 (const char*)data + datlen - chain->misalign, 1689 (size_t)chain->misalign); 1690 chain->off += (size_t)chain->misalign; 1691 buf->total_len += (size_t)chain->misalign; 1692 buf->n_add_for_cb += (size_t)chain->misalign; 1693 datlen -= (size_t)chain->misalign; 1694 chain->misalign = 0; 1695 } 1696 } 1697 1698 /* we need to add another chain */ 1699 if ((tmp = evbuffer_chain_new(datlen)) == NULL) 1700 goto done; 1701 buf->first = tmp; 1702 if (buf->last_with_datap == &buf->first) 1703 buf->last_with_datap = &tmp->next; 1704 1705 tmp->next = chain; 1706 1707 tmp->off = datlen; 1708 EVUTIL_ASSERT(datlen <= tmp->buffer_len); 1709 tmp->misalign = tmp->buffer_len - datlen; 1710 1711 memcpy(tmp->buffer + tmp->misalign, data, datlen); 1712 buf->total_len += datlen; 1713 buf->n_add_for_cb += (size_t)chain->misalign; 1714 1715 out: 1716 evbuffer_invoke_callbacks(buf); 1717 result = 0; 1718 done: 1719 EVBUFFER_UNLOCK(buf); 1720 return result; 1721 } 1722 1723 /** Helper: realigns the memory in chain->buffer so that misalign is 0. */ 1724 static void 1725 evbuffer_chain_align(struct evbuffer_chain *chain) 1726 { 1727 EVUTIL_ASSERT(!(chain->flags & EVBUFFER_IMMUTABLE)); 1728 EVUTIL_ASSERT(!(chain->flags & EVBUFFER_MEM_PINNED_ANY)); 1729 memmove(chain->buffer, chain->buffer + chain->misalign, chain->off); 1730 chain->misalign = 0; 1731 } 1732 1733 #define MAX_TO_COPY_IN_EXPAND 4096 1734 #define MAX_TO_REALIGN_IN_EXPAND 2048 1735 1736 /** Helper: return true iff we should realign chain to fit datalen bytes of 1737 data in it. */ 1738 static int 1739 evbuffer_chain_should_realign(struct evbuffer_chain *chain, 1740 size_t datlen) 1741 { 1742 return chain->buffer_len - chain->off >= datlen && 1743 (chain->off < chain->buffer_len / 2) && 1744 (chain->off <= MAX_TO_REALIGN_IN_EXPAND); 1745 } 1746 1747 /* Expands the available space in the event buffer to at least datlen, all in 1748 * a single chunk. Return that chunk. */ 1749 static struct evbuffer_chain * 1750 evbuffer_expand_singlechain(struct evbuffer *buf, size_t datlen) 1751 { 1752 struct evbuffer_chain *chain, **chainp; 1753 struct evbuffer_chain *result = NULL; 1754 ASSERT_EVBUFFER_LOCKED(buf); 1755 1756 chainp = buf->last_with_datap; 1757 1758 /* XXX If *chainp is no longer writeable, but has enough space in its 1759 * misalign, this might be a bad idea: we could still use *chainp, not 1760 * (*chainp)->next. */ 1761 if (*chainp && CHAIN_SPACE_LEN(*chainp) == 0) 1762 chainp = &(*chainp)->next; 1763 1764 /* 'chain' now points to the first chain with writable space (if any) 1765 * We will either use it, realign it, replace it, or resize it. */ 1766 chain = *chainp; 1767 1768 if (chain == NULL || 1769 (chain->flags & (EVBUFFER_IMMUTABLE|EVBUFFER_MEM_PINNED_ANY))) { 1770 /* We can't use the last_with_data chain at all. Just add a 1771 * new one that's big enough. */ 1772 goto insert_new; 1773 } 1774 1775 /* If we can fit all the data, then we don't have to do anything */ 1776 if (CHAIN_SPACE_LEN(chain) >= datlen) { 1777 result = chain; 1778 goto ok; 1779 } 1780 1781 /* If the chain is completely empty, just replace it by adding a new 1782 * empty chain. */ 1783 if (chain->off == 0) { 1784 goto insert_new; 1785 } 1786 1787 /* If the misalignment plus the remaining space fulfills our data 1788 * needs, we could just force an alignment to happen. Afterwards, we 1789 * have enough space. But only do this if we're saving a lot of space 1790 * and not moving too much data. Otherwise the space savings are 1791 * probably offset by the time lost in copying. 1792 */ 1793 if (evbuffer_chain_should_realign(chain, datlen)) { 1794 evbuffer_chain_align(chain); 1795 result = chain; 1796 goto ok; 1797 } 1798 1799 /* At this point, we can either resize the last chunk with space in 1800 * it, use the next chunk after it, or If we add a new chunk, we waste 1801 * CHAIN_SPACE_LEN(chain) bytes in the former last chunk. If we 1802 * resize, we have to copy chain->off bytes. 1803 */ 1804 1805 /* Would expanding this chunk be affordable and worthwhile? */ 1806 if (CHAIN_SPACE_LEN(chain) < chain->buffer_len / 8 || 1807 chain->off > MAX_TO_COPY_IN_EXPAND || 1808 (datlen < EVBUFFER_CHAIN_MAX && 1809 EVBUFFER_CHAIN_MAX - datlen >= chain->off)) { 1810 /* It's not worth resizing this chain. Can the next one be 1811 * used? */ 1812 if (chain->next && CHAIN_SPACE_LEN(chain->next) >= datlen) { 1813 /* Yes, we can just use the next chain (which should 1814 * be empty. */ 1815 result = chain->next; 1816 goto ok; 1817 } else { 1818 /* No; append a new chain (which will free all 1819 * terminal empty chains.) */ 1820 goto insert_new; 1821 } 1822 } else { 1823 /* Okay, we're going to try to resize this chain: Not doing so 1824 * would waste at least 1/8 of its current allocation, and we 1825 * can do so without having to copy more than 1826 * MAX_TO_COPY_IN_EXPAND bytes. */ 1827 /* figure out how much space we need */ 1828 size_t length = chain->off + datlen; 1829 struct evbuffer_chain *tmp = evbuffer_chain_new(length); 1830 if (tmp == NULL) 1831 goto err; 1832 1833 /* copy the data over that we had so far */ 1834 tmp->off = chain->off; 1835 memcpy(tmp->buffer, chain->buffer + chain->misalign, 1836 chain->off); 1837 /* fix up the list */ 1838 EVUTIL_ASSERT(*chainp == chain); 1839 result = *chainp = tmp; 1840 1841 if (buf->last == chain) 1842 buf->last = tmp; 1843 1844 tmp->next = chain->next; 1845 evbuffer_chain_free(chain); 1846 goto ok; 1847 } 1848 1849 insert_new: 1850 result = evbuffer_chain_insert_new(buf, datlen); 1851 if (!result) 1852 goto err; 1853 ok: 1854 EVUTIL_ASSERT(result); 1855 EVUTIL_ASSERT(CHAIN_SPACE_LEN(result) >= datlen); 1856 err: 1857 return result; 1858 } 1859 1860 /* Make sure that datlen bytes are available for writing in the last n 1861 * chains. Never copies or moves data. */ 1862 int 1863 _evbuffer_expand_fast(struct evbuffer *buf, size_t datlen, int n) 1864 { 1865 struct evbuffer_chain *chain = buf->last, *tmp, *next; 1866 size_t avail; 1867 int used; 1868 1869 ASSERT_EVBUFFER_LOCKED(buf); 1870 EVUTIL_ASSERT(n >= 2); 1871 1872 if (chain == NULL || (chain->flags & EVBUFFER_IMMUTABLE)) { 1873 /* There is no last chunk, or we can't touch the last chunk. 1874 * Just add a new chunk. */ 1875 chain = evbuffer_chain_new(datlen); 1876 if (chain == NULL) 1877 return (-1); 1878 1879 evbuffer_chain_insert(buf, chain); 1880 return (0); 1881 } 1882 1883 used = 0; /* number of chains we're using space in. */ 1884 avail = 0; /* how much space they have. */ 1885 /* How many bytes can we stick at the end of buffer as it is? Iterate 1886 * over the chains at the end of the buffer, tring to see how much 1887 * space we have in the first n. */ 1888 for (chain = *buf->last_with_datap; chain; chain = chain->next) { 1889 if (chain->off) { 1890 size_t space = (size_t) CHAIN_SPACE_LEN(chain); 1891 EVUTIL_ASSERT(chain == *buf->last_with_datap); 1892 if (space) { 1893 avail += space; 1894 ++used; 1895 } 1896 } else { 1897 /* No data in chain; realign it. */ 1898 chain->misalign = 0; 1899 avail += chain->buffer_len; 1900 ++used; 1901 } 1902 if (avail >= datlen) { 1903 /* There is already enough space. Just return */ 1904 return (0); 1905 } 1906 if (used == n) 1907 break; 1908 } 1909 1910 /* There wasn't enough space in the first n chains with space in 1911 * them. Either add a new chain with enough space, or replace all 1912 * empty chains with one that has enough space, depending on n. */ 1913 if (used < n) { 1914 /* The loop ran off the end of the chains before it hit n 1915 * chains; we can add another. */ 1916 EVUTIL_ASSERT(chain == NULL); 1917 1918 tmp = evbuffer_chain_new(datlen - avail); 1919 if (tmp == NULL) 1920 return (-1); 1921 1922 buf->last->next = tmp; 1923 buf->last = tmp; 1924 /* (we would only set last_with_data if we added the first 1925 * chain. But if the buffer had no chains, we would have 1926 * just allocated a new chain earlier) */ 1927 return (0); 1928 } else { 1929 /* Nuke _all_ the empty chains. */ 1930 int rmv_all = 0; /* True iff we removed last_with_data. */ 1931 chain = *buf->last_with_datap; 1932 if (!chain->off) { 1933 EVUTIL_ASSERT(chain == buf->first); 1934 rmv_all = 1; 1935 avail = 0; 1936 } else { 1937 /* can't overflow, since only mutable chains have 1938 * huge misaligns. */ 1939 avail = (size_t) CHAIN_SPACE_LEN(chain); 1940 chain = chain->next; 1941 } 1942 1943 1944 for (; chain; chain = next) { 1945 next = chain->next; 1946 EVUTIL_ASSERT(chain->off == 0); 1947 evbuffer_chain_free(chain); 1948 } 1949 EVUTIL_ASSERT(datlen >= avail); 1950 tmp = evbuffer_chain_new(datlen - avail); 1951 if (tmp == NULL) { 1952 if (rmv_all) { 1953 ZERO_CHAIN(buf); 1954 } else { 1955 buf->last = *buf->last_with_datap; 1956 (*buf->last_with_datap)->next = NULL; 1957 } 1958 return (-1); 1959 } 1960 1961 if (rmv_all) { 1962 buf->first = buf->last = tmp; 1963 buf->last_with_datap = &buf->first; 1964 } else { 1965 (*buf->last_with_datap)->next = tmp; 1966 buf->last = tmp; 1967 } 1968 return (0); 1969 } 1970 } 1971 1972 int 1973 evbuffer_expand(struct evbuffer *buf, size_t datlen) 1974 { 1975 struct evbuffer_chain *chain; 1976 1977 EVBUFFER_LOCK(buf); 1978 chain = evbuffer_expand_singlechain(buf, datlen); 1979 EVBUFFER_UNLOCK(buf); 1980 return chain ? 0 : -1; 1981 } 1982 1983 /* 1984 * Reads data from a file descriptor into a buffer. 1985 */ 1986 1987 #if defined(_EVENT_HAVE_SYS_UIO_H) || defined(WIN32) 1988 #define USE_IOVEC_IMPL 1989 #endif 1990 1991 #ifdef USE_IOVEC_IMPL 1992 1993 #ifdef _EVENT_HAVE_SYS_UIO_H 1994 /* number of iovec we use for writev, fragmentation is going to determine 1995 * how much we end up writing */ 1996 1997 #define DEFAULT_WRITE_IOVEC 128 1998 1999 #if defined(UIO_MAXIOV) && UIO_MAXIOV < DEFAULT_WRITE_IOVEC 2000 #define NUM_WRITE_IOVEC UIO_MAXIOV 2001 #elif defined(IOV_MAX) && IOV_MAX < DEFAULT_WRITE_IOVEC 2002 #define NUM_WRITE_IOVEC IOV_MAX 2003 #else 2004 #define NUM_WRITE_IOVEC DEFAULT_WRITE_IOVEC 2005 #endif 2006 2007 #define IOV_TYPE struct iovec 2008 #define IOV_PTR_FIELD iov_base 2009 #define IOV_LEN_FIELD iov_len 2010 #define IOV_LEN_TYPE size_t 2011 #else 2012 #define NUM_WRITE_IOVEC 16 2013 #define IOV_TYPE WSABUF 2014 #define IOV_PTR_FIELD buf 2015 #define IOV_LEN_FIELD len 2016 #define IOV_LEN_TYPE unsigned long 2017 #endif 2018 #endif 2019 #define NUM_READ_IOVEC 4 2020 2021 #define EVBUFFER_MAX_READ 4096 2022 2023 /** Helper function to figure out which space to use for reading data into 2024 an evbuffer. Internal use only. 2025 2026 @param buf The buffer to read into 2027 @param howmuch How much we want to read. 2028 @param vecs An array of two or more iovecs or WSABUFs. 2029 @param n_vecs_avail The length of vecs 2030 @param chainp A pointer to a variable to hold the first chain we're 2031 reading into. 2032 @param exact Boolean: if true, we do not provide more than 'howmuch' 2033 space in the vectors, even if more space is available. 2034 @return The number of buffers we're using. 2035 */ 2036 int 2037 _evbuffer_read_setup_vecs(struct evbuffer *buf, ev_ssize_t howmuch, 2038 struct evbuffer_iovec *vecs, int n_vecs_avail, 2039 struct evbuffer_chain ***chainp, int exact) 2040 { 2041 struct evbuffer_chain *chain; 2042 struct evbuffer_chain **firstchainp; 2043 size_t so_far; 2044 int i; 2045 ASSERT_EVBUFFER_LOCKED(buf); 2046 2047 if (howmuch < 0) 2048 return -1; 2049 2050 so_far = 0; 2051 /* Let firstchain be the first chain with any space on it */ 2052 firstchainp = buf->last_with_datap; 2053 if (CHAIN_SPACE_LEN(*firstchainp) == 0) { 2054 firstchainp = &(*firstchainp)->next; 2055 } 2056 2057 chain = *firstchainp; 2058 for (i = 0; i < n_vecs_avail && so_far < (size_t)howmuch; ++i) { 2059 size_t avail = (size_t) CHAIN_SPACE_LEN(chain); 2060 if (avail > (howmuch - so_far) && exact) 2061 avail = howmuch - so_far; 2062 vecs[i].iov_base = CHAIN_SPACE_PTR(chain); 2063 vecs[i].iov_len = avail; 2064 so_far += avail; 2065 chain = chain->next; 2066 } 2067 2068 *chainp = firstchainp; 2069 return i; 2070 } 2071 2072 static int 2073 get_n_bytes_readable_on_socket(evutil_socket_t fd) 2074 { 2075 #if defined(FIONREAD) && defined(WIN32) 2076 unsigned long lng = EVBUFFER_MAX_READ; 2077 if (ioctlsocket(fd, FIONREAD, &lng) < 0) 2078 return -1; 2079 /* Can overflow, but mostly harmlessly. XXXX */ 2080 return (int)lng; 2081 #elif defined(FIONREAD) 2082 int n = EVBUFFER_MAX_READ; 2083 if (ioctl(fd, FIONREAD, &n) < 0) 2084 return -1; 2085 return n; 2086 #else 2087 return EVBUFFER_MAX_READ; 2088 #endif 2089 } 2090 2091 /* TODO(niels): should this function return ev_ssize_t and take ev_ssize_t 2092 * as howmuch? */ 2093 int 2094 evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch) 2095 { 2096 struct evbuffer_chain **chainp; 2097 int n; 2098 int result; 2099 2100 #ifdef USE_IOVEC_IMPL 2101 int nvecs, i, remaining; 2102 #else 2103 struct evbuffer_chain *chain; 2104 unsigned char *p; 2105 #endif 2106 2107 EVBUFFER_LOCK(buf); 2108 2109 if (buf->freeze_end) { 2110 result = -1; 2111 goto done; 2112 } 2113 2114 n = get_n_bytes_readable_on_socket(fd); 2115 if (n <= 0 || n > EVBUFFER_MAX_READ) 2116 n = EVBUFFER_MAX_READ; 2117 if (howmuch < 0 || howmuch > n) 2118 howmuch = n; 2119 2120 #ifdef USE_IOVEC_IMPL 2121 /* Since we can use iovecs, we're willing to use the last 2122 * NUM_READ_IOVEC chains. */ 2123 if (_evbuffer_expand_fast(buf, howmuch, NUM_READ_IOVEC) == -1) { 2124 result = -1; 2125 goto done; 2126 } else { 2127 IOV_TYPE vecs[NUM_READ_IOVEC]; 2128 #ifdef _EVBUFFER_IOVEC_IS_NATIVE 2129 nvecs = _evbuffer_read_setup_vecs(buf, howmuch, vecs, 2130 NUM_READ_IOVEC, &chainp, 1); 2131 #else 2132 /* We aren't using the native struct iovec. Therefore, 2133 we are on win32. */ 2134 struct evbuffer_iovec ev_vecs[NUM_READ_IOVEC]; 2135 nvecs = _evbuffer_read_setup_vecs(buf, howmuch, ev_vecs, 2, 2136 &chainp, 1); 2137 2138 for (i=0; i < nvecs; ++i) 2139 WSABUF_FROM_EVBUFFER_IOV(&vecs[i], &ev_vecs[i]); 2140 #endif 2141 2142 #ifdef WIN32 2143 { 2144 DWORD bytesRead; 2145 DWORD flags=0; 2146 if (WSARecv(fd, vecs, nvecs, &bytesRead, &flags, NULL, NULL)) { 2147 /* The read failed. It might be a close, 2148 * or it might be an error. */ 2149 if (WSAGetLastError() == WSAECONNABORTED) 2150 n = 0; 2151 else 2152 n = -1; 2153 } else 2154 n = bytesRead; 2155 } 2156 #else 2157 n = readv(fd, vecs, nvecs); 2158 #endif 2159 } 2160 2161 #else /*!USE_IOVEC_IMPL*/ 2162 /* If we don't have FIONREAD, we might waste some space here */ 2163 /* XXX we _will_ waste some space here if there is any space left 2164 * over on buf->last. */ 2165 if ((chain = evbuffer_expand_singlechain(buf, howmuch)) == NULL) { 2166 result = -1; 2167 goto done; 2168 } 2169 2170 /* We can append new data at this point */ 2171 p = chain->buffer + chain->misalign + chain->off; 2172 2173 #ifndef WIN32 2174 n = read(fd, p, howmuch); 2175 #else 2176 n = recv(fd, p, howmuch, 0); 2177 #endif 2178 #endif /* USE_IOVEC_IMPL */ 2179 2180 if (n == -1) { 2181 result = -1; 2182 goto done; 2183 } 2184 if (n == 0) { 2185 result = 0; 2186 goto done; 2187 } 2188 2189 #ifdef USE_IOVEC_IMPL 2190 remaining = n; 2191 for (i=0; i < nvecs; ++i) { 2192 /* can't overflow, since only mutable chains have 2193 * huge misaligns. */ 2194 size_t space = (size_t) CHAIN_SPACE_LEN(*chainp); 2195 /* XXXX This is a kludge that can waste space in perverse 2196 * situations. */ 2197 if (space > EVBUFFER_CHAIN_MAX) 2198 space = EVBUFFER_CHAIN_MAX; 2199 if ((ev_ssize_t)space < remaining) { 2200 (*chainp)->off += space; 2201 remaining -= (int)space; 2202 } else { 2203 (*chainp)->off += remaining; 2204 buf->last_with_datap = chainp; 2205 break; 2206 } 2207 chainp = &(*chainp)->next; 2208 } 2209 #else 2210 chain->off += n; 2211 advance_last_with_data(buf); 2212 #endif 2213 buf->total_len += n; 2214 buf->n_add_for_cb += n; 2215 2216 /* Tell someone about changes in this buffer */ 2217 evbuffer_invoke_callbacks(buf); 2218 result = n; 2219 done: 2220 EVBUFFER_UNLOCK(buf); 2221 return result; 2222 } 2223 2224 #ifdef WIN32 2225 static int 2226 evbuffer_readfile(struct evbuffer *buf, evutil_socket_t fd, ev_ssize_t howmuch) 2227 { 2228 int result; 2229 int nchains, n; 2230 struct evbuffer_iovec v[2]; 2231 2232 EVBUFFER_LOCK(buf); 2233 2234 if (buf->freeze_end) { 2235 result = -1; 2236 goto done; 2237 } 2238 2239 if (howmuch < 0) 2240 howmuch = 16384; 2241 2242 2243 /* XXX we _will_ waste some space here if there is any space left 2244 * over on buf->last. */ 2245 nchains = evbuffer_reserve_space(buf, howmuch, v, 2); 2246 if (nchains < 1 || nchains > 2) { 2247 result = -1; 2248 goto done; 2249 } 2250 n = read((int)fd, v[0].iov_base, (unsigned int)v[0].iov_len); 2251 if (n <= 0) { 2252 result = n; 2253 goto done; 2254 } 2255 v[0].iov_len = (IOV_LEN_TYPE) n; /* XXXX another problem with big n.*/ 2256 if (nchains > 1) { 2257 n = read((int)fd, v[1].iov_base, (unsigned int)v[1].iov_len); 2258 if (n <= 0) { 2259 result = (unsigned long) v[0].iov_len; 2260 evbuffer_commit_space(buf, v, 1); 2261 goto done; 2262 } 2263 v[1].iov_len = n; 2264 } 2265 evbuffer_commit_space(buf, v, nchains); 2266 2267 result = n; 2268 done: 2269 EVBUFFER_UNLOCK(buf); 2270 return result; 2271 } 2272 #endif 2273 2274 #ifdef USE_IOVEC_IMPL 2275 static inline int 2276 evbuffer_write_iovec(struct evbuffer *buffer, evutil_socket_t fd, 2277 ev_ssize_t howmuch) 2278 { 2279 IOV_TYPE iov[NUM_WRITE_IOVEC]; 2280 struct evbuffer_chain *chain = buffer->first; 2281 int n, i = 0; 2282 2283 if (howmuch < 0) 2284 return -1; 2285 2286 ASSERT_EVBUFFER_LOCKED(buffer); 2287 /* XXX make this top out at some maximal data length? if the 2288 * buffer has (say) 1MB in it, split over 128 chains, there's 2289 * no way it all gets written in one go. */ 2290 while (chain != NULL && i < NUM_WRITE_IOVEC && howmuch) { 2291 #ifdef USE_SENDFILE 2292 /* we cannot write the file info via writev */ 2293 if (chain->flags & EVBUFFER_SENDFILE) 2294 break; 2295 #endif 2296 iov[i].IOV_PTR_FIELD = (void *) (chain->buffer + chain->misalign); 2297 if ((size_t)howmuch >= chain->off) { 2298 /* XXXcould be problematic when windows supports mmap*/ 2299 iov[i++].IOV_LEN_FIELD = (IOV_LEN_TYPE)chain->off; 2300 howmuch -= chain->off; 2301 } else { 2302 /* XXXcould be problematic when windows supports mmap*/ 2303 iov[i++].IOV_LEN_FIELD = (IOV_LEN_TYPE)howmuch; 2304 break; 2305 } 2306 chain = chain->next; 2307 } 2308 if (! i) 2309 return 0; 2310 #ifdef WIN32 2311 { 2312 DWORD bytesSent; 2313 if (WSASend(fd, iov, i, &bytesSent, 0, NULL, NULL)) 2314 n = -1; 2315 else 2316 n = bytesSent; 2317 } 2318 #else 2319 n = writev(fd, iov, i); 2320 #endif 2321 return (n); 2322 } 2323 #endif 2324 2325 #ifdef USE_SENDFILE 2326 static inline int 2327 evbuffer_write_sendfile(struct evbuffer *buffer, evutil_socket_t fd, 2328 ev_ssize_t howmuch) 2329 { 2330 struct evbuffer_chain *chain = buffer->first; 2331 struct evbuffer_chain_fd *info = 2332 EVBUFFER_CHAIN_EXTRA(struct evbuffer_chain_fd, chain); 2333 #if defined(SENDFILE_IS_MACOSX) || defined(SENDFILE_IS_FREEBSD) 2334 int res; 2335 off_t len = chain->off; 2336 #elif defined(SENDFILE_IS_LINUX) || defined(SENDFILE_IS_SOLARIS) 2337 ev_ssize_t res; 2338 off_t offset = chain->misalign; 2339 #endif 2340 2341 ASSERT_EVBUFFER_LOCKED(buffer); 2342 2343 #if defined(SENDFILE_IS_MACOSX) 2344 res = sendfile(info->fd, fd, chain->misalign, &len, NULL, 0); 2345 if (res == -1 && !EVUTIL_ERR_RW_RETRIABLE(errno)) 2346 return (-1); 2347 2348 return (len); 2349 #elif defined(SENDFILE_IS_FREEBSD) 2350 res = sendfile(info->fd, fd, chain->misalign, chain->off, NULL, &len, 0); 2351 if (res == -1 && !EVUTIL_ERR_RW_RETRIABLE(errno)) 2352 return (-1); 2353 2354 return (len); 2355 #elif defined(SENDFILE_IS_LINUX) 2356 /* TODO(niels): implement splice */ 2357 res = sendfile(fd, info->fd, &offset, chain->off); 2358 if (res == -1 && EVUTIL_ERR_RW_RETRIABLE(errno)) { 2359 /* if this is EAGAIN or EINTR return 0; otherwise, -1 */ 2360 return (0); 2361 } 2362 return (res); 2363 #elif defined(SENDFILE_IS_SOLARIS) 2364 { 2365 const off_t offset_orig = offset; 2366 res = sendfile(fd, info->fd, &offset, chain->off); 2367 if (res == -1 && EVUTIL_ERR_RW_RETRIABLE(errno)) { 2368 if (offset - offset_orig) 2369 return offset - offset_orig; 2370 /* if this is EAGAIN or EINTR and no bytes were 2371 * written, return 0 */ 2372 return (0); 2373 } 2374 return (res); 2375 } 2376 #endif 2377 } 2378 #endif 2379 2380 int 2381 evbuffer_write_atmost(struct evbuffer *buffer, evutil_socket_t fd, 2382 ev_ssize_t howmuch) 2383 { 2384 int n = -1; 2385 2386 EVBUFFER_LOCK(buffer); 2387 2388 if (buffer->freeze_start) { 2389 goto done; 2390 } 2391 2392 if (howmuch < 0 || (size_t)howmuch > buffer->total_len) 2393 howmuch = buffer->total_len; 2394 2395 if (howmuch > 0) { 2396 #ifdef USE_SENDFILE 2397 struct evbuffer_chain *chain = buffer->first; 2398 if (chain != NULL && (chain->flags & EVBUFFER_SENDFILE)) 2399 n = evbuffer_write_sendfile(buffer, fd, howmuch); 2400 else { 2401 #endif 2402 #ifdef USE_IOVEC_IMPL 2403 n = evbuffer_write_iovec(buffer, fd, howmuch); 2404 #elif defined(WIN32) 2405 /* XXX(nickm) Don't disable this code until we know if 2406 * the WSARecv code above works. */ 2407 void *p = evbuffer_pullup(buffer, howmuch); 2408 EVUTIL_ASSERT(p || !howmuch); 2409 n = send(fd, p, howmuch, 0); 2410 #else 2411 void *p = evbuffer_pullup(buffer, howmuch); 2412 EVUTIL_ASSERT(p || !howmuch); 2413 n = write(fd, p, howmuch); 2414 #endif 2415 #ifdef USE_SENDFILE 2416 } 2417 #endif 2418 } 2419 2420 if (n > 0) 2421 evbuffer_drain(buffer, n); 2422 2423 done: 2424 EVBUFFER_UNLOCK(buffer); 2425 return (n); 2426 } 2427 2428 int 2429 evbuffer_write(struct evbuffer *buffer, evutil_socket_t fd) 2430 { 2431 return evbuffer_write_atmost(buffer, fd, -1); 2432 } 2433 2434 unsigned char * 2435 evbuffer_find(struct evbuffer *buffer, const unsigned char *what, size_t len) 2436 { 2437 unsigned char *search; 2438 struct evbuffer_ptr ptr; 2439 2440 EVBUFFER_LOCK(buffer); 2441 2442 ptr = evbuffer_search(buffer, (const char *)what, len, NULL); 2443 if (ptr.pos < 0) { 2444 search = NULL; 2445 } else { 2446 search = evbuffer_pullup(buffer, ptr.pos + len); 2447 if (search) 2448 search += ptr.pos; 2449 } 2450 EVBUFFER_UNLOCK(buffer); 2451 return search; 2452 } 2453 2454 int 2455 evbuffer_ptr_set(struct evbuffer *buf, struct evbuffer_ptr *pos, 2456 size_t position, enum evbuffer_ptr_how how) 2457 { 2458 size_t left = position; 2459 struct evbuffer_chain *chain = NULL; 2460 2461 EVBUFFER_LOCK(buf); 2462 2463 switch (how) { 2464 case EVBUFFER_PTR_SET: 2465 chain = buf->first; 2466 pos->pos = position; 2467 position = 0; 2468 break; 2469 case EVBUFFER_PTR_ADD: 2470 /* this avoids iterating over all previous chains if 2471 we just want to advance the position */ 2472 if (pos->pos < 0 || EV_SIZE_MAX - position < (size_t)pos->pos) { 2473 EVBUFFER_UNLOCK(buf); 2474 return -1; 2475 } 2476 chain = pos->_internal.chain; 2477 pos->pos += position; 2478 position = pos->_internal.pos_in_chain; 2479 break; 2480 } 2481 2482 EVUTIL_ASSERT(EV_SIZE_MAX - left >= position); 2483 while (chain && position + left >= chain->off) { 2484 left -= chain->off - position; 2485 chain = chain->next; 2486 position = 0; 2487 } 2488 if (chain) { 2489 pos->_internal.chain = chain; 2490 pos->_internal.pos_in_chain = position + left; 2491 } else { 2492 pos->_internal.chain = NULL; 2493 pos->pos = -1; 2494 } 2495 2496 EVBUFFER_UNLOCK(buf); 2497 2498 return chain != NULL ? 0 : -1; 2499 } 2500 2501 /** 2502 Compare the bytes in buf at position pos to the len bytes in mem. Return 2503 less than 0, 0, or greater than 0 as memcmp. 2504 */ 2505 static int 2506 evbuffer_ptr_memcmp(const struct evbuffer *buf, const struct evbuffer_ptr *pos, 2507 const char *mem, size_t len) 2508 { 2509 struct evbuffer_chain *chain; 2510 size_t position; 2511 int r; 2512 2513 ASSERT_EVBUFFER_LOCKED(buf); 2514 2515 if (pos->pos < 0 || 2516 EV_SIZE_MAX - len < (size_t)pos->pos || 2517 pos->pos + len > buf->total_len) 2518 return -1; 2519 2520 chain = pos->_internal.chain; 2521 position = pos->_internal.pos_in_chain; 2522 while (len && chain) { 2523 size_t n_comparable; 2524 if (len + position > chain->off) 2525 n_comparable = chain->off - position; 2526 else 2527 n_comparable = len; 2528 r = memcmp(chain->buffer + chain->misalign + position, mem, 2529 n_comparable); 2530 if (r) 2531 return r; 2532 mem += n_comparable; 2533 len -= n_comparable; 2534 position = 0; 2535 chain = chain->next; 2536 } 2537 2538 return 0; 2539 } 2540 2541 struct evbuffer_ptr 2542 evbuffer_search(struct evbuffer *buffer, const char *what, size_t len, const struct evbuffer_ptr *start) 2543 { 2544 return evbuffer_search_range(buffer, what, len, start, NULL); 2545 } 2546 2547 struct evbuffer_ptr 2548 evbuffer_search_range(struct evbuffer *buffer, const char *what, size_t len, const struct evbuffer_ptr *start, const struct evbuffer_ptr *end) 2549 { 2550 struct evbuffer_ptr pos; 2551 struct evbuffer_chain *chain, *last_chain = NULL; 2552 const unsigned char *p; 2553 char first; 2554 2555 EVBUFFER_LOCK(buffer); 2556 2557 if (start) { 2558 memcpy(&pos, start, sizeof(pos)); 2559 chain = pos._internal.chain; 2560 } else { 2561 pos.pos = 0; 2562 chain = pos._internal.chain = buffer->first; 2563 pos._internal.pos_in_chain = 0; 2564 } 2565 2566 if (end) 2567 last_chain = end->_internal.chain; 2568 2569 if (!len || len > EV_SSIZE_MAX) 2570 goto done; 2571 2572 first = what[0]; 2573 2574 while (chain) { 2575 const unsigned char *start_at = 2576 chain->buffer + chain->misalign + 2577 pos._internal.pos_in_chain; 2578 p = memchr(start_at, first, 2579 chain->off - pos._internal.pos_in_chain); 2580 if (p) { 2581 pos.pos += p - start_at; 2582 pos._internal.pos_in_chain += p - start_at; 2583 if (!evbuffer_ptr_memcmp(buffer, &pos, what, len)) { 2584 if (end && pos.pos + (ev_ssize_t)len > end->pos) 2585 goto not_found; 2586 else 2587 goto done; 2588 } 2589 ++pos.pos; 2590 ++pos._internal.pos_in_chain; 2591 if (pos._internal.pos_in_chain == chain->off) { 2592 chain = pos._internal.chain = chain->next; 2593 pos._internal.pos_in_chain = 0; 2594 } 2595 } else { 2596 if (chain == last_chain) 2597 goto not_found; 2598 pos.pos += chain->off - pos._internal.pos_in_chain; 2599 chain = pos._internal.chain = chain->next; 2600 pos._internal.pos_in_chain = 0; 2601 } 2602 } 2603 2604 not_found: 2605 pos.pos = -1; 2606 pos._internal.chain = NULL; 2607 done: 2608 EVBUFFER_UNLOCK(buffer); 2609 return pos; 2610 } 2611 2612 int 2613 evbuffer_peek(struct evbuffer *buffer, ev_ssize_t len, 2614 struct evbuffer_ptr *start_at, 2615 struct evbuffer_iovec *vec, int n_vec) 2616 { 2617 struct evbuffer_chain *chain; 2618 int idx = 0; 2619 ev_ssize_t len_so_far = 0; 2620 2621 EVBUFFER_LOCK(buffer); 2622 2623 if (start_at) { 2624 chain = start_at->_internal.chain; 2625 len_so_far = chain->off 2626 - start_at->_internal.pos_in_chain; 2627 idx = 1; 2628 if (n_vec > 0) { 2629 vec[0].iov_base = chain->buffer + chain->misalign 2630 + start_at->_internal.pos_in_chain; 2631 vec[0].iov_len = len_so_far; 2632 } 2633 chain = chain->next; 2634 } else { 2635 chain = buffer->first; 2636 } 2637 2638 if (n_vec == 0 && len < 0) { 2639 /* If no vectors are provided and they asked for "everything", 2640 * pretend they asked for the actual available amount. */ 2641 len = buffer->total_len; 2642 if (start_at) { 2643 len -= start_at->pos; 2644 } 2645 } 2646 2647 while (chain) { 2648 if (len >= 0 && len_so_far >= len) 2649 break; 2650 if (idx<n_vec) { 2651 vec[idx].iov_base = chain->buffer + chain->misalign; 2652 vec[idx].iov_len = chain->off; 2653 } else if (len<0) { 2654 break; 2655 } 2656 ++idx; 2657 len_so_far += chain->off; 2658 chain = chain->next; 2659 } 2660 2661 EVBUFFER_UNLOCK(buffer); 2662 2663 return idx; 2664 } 2665 2666 2667 int 2668 evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap) 2669 { 2670 char *buffer; 2671 size_t space; 2672 int sz, result = -1; 2673 va_list aq; 2674 struct evbuffer_chain *chain; 2675 2676 2677 EVBUFFER_LOCK(buf); 2678 2679 if (buf->freeze_end) { 2680 goto done; 2681 } 2682 2683 /* make sure that at least some space is available */ 2684 if ((chain = evbuffer_expand_singlechain(buf, 64)) == NULL) 2685 goto done; 2686 2687 for (;;) { 2688 #if 0 2689 size_t used = chain->misalign + chain->off; 2690 buffer = (char *)chain->buffer + chain->misalign + chain->off; 2691 EVUTIL_ASSERT(chain->buffer_len >= used); 2692 space = chain->buffer_len - used; 2693 #endif 2694 buffer = (char*) CHAIN_SPACE_PTR(chain); 2695 space = (size_t) CHAIN_SPACE_LEN(chain); 2696 2697 #ifndef va_copy 2698 #define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list)) 2699 #endif 2700 va_copy(aq, ap); 2701 2702 sz = evutil_vsnprintf(buffer, space, fmt, aq); 2703 2704 va_end(aq); 2705 2706 if (sz < 0) 2707 goto done; 2708 if (INT_MAX >= EVBUFFER_CHAIN_MAX && 2709 (size_t)sz >= EVBUFFER_CHAIN_MAX) 2710 goto done; 2711 if ((size_t)sz < space) { 2712 chain->off += sz; 2713 buf->total_len += sz; 2714 buf->n_add_for_cb += sz; 2715 2716 advance_last_with_data(buf); 2717 evbuffer_invoke_callbacks(buf); 2718 result = sz; 2719 goto done; 2720 } 2721 if ((chain = evbuffer_expand_singlechain(buf, sz + 1)) == NULL) 2722 goto done; 2723 } 2724 /* NOTREACHED */ 2725 2726 done: 2727 EVBUFFER_UNLOCK(buf); 2728 return result; 2729 } 2730 2731 int 2732 evbuffer_add_printf(struct evbuffer *buf, const char *fmt, ...) 2733 { 2734 int res = -1; 2735 va_list ap; 2736 2737 va_start(ap, fmt); 2738 res = evbuffer_add_vprintf(buf, fmt, ap); 2739 va_end(ap); 2740 2741 return (res); 2742 } 2743 2744 int 2745 evbuffer_add_reference(struct evbuffer *outbuf, 2746 const void *data, size_t datlen, 2747 evbuffer_ref_cleanup_cb cleanupfn, void *extra) 2748 { 2749 struct evbuffer_chain *chain; 2750 struct evbuffer_chain_reference *info; 2751 int result = -1; 2752 2753 chain = evbuffer_chain_new(sizeof(struct evbuffer_chain_reference)); 2754 if (!chain) 2755 return (-1); 2756 chain->flags |= EVBUFFER_REFERENCE | EVBUFFER_IMMUTABLE; 2757 chain->buffer = __UNCONST(data); 2758 chain->buffer_len = datlen; 2759 chain->off = datlen; 2760 2761 info = EVBUFFER_CHAIN_EXTRA(struct evbuffer_chain_reference, chain); 2762 info->cleanupfn = cleanupfn; 2763 info->extra = extra; 2764 2765 EVBUFFER_LOCK(outbuf); 2766 if (outbuf->freeze_end) { 2767 /* don't call chain_free; we do not want to actually invoke 2768 * the cleanup function */ 2769 mm_free(chain); 2770 goto done; 2771 } 2772 evbuffer_chain_insert(outbuf, chain); 2773 outbuf->n_add_for_cb += datlen; 2774 2775 evbuffer_invoke_callbacks(outbuf); 2776 2777 result = 0; 2778 done: 2779 EVBUFFER_UNLOCK(outbuf); 2780 2781 return result; 2782 } 2783 2784 /* TODO(niels): maybe we don't want to own the fd, however, in that 2785 * case, we should dup it - dup is cheap. Perhaps, we should use a 2786 * callback instead? 2787 */ 2788 /* TODO(niels): we may want to add to automagically convert to mmap, in 2789 * case evbuffer_remove() or evbuffer_pullup() are being used. 2790 */ 2791 int 2792 evbuffer_add_file(struct evbuffer *outbuf, int fd, 2793 ev_off_t offset, ev_off_t length) 2794 { 2795 #if defined(USE_SENDFILE) || defined(_EVENT_HAVE_MMAP) 2796 struct evbuffer_chain *chain; 2797 struct evbuffer_chain_fd *info; 2798 #endif 2799 #if defined(USE_SENDFILE) 2800 int sendfile_okay = 1; 2801 #endif 2802 int ok = 1; 2803 2804 if (offset < 0 || length < 0 || 2805 ((ev_uint64_t)length > EVBUFFER_CHAIN_MAX) || 2806 (ev_uint64_t)offset > (ev_uint64_t)(EVBUFFER_CHAIN_MAX - length)) 2807 return (-1); 2808 2809 #if defined(USE_SENDFILE) 2810 if (use_sendfile) { 2811 EVBUFFER_LOCK(outbuf); 2812 sendfile_okay = outbuf->flags & EVBUFFER_FLAG_DRAINS_TO_FD; 2813 EVBUFFER_UNLOCK(outbuf); 2814 } 2815 2816 if (use_sendfile && sendfile_okay) { 2817 chain = evbuffer_chain_new(sizeof(struct evbuffer_chain_fd)); 2818 if (chain == NULL) { 2819 event_warn("%s: out of memory", __func__); 2820 return (-1); 2821 } 2822 2823 chain->flags |= EVBUFFER_SENDFILE | EVBUFFER_IMMUTABLE; 2824 chain->buffer = NULL; /* no reading possible */ 2825 chain->buffer_len = length + offset; 2826 chain->off = length; 2827 chain->misalign = offset; 2828 2829 info = EVBUFFER_CHAIN_EXTRA(struct evbuffer_chain_fd, chain); 2830 info->fd = fd; 2831 2832 EVBUFFER_LOCK(outbuf); 2833 if (outbuf->freeze_end) { 2834 mm_free(chain); 2835 ok = 0; 2836 } else { 2837 outbuf->n_add_for_cb += length; 2838 evbuffer_chain_insert(outbuf, chain); 2839 } 2840 } else 2841 #endif 2842 #if defined(_EVENT_HAVE_MMAP) 2843 if (use_mmap) { 2844 void *mapped = mmap(NULL, length + offset, PROT_READ, 2845 #ifdef MAP_NOCACHE 2846 MAP_NOCACHE | 2847 #endif 2848 #ifdef MAP_FILE 2849 MAP_FILE | 2850 #endif 2851 MAP_PRIVATE, 2852 fd, 0); 2853 /* some mmap implementations require offset to be a multiple of 2854 * the page size. most users of this api, are likely to use 0 2855 * so mapping everything is not likely to be a problem. 2856 * TODO(niels): determine page size and round offset to that 2857 * page size to avoid mapping too much memory. 2858 */ 2859 if (mapped == MAP_FAILED) { 2860 event_warn("%s: mmap(%d, %d, %zu) failed", 2861 __func__, fd, 0, (size_t)(offset + length)); 2862 return (-1); 2863 } 2864 chain = evbuffer_chain_new(sizeof(struct evbuffer_chain_fd)); 2865 if (chain == NULL) { 2866 event_warn("%s: out of memory", __func__); 2867 munmap(mapped, length); 2868 return (-1); 2869 } 2870 2871 chain->flags |= EVBUFFER_MMAP | EVBUFFER_IMMUTABLE; 2872 chain->buffer = mapped; 2873 chain->buffer_len = length + offset; 2874 chain->off = length + offset; 2875 2876 info = EVBUFFER_CHAIN_EXTRA(struct evbuffer_chain_fd, chain); 2877 info->fd = fd; 2878 2879 EVBUFFER_LOCK(outbuf); 2880 if (outbuf->freeze_end) { 2881 info->fd = -1; 2882 evbuffer_chain_free(chain); 2883 ok = 0; 2884 } else { 2885 outbuf->n_add_for_cb += length; 2886 2887 evbuffer_chain_insert(outbuf, chain); 2888 2889 /* we need to subtract whatever we don't need */ 2890 evbuffer_drain(outbuf, offset); 2891 } 2892 } else 2893 #endif 2894 { 2895 /* the default implementation */ 2896 struct evbuffer *tmp = evbuffer_new(); 2897 ev_ssize_t read; 2898 2899 if (tmp == NULL) 2900 return (-1); 2901 2902 #ifdef WIN32 2903 #define lseek _lseeki64 2904 #endif 2905 if (lseek(fd, offset, SEEK_SET) == -1) { 2906 evbuffer_free(tmp); 2907 return (-1); 2908 } 2909 2910 /* we add everything to a temporary buffer, so that we 2911 * can abort without side effects if the read fails. 2912 */ 2913 while (length) { 2914 ev_ssize_t to_read = length > EV_SSIZE_MAX ? EV_SSIZE_MAX : (ev_ssize_t)length; 2915 read = evbuffer_readfile(tmp, fd, to_read); 2916 if (read == -1) { 2917 evbuffer_free(tmp); 2918 return (-1); 2919 } 2920 2921 length -= read; 2922 } 2923 2924 EVBUFFER_LOCK(outbuf); 2925 if (outbuf->freeze_end) { 2926 evbuffer_free(tmp); 2927 ok = 0; 2928 } else { 2929 evbuffer_add_buffer(outbuf, tmp); 2930 evbuffer_free(tmp); 2931 2932 #ifdef WIN32 2933 #define close _close 2934 #endif 2935 close(fd); 2936 } 2937 } 2938 2939 if (ok) 2940 evbuffer_invoke_callbacks(outbuf); 2941 EVBUFFER_UNLOCK(outbuf); 2942 2943 return ok ? 0 : -1; 2944 } 2945 2946 2947 void 2948 evbuffer_setcb(struct evbuffer *buffer, evbuffer_cb cb, void *cbarg) 2949 { 2950 EVBUFFER_LOCK(buffer); 2951 2952 if (!TAILQ_EMPTY(&buffer->callbacks)) 2953 evbuffer_remove_all_callbacks(buffer); 2954 2955 if (cb) { 2956 struct evbuffer_cb_entry *ent = 2957 evbuffer_add_cb(buffer, NULL, cbarg); 2958 ent->cb.cb_obsolete = cb; 2959 ent->flags |= EVBUFFER_CB_OBSOLETE; 2960 } 2961 EVBUFFER_UNLOCK(buffer); 2962 } 2963 2964 struct evbuffer_cb_entry * 2965 evbuffer_add_cb(struct evbuffer *buffer, evbuffer_cb_func cb, void *cbarg) 2966 { 2967 struct evbuffer_cb_entry *e; 2968 if (! (e = mm_calloc(1, sizeof(struct evbuffer_cb_entry)))) 2969 return NULL; 2970 EVBUFFER_LOCK(buffer); 2971 e->cb.cb_func = cb; 2972 e->cbarg = cbarg; 2973 e->flags = EVBUFFER_CB_ENABLED; 2974 TAILQ_INSERT_HEAD(&buffer->callbacks, e, next); 2975 EVBUFFER_UNLOCK(buffer); 2976 return e; 2977 } 2978 2979 int 2980 evbuffer_remove_cb_entry(struct evbuffer *buffer, 2981 struct evbuffer_cb_entry *ent) 2982 { 2983 EVBUFFER_LOCK(buffer); 2984 TAILQ_REMOVE(&buffer->callbacks, ent, next); 2985 EVBUFFER_UNLOCK(buffer); 2986 mm_free(ent); 2987 return 0; 2988 } 2989 2990 int 2991 evbuffer_remove_cb(struct evbuffer *buffer, evbuffer_cb_func cb, void *cbarg) 2992 { 2993 struct evbuffer_cb_entry *cbent; 2994 int result = -1; 2995 EVBUFFER_LOCK(buffer); 2996 TAILQ_FOREACH(cbent, &buffer->callbacks, next) { 2997 if (cb == cbent->cb.cb_func && cbarg == cbent->cbarg) { 2998 result = evbuffer_remove_cb_entry(buffer, cbent); 2999 goto done; 3000 } 3001 } 3002 done: 3003 EVBUFFER_UNLOCK(buffer); 3004 return result; 3005 } 3006 3007 int 3008 evbuffer_cb_set_flags(struct evbuffer *buffer, 3009 struct evbuffer_cb_entry *cb, ev_uint32_t flags) 3010 { 3011 /* the user isn't allowed to mess with these. */ 3012 flags &= ~EVBUFFER_CB_INTERNAL_FLAGS; 3013 EVBUFFER_LOCK(buffer); 3014 cb->flags |= flags; 3015 EVBUFFER_UNLOCK(buffer); 3016 return 0; 3017 } 3018 3019 int 3020 evbuffer_cb_clear_flags(struct evbuffer *buffer, 3021 struct evbuffer_cb_entry *cb, ev_uint32_t flags) 3022 { 3023 /* the user isn't allowed to mess with these. */ 3024 flags &= ~EVBUFFER_CB_INTERNAL_FLAGS; 3025 EVBUFFER_LOCK(buffer); 3026 cb->flags &= ~flags; 3027 EVBUFFER_UNLOCK(buffer); 3028 return 0; 3029 } 3030 3031 int 3032 evbuffer_freeze(struct evbuffer *buffer, int start) 3033 { 3034 EVBUFFER_LOCK(buffer); 3035 if (start) 3036 buffer->freeze_start = 1; 3037 else 3038 buffer->freeze_end = 1; 3039 EVBUFFER_UNLOCK(buffer); 3040 return 0; 3041 } 3042 3043 int 3044 evbuffer_unfreeze(struct evbuffer *buffer, int start) 3045 { 3046 EVBUFFER_LOCK(buffer); 3047 if (start) 3048 buffer->freeze_start = 0; 3049 else 3050 buffer->freeze_end = 0; 3051 EVBUFFER_UNLOCK(buffer); 3052 return 0; 3053 } 3054 3055 #if 0 3056 void 3057 evbuffer_cb_suspend(struct evbuffer *buffer, struct evbuffer_cb_entry *cb) 3058 { 3059 if (!(cb->flags & EVBUFFER_CB_SUSPENDED)) { 3060 cb->size_before_suspend = evbuffer_get_length(buffer); 3061 cb->flags |= EVBUFFER_CB_SUSPENDED; 3062 } 3063 } 3064 3065 void 3066 evbuffer_cb_unsuspend(struct evbuffer *buffer, struct evbuffer_cb_entry *cb) 3067 { 3068 if ((cb->flags & EVBUFFER_CB_SUSPENDED)) { 3069 unsigned call = (cb->flags & EVBUFFER_CB_CALL_ON_UNSUSPEND); 3070 size_t sz = cb->size_before_suspend; 3071 cb->flags &= ~(EVBUFFER_CB_SUSPENDED| 3072 EVBUFFER_CB_CALL_ON_UNSUSPEND); 3073 cb->size_before_suspend = 0; 3074 if (call && (cb->flags & EVBUFFER_CB_ENABLED)) { 3075 cb->cb(buffer, sz, evbuffer_get_length(buffer), cb->cbarg); 3076 } 3077 } 3078 } 3079 #endif 3080 3081 /* These hooks are exposed so that the unit tests can temporarily disable 3082 * sendfile support in order to test mmap, or both to test linear 3083 * access. Don't use it; if we need to add a way to disable sendfile support 3084 * in the future, it will probably be via an alternate version of 3085 * evbuffer_add_file() with a 'flags' argument. 3086 */ 3087 int _evbuffer_testing_use_sendfile(void); 3088 int _evbuffer_testing_use_mmap(void); 3089 int _evbuffer_testing_use_linear_file_access(void); 3090 3091 int 3092 _evbuffer_testing_use_sendfile(void) 3093 { 3094 int ok = 0; 3095 #ifdef USE_SENDFILE 3096 use_sendfile = 1; 3097 ok = 1; 3098 #endif 3099 #ifdef _EVENT_HAVE_MMAP 3100 use_mmap = 0; 3101 #endif 3102 return ok; 3103 } 3104 int 3105 _evbuffer_testing_use_mmap(void) 3106 { 3107 int ok = 0; 3108 #ifdef USE_SENDFILE 3109 use_sendfile = 0; 3110 #endif 3111 #ifdef _EVENT_HAVE_MMAP 3112 use_mmap = 1; 3113 ok = 1; 3114 #endif 3115 return ok; 3116 } 3117 int 3118 _evbuffer_testing_use_linear_file_access(void) 3119 { 3120 #ifdef USE_SENDFILE 3121 use_sendfile = 0; 3122 #endif 3123 #ifdef _EVENT_HAVE_MMAP 3124 use_mmap = 0; 3125 #endif 3126 return 1; 3127 } 3128