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