1 /* $OpenBSD: buffer.c,v 1.19 2010/07/17 17:16:47 chl Exp $ */ 2 3 /* 4 * Copyright (c) 2002, 2003 Niels Provos <provos@citi.umich.edu> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #ifdef HAVE_CONFIG_H 31 #include "config.h" 32 #endif 33 34 #ifdef WIN32 35 #include <winsock2.h> 36 #include <windows.h> 37 #endif 38 39 #ifdef 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 HAVE_SYS_TIME_H 47 #include <sys/time.h> 48 #endif 49 50 #ifdef HAVE_SYS_IOCTL_H 51 #include <sys/ioctl.h> 52 #endif 53 54 #include <assert.h> 55 #include <errno.h> 56 #include <stdio.h> 57 #include <stdlib.h> 58 #include <string.h> 59 #ifdef HAVE_STDARG_H 60 #include <stdarg.h> 61 #endif 62 #ifdef HAVE_UNISTD_H 63 #include <unistd.h> 64 #endif 65 66 #include "event.h" 67 #include "evutil.h" 68 #include "./log.h" 69 70 struct evbuffer * 71 evbuffer_new(void) 72 { 73 struct evbuffer *buffer; 74 75 buffer = calloc(1, sizeof(struct evbuffer)); 76 77 return (buffer); 78 } 79 80 void 81 evbuffer_free(struct evbuffer *buffer) 82 { 83 if (buffer->orig_buffer != NULL) 84 free(buffer->orig_buffer); 85 free(buffer); 86 } 87 88 /* 89 * This is a destructive add. The data from one buffer moves into 90 * the other buffer. 91 */ 92 93 #define SWAP(x,y) do { \ 94 (x)->buffer = (y)->buffer; \ 95 (x)->orig_buffer = (y)->orig_buffer; \ 96 (x)->misalign = (y)->misalign; \ 97 (x)->totallen = (y)->totallen; \ 98 (x)->off = (y)->off; \ 99 } while (0) 100 101 int 102 evbuffer_add_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf) 103 { 104 int res; 105 106 /* Short cut for better performance */ 107 if (outbuf->off == 0) { 108 struct evbuffer tmp; 109 size_t oldoff = inbuf->off; 110 111 /* Swap them directly */ 112 SWAP(&tmp, outbuf); 113 SWAP(outbuf, inbuf); 114 SWAP(inbuf, &tmp); 115 116 /* 117 * Optimization comes with a price; we need to notify the 118 * buffer if necessary of the changes. oldoff is the amount 119 * of data that we transferred from inbuf to outbuf 120 */ 121 if (inbuf->off != oldoff && inbuf->cb != NULL) 122 (*inbuf->cb)(inbuf, oldoff, inbuf->off, inbuf->cbarg); 123 if (oldoff && outbuf->cb != NULL) 124 (*outbuf->cb)(outbuf, 0, oldoff, outbuf->cbarg); 125 126 return (0); 127 } 128 129 res = evbuffer_add(outbuf, inbuf->buffer, inbuf->off); 130 if (res == 0) { 131 /* We drain the input buffer on success */ 132 evbuffer_drain(inbuf, inbuf->off); 133 } 134 135 return (res); 136 } 137 138 int 139 evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap) 140 { 141 char *buffer; 142 size_t space; 143 size_t oldoff = buf->off; 144 int sz; 145 va_list aq; 146 147 /* make sure that at least some space is available */ 148 evbuffer_expand(buf, 64); 149 for (;;) { 150 size_t used = buf->misalign + buf->off; 151 buffer = (char *)buf->buffer + buf->off; 152 assert(buf->totallen >= used); 153 space = buf->totallen - used; 154 155 #ifndef va_copy 156 #define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list)) 157 #endif 158 va_copy(aq, ap); 159 160 sz = evutil_vsnprintf(buffer, space, fmt, aq); 161 162 va_end(aq); 163 164 if (sz < 0) 165 return (-1); 166 if ((size_t)sz < space) { 167 buf->off += sz; 168 if (buf->cb != NULL) 169 (*buf->cb)(buf, oldoff, buf->off, buf->cbarg); 170 return (sz); 171 } 172 if (evbuffer_expand(buf, sz + 1) == -1) 173 return (-1); 174 175 } 176 /* NOTREACHED */ 177 } 178 179 int 180 evbuffer_add_printf(struct evbuffer *buf, const char *fmt, ...) 181 { 182 int res = -1; 183 va_list ap; 184 185 va_start(ap, fmt); 186 res = evbuffer_add_vprintf(buf, fmt, ap); 187 va_end(ap); 188 189 return (res); 190 } 191 192 /* Reads data from an event buffer and drains the bytes read */ 193 194 int 195 evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen) 196 { 197 size_t nread = datlen; 198 if (nread >= buf->off) 199 nread = buf->off; 200 201 memcpy(data, buf->buffer, nread); 202 evbuffer_drain(buf, nread); 203 204 return (nread); 205 } 206 207 /* 208 * Reads a line terminated by either '\r\n', '\n\r' or '\r' or '\n'. 209 * The returned buffer needs to be freed by the called. 210 */ 211 212 char * 213 evbuffer_readline(struct evbuffer *buffer) 214 { 215 u_char *data = EVBUFFER_DATA(buffer); 216 size_t len = EVBUFFER_LENGTH(buffer); 217 char *line; 218 unsigned int i; 219 220 for (i = 0; i < len; i++) { 221 if (data[i] == '\r' || data[i] == '\n') 222 break; 223 } 224 225 if (i == len) 226 return (NULL); 227 228 if ((line = malloc(i + 1)) == NULL) { 229 fprintf(stderr, "%s: out of memory\n", __func__); 230 return (NULL); 231 } 232 233 memcpy(line, data, i); 234 line[i] = '\0'; 235 236 /* 237 * Some protocols terminate a line with '\r\n', so check for 238 * that, too. 239 */ 240 if ( i < len - 1 ) { 241 char fch = data[i], sch = data[i+1]; 242 243 /* Drain one more character if needed */ 244 if ( (sch == '\r' || sch == '\n') && sch != fch ) 245 i += 1; 246 } 247 248 evbuffer_drain(buffer, i + 1); 249 250 return (line); 251 } 252 253 254 char * 255 evbuffer_readln(struct evbuffer *buffer, size_t *n_read_out, 256 enum evbuffer_eol_style eol_style) 257 { 258 u_char *data = EVBUFFER_DATA(buffer); 259 u_char *start_of_eol, *end_of_eol; 260 size_t len = EVBUFFER_LENGTH(buffer); 261 char *line; 262 unsigned int i, n_to_copy, n_to_drain; 263 264 if (n_read_out) 265 *n_read_out = 0; 266 267 /* depending on eol_style, set start_of_eol to the first character 268 * in the newline, and end_of_eol to one after the last character. */ 269 switch (eol_style) { 270 case EVBUFFER_EOL_ANY: 271 for (i = 0; i < len; i++) { 272 if (data[i] == '\r' || data[i] == '\n') 273 break; 274 } 275 if (i == len) 276 return (NULL); 277 start_of_eol = data+i; 278 ++i; 279 for ( ; i < len; i++) { 280 if (data[i] != '\r' && data[i] != '\n') 281 break; 282 } 283 end_of_eol = data+i; 284 break; 285 case EVBUFFER_EOL_CRLF: 286 end_of_eol = memchr(data, '\n', len); 287 if (!end_of_eol) 288 return (NULL); 289 if (end_of_eol > data && *(end_of_eol-1) == '\r') 290 start_of_eol = end_of_eol - 1; 291 else 292 start_of_eol = end_of_eol; 293 end_of_eol++; /*point to one after the LF. */ 294 break; 295 case EVBUFFER_EOL_CRLF_STRICT: { 296 u_char *cp = data; 297 while ((cp = memchr(cp, '\r', len-(cp-data)))) { 298 if (cp < data+len-1 && *(cp+1) == '\n') 299 break; 300 if (++cp >= data+len) { 301 cp = NULL; 302 break; 303 } 304 } 305 if (!cp) 306 return (NULL); 307 start_of_eol = cp; 308 end_of_eol = cp+2; 309 break; 310 } 311 case EVBUFFER_EOL_LF: 312 start_of_eol = memchr(data, '\n', len); 313 if (!start_of_eol) 314 return (NULL); 315 end_of_eol = start_of_eol + 1; 316 break; 317 default: 318 return (NULL); 319 } 320 321 n_to_copy = start_of_eol - data; 322 n_to_drain = end_of_eol - data; 323 324 if ((line = malloc(n_to_copy+1)) == NULL) { 325 event_warn("%s: out of memory\n", __func__); 326 return (NULL); 327 } 328 329 memcpy(line, data, n_to_copy); 330 line[n_to_copy] = '\0'; 331 332 evbuffer_drain(buffer, n_to_drain); 333 if (n_read_out) 334 *n_read_out = (size_t)n_to_copy; 335 336 return (line); 337 } 338 339 /* Adds data to an event buffer */ 340 341 static void 342 evbuffer_align(struct evbuffer *buf) 343 { 344 memmove(buf->orig_buffer, buf->buffer, buf->off); 345 buf->buffer = buf->orig_buffer; 346 buf->misalign = 0; 347 } 348 349 /* Expands the available space in the event buffer to at least datlen */ 350 351 int 352 evbuffer_expand(struct evbuffer *buf, size_t datlen) 353 { 354 size_t need = buf->misalign + buf->off + datlen; 355 356 /* If we can fit all the data, then we don't have to do anything */ 357 if (buf->totallen >= need) 358 return (0); 359 360 /* 361 * If the misalignment fulfills our data needs, we just force an 362 * alignment to happen. Afterwards, we have enough space. 363 */ 364 if (buf->misalign >= datlen) { 365 evbuffer_align(buf); 366 } else { 367 void *newbuf; 368 size_t length = buf->totallen; 369 370 if (length < 256) 371 length = 256; 372 while (length < need) 373 length <<= 1; 374 375 if (buf->orig_buffer != buf->buffer) 376 evbuffer_align(buf); 377 if ((newbuf = realloc(buf->buffer, length)) == NULL) 378 return (-1); 379 380 buf->orig_buffer = buf->buffer = newbuf; 381 buf->totallen = length; 382 } 383 384 return (0); 385 } 386 387 int 388 evbuffer_add(struct evbuffer *buf, const void *data, size_t datlen) 389 { 390 size_t need = buf->misalign + buf->off + datlen; 391 size_t oldoff = buf->off; 392 393 if (buf->totallen < need) { 394 if (evbuffer_expand(buf, datlen) == -1) 395 return (-1); 396 } 397 398 memcpy(buf->buffer + buf->off, data, datlen); 399 buf->off += datlen; 400 401 if (datlen && buf->cb != NULL) 402 (*buf->cb)(buf, oldoff, buf->off, buf->cbarg); 403 404 return (0); 405 } 406 407 void 408 evbuffer_drain(struct evbuffer *buf, size_t len) 409 { 410 size_t oldoff = buf->off; 411 412 if (len >= buf->off) { 413 buf->off = 0; 414 buf->buffer = buf->orig_buffer; 415 buf->misalign = 0; 416 goto done; 417 } 418 419 buf->buffer += len; 420 buf->misalign += len; 421 422 buf->off -= len; 423 424 done: 425 /* Tell someone about changes in this buffer */ 426 if (buf->off != oldoff && buf->cb != NULL) 427 (*buf->cb)(buf, oldoff, buf->off, buf->cbarg); 428 429 } 430 431 /* 432 * Reads data from a file descriptor into a buffer. 433 */ 434 435 #define EVBUFFER_MAX_READ 4096 436 437 int 438 evbuffer_read(struct evbuffer *buf, int fd, int howmuch) 439 { 440 u_char *p; 441 size_t oldoff = buf->off; 442 int n = EVBUFFER_MAX_READ; 443 444 #if defined(FIONREAD) 445 #ifdef WIN32 446 long lng = n; 447 if (ioctlsocket(fd, FIONREAD, &lng) == -1 || (n=lng) <= 0) { 448 #else 449 if (ioctl(fd, FIONREAD, &n) == -1 || n <= 0) { 450 #endif 451 n = EVBUFFER_MAX_READ; 452 } else if (n > EVBUFFER_MAX_READ && n > howmuch) { 453 /* 454 * It's possible that a lot of data is available for 455 * reading. We do not want to exhaust resources 456 * before the reader has a chance to do something 457 * about it. If the reader does not tell us how much 458 * data we should read, we artifically limit it. 459 */ 460 if ((size_t)n > buf->totallen << 2) 461 n = buf->totallen << 2; 462 if (n < EVBUFFER_MAX_READ) 463 n = EVBUFFER_MAX_READ; 464 } 465 #endif 466 if (howmuch < 0 || howmuch > n) 467 howmuch = n; 468 469 /* If we don't have FIONREAD, we might waste some space here */ 470 if (evbuffer_expand(buf, howmuch) == -1) 471 return (-1); 472 473 /* We can append new data at this point */ 474 p = buf->buffer + buf->off; 475 476 #ifndef WIN32 477 n = read(fd, p, howmuch); 478 #else 479 n = recv(fd, p, howmuch, 0); 480 #endif 481 if (n == -1) 482 return (-1); 483 if (n == 0) 484 return (0); 485 486 buf->off += n; 487 488 /* Tell someone about changes in this buffer */ 489 if (buf->off != oldoff && buf->cb != NULL) 490 (*buf->cb)(buf, oldoff, buf->off, buf->cbarg); 491 492 return (n); 493 } 494 495 int 496 evbuffer_write(struct evbuffer *buffer, int fd) 497 { 498 int n; 499 500 #ifndef WIN32 501 n = write(fd, buffer->buffer, buffer->off); 502 #else 503 n = send(fd, buffer->buffer, buffer->off, 0); 504 #endif 505 if (n == -1) 506 return (-1); 507 if (n == 0) 508 return (0); 509 evbuffer_drain(buffer, n); 510 511 return (n); 512 } 513 514 u_char * 515 evbuffer_find(struct evbuffer *buffer, const u_char *what, size_t len) 516 { 517 u_char *search = buffer->buffer, *end = search + buffer->off; 518 u_char *p; 519 520 while (search < end && 521 (p = memchr(search, *what, end - search)) != NULL) { 522 if (p + len > end) 523 break; 524 if (memcmp(p, what, len) == 0) 525 return (p); 526 search = p + 1; 527 } 528 529 return (NULL); 530 } 531 532 void evbuffer_setcb(struct evbuffer *buffer, 533 void (*cb)(struct evbuffer *, size_t, size_t, void *), 534 void *cbarg) 535 { 536 buffer->cb = cb; 537 buffer->cbarg = cbarg; 538 } 539