1 /* $OpenBSD: buffer.c,v 1.17 2010/04/21 20:02:40 nicm 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 69 struct evbuffer * 70 evbuffer_new(void) 71 { 72 struct evbuffer *buffer; 73 74 buffer = calloc(1, sizeof(struct evbuffer)); 75 76 return (buffer); 77 } 78 79 void 80 evbuffer_free(struct evbuffer *buffer) 81 { 82 if (buffer->orig_buffer != NULL) 83 free(buffer->orig_buffer); 84 free(buffer); 85 } 86 87 /* 88 * This is a destructive add. The data from one buffer moves into 89 * the other buffer. 90 */ 91 92 #define SWAP(x,y) do { \ 93 (x)->buffer = (y)->buffer; \ 94 (x)->orig_buffer = (y)->orig_buffer; \ 95 (x)->misalign = (y)->misalign; \ 96 (x)->totallen = (y)->totallen; \ 97 (x)->off = (y)->off; \ 98 } while (0) 99 100 int 101 evbuffer_add_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf) 102 { 103 int res; 104 105 /* Short cut for better performance */ 106 if (outbuf->off == 0) { 107 struct evbuffer tmp; 108 size_t oldoff = inbuf->off; 109 110 /* Swap them directly */ 111 SWAP(&tmp, outbuf); 112 SWAP(outbuf, inbuf); 113 SWAP(inbuf, &tmp); 114 115 /* 116 * Optimization comes with a price; we need to notify the 117 * buffer if necessary of the changes. oldoff is the amount 118 * of data that we transferred from inbuf to outbuf 119 */ 120 if (inbuf->off != oldoff && inbuf->cb != NULL) 121 (*inbuf->cb)(inbuf, oldoff, inbuf->off, inbuf->cbarg); 122 if (oldoff && outbuf->cb != NULL) 123 (*outbuf->cb)(outbuf, 0, oldoff, outbuf->cbarg); 124 125 return (0); 126 } 127 128 res = evbuffer_add(outbuf, inbuf->buffer, inbuf->off); 129 if (res == 0) { 130 /* We drain the input buffer on success */ 131 evbuffer_drain(inbuf, inbuf->off); 132 } 133 134 return (res); 135 } 136 137 int 138 evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap) 139 { 140 char *buffer; 141 size_t space; 142 size_t oldoff = buf->off; 143 int sz; 144 va_list aq; 145 146 /* make sure that at least some space is available */ 147 evbuffer_expand(buf, 64); 148 for (;;) { 149 size_t used = buf->misalign + buf->off; 150 buffer = (char *)buf->buffer + buf->off; 151 assert(buf->totallen >= used); 152 space = buf->totallen - used; 153 154 #ifndef va_copy 155 #define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list)) 156 #endif 157 va_copy(aq, ap); 158 159 sz = evutil_vsnprintf(buffer, space, fmt, aq); 160 161 va_end(aq); 162 163 if (sz < 0) 164 return (-1); 165 if ((size_t)sz < space) { 166 buf->off += sz; 167 if (buf->cb != NULL) 168 (*buf->cb)(buf, oldoff, buf->off, buf->cbarg); 169 return (sz); 170 } 171 if (evbuffer_expand(buf, sz + 1) == -1) 172 return (-1); 173 174 } 175 /* NOTREACHED */ 176 } 177 178 int 179 evbuffer_add_printf(struct evbuffer *buf, const char *fmt, ...) 180 { 181 int res = -1; 182 va_list ap; 183 184 va_start(ap, fmt); 185 res = evbuffer_add_vprintf(buf, fmt, ap); 186 va_end(ap); 187 188 return (res); 189 } 190 191 /* Reads data from an event buffer and drains the bytes read */ 192 193 int 194 evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen) 195 { 196 size_t nread = datlen; 197 if (nread >= buf->off) 198 nread = buf->off; 199 200 memcpy(data, buf->buffer, nread); 201 evbuffer_drain(buf, nread); 202 203 return (nread); 204 } 205 206 /* 207 * Reads a line terminated by either '\r\n', '\n\r' or '\r' or '\n'. 208 * The returned buffer needs to be freed by the called. 209 */ 210 211 char * 212 evbuffer_readline(struct evbuffer *buffer) 213 { 214 u_char *data = EVBUFFER_DATA(buffer); 215 size_t len = EVBUFFER_LENGTH(buffer); 216 char *line; 217 unsigned int i; 218 219 for (i = 0; i < len; i++) { 220 if (data[i] == '\r' || data[i] == '\n') 221 break; 222 } 223 224 if (i == len) 225 return (NULL); 226 227 if ((line = malloc(i + 1)) == NULL) { 228 fprintf(stderr, "%s: out of memory\n", __func__); 229 return (NULL); 230 } 231 232 memcpy(line, data, i); 233 line[i] = '\0'; 234 235 /* 236 * Some protocols terminate a line with '\r\n', so check for 237 * that, too. 238 */ 239 if ( i < len - 1 ) { 240 char fch = data[i], sch = data[i+1]; 241 242 /* Drain one more character if needed */ 243 if ( (sch == '\r' || sch == '\n') && sch != fch ) 244 i += 1; 245 } 246 247 evbuffer_drain(buffer, i + 1); 248 249 return (line); 250 } 251 252 253 char * 254 evbuffer_readln(struct evbuffer *buffer, size_t *n_read_out, 255 enum evbuffer_eol_style eol_style) 256 { 257 u_char *data = EVBUFFER_DATA(buffer); 258 u_char *start_of_eol, *end_of_eol; 259 size_t len = EVBUFFER_LENGTH(buffer); 260 char *line; 261 unsigned int i, n_to_copy, n_to_drain; 262 263 /* depending on eol_style, set start_of_eol to the first character 264 * in the newline, and end_of_eol to one after the last character. */ 265 switch (eol_style) { 266 case EVBUFFER_EOL_ANY: 267 for (i = 0; i < len; i++) { 268 if (data[i] == '\r' || data[i] == '\n') 269 break; 270 } 271 if (i == len) 272 return (NULL); 273 start_of_eol = data+i; 274 ++i; 275 for ( ; i < len; i++) { 276 if (data[i] != '\r' && data[i] != '\n') 277 break; 278 } 279 end_of_eol = data+i; 280 break; 281 case EVBUFFER_EOL_CRLF: 282 end_of_eol = memchr(data, '\n', len); 283 if (!end_of_eol) 284 return (NULL); 285 if (end_of_eol > data && *(end_of_eol-1) == '\r') 286 start_of_eol = end_of_eol - 1; 287 else 288 start_of_eol = end_of_eol; 289 end_of_eol++; /*point to one after the LF. */ 290 break; 291 case EVBUFFER_EOL_CRLF_STRICT: { 292 u_char *cp = data; 293 while ((cp = memchr(cp, '\r', len-(cp-data)))) { 294 if (cp < data+len-1 && *(cp+1) == '\n') 295 break; 296 if (++cp >= data+len) { 297 cp = NULL; 298 break; 299 } 300 } 301 if (!cp) 302 return (NULL); 303 start_of_eol = cp; 304 end_of_eol = cp+2; 305 break; 306 } 307 case EVBUFFER_EOL_LF: 308 start_of_eol = memchr(data, '\n', len); 309 if (!start_of_eol) 310 return (NULL); 311 end_of_eol = start_of_eol + 1; 312 break; 313 default: 314 return (NULL); 315 } 316 317 n_to_copy = start_of_eol - data; 318 n_to_drain = end_of_eol - data; 319 320 if ((line = malloc(n_to_copy+1)) == NULL) { 321 fprintf(stderr, "%s: out of memory\n", __func__); 322 evbuffer_drain(buffer, n_to_drain); 323 return (NULL); 324 } 325 326 memcpy(line, data, n_to_copy); 327 line[n_to_copy] = '\0'; 328 329 evbuffer_drain(buffer, n_to_drain); 330 if (n_read_out) 331 *n_read_out = (size_t)n_to_copy; 332 333 return (line); 334 } 335 336 /* Adds data to an event buffer */ 337 338 static void 339 evbuffer_align(struct evbuffer *buf) 340 { 341 memmove(buf->orig_buffer, buf->buffer, buf->off); 342 buf->buffer = buf->orig_buffer; 343 buf->misalign = 0; 344 } 345 346 /* Expands the available space in the event buffer to at least datlen */ 347 348 int 349 evbuffer_expand(struct evbuffer *buf, size_t datlen) 350 { 351 size_t need = buf->misalign + buf->off + datlen; 352 353 /* If we can fit all the data, then we don't have to do anything */ 354 if (buf->totallen >= need) 355 return (0); 356 357 /* 358 * If the misalignment fulfills our data needs, we just force an 359 * alignment to happen. Afterwards, we have enough space. 360 */ 361 if (buf->misalign >= datlen) { 362 evbuffer_align(buf); 363 } else { 364 void *newbuf; 365 size_t length = buf->totallen; 366 367 if (length < 256) 368 length = 256; 369 while (length < need) 370 length <<= 1; 371 372 if (buf->orig_buffer != buf->buffer) 373 evbuffer_align(buf); 374 if ((newbuf = realloc(buf->buffer, length)) == NULL) 375 return (-1); 376 377 buf->orig_buffer = buf->buffer = newbuf; 378 buf->totallen = length; 379 } 380 381 return (0); 382 } 383 384 int 385 evbuffer_add(struct evbuffer *buf, const void *data, size_t datlen) 386 { 387 size_t need = buf->misalign + buf->off + datlen; 388 size_t oldoff = buf->off; 389 390 if (buf->totallen < need) { 391 if (evbuffer_expand(buf, datlen) == -1) 392 return (-1); 393 } 394 395 memcpy(buf->buffer + buf->off, data, datlen); 396 buf->off += datlen; 397 398 if (datlen && buf->cb != NULL) 399 (*buf->cb)(buf, oldoff, buf->off, buf->cbarg); 400 401 return (0); 402 } 403 404 void 405 evbuffer_drain(struct evbuffer *buf, size_t len) 406 { 407 size_t oldoff = buf->off; 408 409 if (len >= buf->off) { 410 buf->off = 0; 411 buf->buffer = buf->orig_buffer; 412 buf->misalign = 0; 413 goto done; 414 } 415 416 buf->buffer += len; 417 buf->misalign += len; 418 419 buf->off -= len; 420 421 done: 422 /* Tell someone about changes in this buffer */ 423 if (buf->off != oldoff && buf->cb != NULL) 424 (*buf->cb)(buf, oldoff, buf->off, buf->cbarg); 425 426 } 427 428 /* 429 * Reads data from a file descriptor into a buffer. 430 */ 431 432 #define EVBUFFER_MAX_READ 4096 433 434 int 435 evbuffer_read(struct evbuffer *buf, int fd, int howmuch) 436 { 437 u_char *p; 438 size_t oldoff = buf->off; 439 int n = EVBUFFER_MAX_READ; 440 441 #if defined(FIONREAD) 442 #ifdef WIN32 443 long lng = n; 444 if (ioctlsocket(fd, FIONREAD, &lng) == -1 || (n=lng) <= 0) { 445 #else 446 if (ioctl(fd, FIONREAD, &n) == -1 || n <= 0) { 447 #endif 448 n = EVBUFFER_MAX_READ; 449 } else if (n > EVBUFFER_MAX_READ && n > howmuch) { 450 /* 451 * It's possible that a lot of data is available for 452 * reading. We do not want to exhaust resources 453 * before the reader has a chance to do something 454 * about it. If the reader does not tell us how much 455 * data we should read, we artifically limit it. 456 */ 457 if ((size_t)n > buf->totallen << 2) 458 n = buf->totallen << 2; 459 if (n < EVBUFFER_MAX_READ) 460 n = EVBUFFER_MAX_READ; 461 } 462 #endif 463 if (howmuch < 0 || howmuch > n) 464 howmuch = n; 465 466 /* If we don't have FIONREAD, we might waste some space here */ 467 if (evbuffer_expand(buf, howmuch) == -1) 468 return (-1); 469 470 /* We can append new data at this point */ 471 p = buf->buffer + buf->off; 472 473 #ifndef WIN32 474 n = read(fd, p, howmuch); 475 #else 476 n = recv(fd, p, howmuch, 0); 477 #endif 478 if (n == -1) 479 return (-1); 480 if (n == 0) 481 return (0); 482 483 buf->off += n; 484 485 /* Tell someone about changes in this buffer */ 486 if (buf->off != oldoff && buf->cb != NULL) 487 (*buf->cb)(buf, oldoff, buf->off, buf->cbarg); 488 489 return (n); 490 } 491 492 int 493 evbuffer_write(struct evbuffer *buffer, int fd) 494 { 495 int n; 496 497 #ifndef WIN32 498 n = write(fd, buffer->buffer, buffer->off); 499 #else 500 n = send(fd, buffer->buffer, buffer->off, 0); 501 #endif 502 if (n == -1) 503 return (-1); 504 if (n == 0) 505 return (0); 506 evbuffer_drain(buffer, n); 507 508 return (n); 509 } 510 511 u_char * 512 evbuffer_find(struct evbuffer *buffer, const u_char *what, size_t len) 513 { 514 u_char *search = buffer->buffer, *end = search + buffer->off; 515 u_char *p; 516 517 while (search < end && 518 (p = memchr(search, *what, end - search)) != NULL) { 519 if (p + len > end) 520 break; 521 if (memcmp(p, what, len) == 0) 522 return (p); 523 search = p + 1; 524 } 525 526 return (NULL); 527 } 528 529 void evbuffer_setcb(struct evbuffer *buffer, 530 void (*cb)(struct evbuffer *, size_t, size_t, void *), 531 void *cbarg) 532 { 533 buffer->cb = cb; 534 buffer->cbarg = cbarg; 535 } 536