1/* 2 * Copyright (C) 2010 Julien BLACHE <jb@jblache.org> 3 * Based on evhttp from libevent 1.4.x 4 * 5 * Copyright (c) 2002-2006 Niels Provos <provos@citi.umich.edu> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include <event-config.h> 32 33#ifdef _EVENT_HAVE_SYS_PARAM_H 34#include <sys/param.h> 35#endif 36#ifdef _EVENT_HAVE_SYS_TYPES_H 37#include <sys/types.h> 38#endif 39 40#ifdef _EVENT_HAVE_SYS_TIME_H 41#include <sys/time.h> 42#endif 43#ifdef _EVENT_HAVE_SYS_IOCCOM_H 44#include <sys/ioccom.h> 45#endif 46 47#ifndef WIN32 48#include <sys/resource.h> 49#include <sys/socket.h> 50#include <sys/stat.h> 51#include <sys/wait.h> 52#endif 53 54#include <sys/queue.h> 55 56#ifndef WIN32 57#include <netinet/in.h> 58#include <netdb.h> 59#include <arpa/inet.h> 60#endif 61 62#ifdef WIN32 63#include <winsock2.h> 64#endif 65 66#include <assert.h> 67#include <ctype.h> 68#include <errno.h> 69#include <stdio.h> 70#include <stdlib.h> 71#include <string.h> 72#ifndef WIN32 73#include <syslog.h> 74#endif 75#include <signal.h> 76#include <time.h> 77#ifdef _EVENT_HAVE_UNISTD_H 78#include <unistd.h> 79#endif 80#ifdef _EVENT_HAVE_FCNTL_H 81#include <fcntl.h> 82#endif 83 84#undef timeout_pending 85#undef timeout_initialized 86 87#include <event.h> 88#include "evrtsp.h" 89#include <evutil.h> 90/* #define USE_DEBUG */ 91#include "log.h" 92#include "rtsp-internal.h" 93 94#ifdef WIN32 95#define strcasecmp _stricmp 96#define strncasecmp _strnicmp 97#define strdup _strdup 98#endif 99 100#ifndef _EVENT_HAVE_GETNAMEINFO 101#define NI_MAXSERV 32 102#define NI_MAXHOST 1025 103 104#define NI_NUMERICHOST 1 105#define NI_NUMERICSERV 2 106 107static int 108fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, 109 size_t hostlen, char *serv, size_t servlen, int flags) 110{ 111 struct sockaddr_in *sin = (struct sockaddr_in *)sa; 112 int ret; 113 114 if (serv != NULL) { 115 char tmpserv[16]; 116 evutil_snprintf(tmpserv, sizeof(tmpserv), 117 "%d", ntohs(sin->sin_port)); 118 ret = evutil_snprintf(serv, servlen, "%s", tmpserv); 119 if ((ret < 0) || (ret >= servlen)) 120 return (-1); 121 } 122 123 if (host != NULL) { 124 if (flags & NI_NUMERICHOST) { 125 ret = evutil_snprintf(host, hostlen, "%s", inet_ntoa(sin->sin_addr)); 126 if ((ret < 0) || (ret >= hostlen)) 127 return (-1); 128 else 129 return (0); 130 } else { 131 struct hostent *hp; 132 hp = gethostbyaddr((char *)&sin->sin_addr, 133 sizeof(struct in_addr), AF_INET); 134 if (hp == NULL) 135 return (-2); 136 137 ret = evutil_snprintf(host, hostlen, "%s", hp->h_name); 138 if ((ret < 0) || (ret >= hostlen)) 139 return (-1); 140 else 141 return (0); 142 } 143 } 144 return (0); 145} 146 147#endif 148 149#ifndef _EVENT_HAVE_GETADDRINFO 150struct addrinfo { 151 int ai_family; 152 int ai_socktype; 153 int ai_protocol; 154 size_t ai_addrlen; 155 struct sockaddr *ai_addr; 156 struct addrinfo *ai_next; 157}; 158static int 159fake_getaddrinfo(const char *hostname, struct addrinfo *ai) 160{ 161 struct hostent *he = NULL; 162 struct sockaddr_in *sa; 163 if (hostname) { 164 he = gethostbyname(hostname); 165 if (!he) 166 return (-1); 167 } 168 ai->ai_family = he ? he->h_addrtype : AF_INET; 169 ai->ai_socktype = SOCK_STREAM; 170 ai->ai_protocol = 0; 171 ai->ai_addrlen = sizeof(struct sockaddr_in); 172 if (NULL == (ai->ai_addr = malloc(ai->ai_addrlen))) 173 return (-1); 174 sa = (struct sockaddr_in*)ai->ai_addr; 175 memset(sa, 0, ai->ai_addrlen); 176 if (he) { 177 sa->sin_family = he->h_addrtype; 178 memcpy(&sa->sin_addr, he->h_addr_list[0], he->h_length); 179 } else { 180 sa->sin_family = AF_INET; 181 sa->sin_addr.s_addr = INADDR_ANY; 182 } 183 ai->ai_next = NULL; 184 return (0); 185} 186static void 187fake_freeaddrinfo(struct addrinfo *ai) 188{ 189 free(ai->ai_addr); 190} 191#endif 192 193#ifndef MIN 194#define MIN(a,b) (((a)<(b))?(a):(b)) 195#endif 196 197/* wrapper for setting the base from the rtsp server */ 198#define EVRTSP_BASE_SET(x, y) do { \ 199 if ((x)->base != NULL) event_base_set((x)->base, y); \ 200} while (0) 201 202extern int debug; 203 204static int socket_connect(int fd, const char *address, unsigned short port); 205static int bind_socket_ai(int family, struct addrinfo *, int reuse); 206static int bind_socket(int family, const char *, u_short, int reuse); 207static void name_from_addr(struct sockaddr *, socklen_t, char **, char **); 208static void evrtsp_connection_start_detectclose( 209 struct evrtsp_connection *evcon); 210static void evrtsp_connection_stop_detectclose( 211 struct evrtsp_connection *evcon); 212static void evrtsp_request_dispatch(struct evrtsp_connection* evcon); 213static void evrtsp_read_firstline(struct evrtsp_connection *evcon, 214 struct evrtsp_request *req); 215static void evrtsp_read_header(struct evrtsp_connection *evcon, 216 struct evrtsp_request *req); 217static int evrtsp_add_header_internal(struct evkeyvalq *headers, 218 const char *key, const char *value); 219 220void evrtsp_read(int, short, void *); 221void evrtsp_write(int, short, void *); 222 223#ifndef _EVENT_HAVE_STRSEP 224/* strsep replacement for platforms that lack it. Only works if 225 * del is one character long. */ 226static char * 227strsep(char **s, const char *del) 228{ 229 char *d, *tok; 230 assert(strlen(del) == 1); 231 if (!s || !*s) 232 return NULL; 233 tok = *s; 234 d = strstr(tok, del); 235 if (d) { 236 *d = '\0'; 237 *s = d + 1; 238 } else 239 *s = NULL; 240 return tok; 241} 242#endif 243 244const char * 245evrtsp_method(enum evrtsp_cmd_type type) 246{ 247 const char *method; 248 249 switch (type) { 250 case EVRTSP_REQ_ANNOUNCE: 251 method = "ANNOUNCE"; 252 break; 253 254 case EVRTSP_REQ_OPTIONS: 255 method = "OPTIONS"; 256 break; 257 258 case EVRTSP_REQ_SETUP: 259 method = "SETUP"; 260 break; 261 262 case EVRTSP_REQ_RECORD: 263 method = "RECORD"; 264 break; 265 266 case EVRTSP_REQ_PAUSE: 267 method = "PAUSE"; 268 break; 269 270 case EVRTSP_REQ_GET_PARAMETER: 271 method = "GET_PARAMETER"; 272 break; 273 274 case EVRTSP_REQ_SET_PARAMETER: 275 method = "SET_PARAMETER"; 276 break; 277 278 case EVRTSP_REQ_FLUSH: 279 method = "FLUSH"; 280 break; 281 282 case EVRTSP_REQ_TEARDOWN: 283 method = "TEARDOWN"; 284 break; 285 286 default: 287 method = NULL; 288 break; 289 } 290 291 return (method); 292} 293 294static void 295evrtsp_add_event(struct event *ev, int timeout, int default_timeout) 296{ 297 if (timeout != 0) { 298 struct timeval tv; 299 300 evutil_timerclear(&tv); 301 tv.tv_sec = timeout != -1 ? timeout : default_timeout; 302 event_add(ev, &tv); 303 } else { 304 event_add(ev, NULL); 305 } 306} 307 308void 309evrtsp_write_buffer(struct evrtsp_connection *evcon, 310 void (*cb)(struct evrtsp_connection *, void *), void *arg) 311{ 312 event_debug(("%s: preparing to write buffer\n", __func__)); 313 314 /* Set call back */ 315 evcon->cb = cb; 316 evcon->cb_arg = arg; 317 318 /* check if the event is already pending */ 319 if (event_pending(&evcon->ev, EV_WRITE|EV_TIMEOUT, NULL)) 320 event_del(&evcon->ev); 321 322 event_set(&evcon->ev, evcon->fd, EV_WRITE, evrtsp_write, evcon); 323 EVRTSP_BASE_SET(evcon, &evcon->ev); 324 evrtsp_add_event(&evcon->ev, evcon->timeout, RTSP_WRITE_TIMEOUT); 325} 326 327static int 328evrtsp_connected(struct evrtsp_connection *evcon) 329{ 330 switch (evcon->state) { 331 case EVCON_DISCONNECTED: 332 case EVCON_CONNECTING: 333 return (0); 334 case EVCON_IDLE: 335 case EVCON_READING_FIRSTLINE: 336 case EVCON_READING_HEADERS: 337 case EVCON_READING_BODY: 338 case EVCON_READING_TRAILER: 339 case EVCON_WRITING: 340 default: 341 return (1); 342 } 343} 344 345/* 346 * Create the headers needed for an RTSP request 347 */ 348static void 349evrtsp_make_header_request(struct evrtsp_connection *evcon, 350 struct evrtsp_request *req) 351{ 352 const char *method; 353 354 /* Generate request line */ 355 method = evrtsp_method(req->type); 356 evbuffer_add_printf(evcon->output_buffer, "%s %s RTSP/%d.%d\r\n", 357 method, req->uri, req->major, req->minor); 358 359 /* Content-Length is mandatory, absent means 0 */ 360 if ((EVBUFFER_LENGTH(req->output_buffer) > 0) 361 && (evrtsp_find_header(req->output_headers, "Content-Length") == NULL)) 362 { 363 char size[12]; 364 evutil_snprintf(size, sizeof(size), "%ld", 365 (long)EVBUFFER_LENGTH(req->output_buffer)); 366 evrtsp_add_header(req->output_headers, "Content-Length", size); 367 } 368} 369 370void 371evrtsp_make_header(struct evrtsp_connection *evcon, struct evrtsp_request *req) 372{ 373 struct evkeyval *header; 374 375 evrtsp_make_header_request(evcon, req); 376 377 TAILQ_FOREACH(header, req->output_headers, next) { 378 evbuffer_add_printf(evcon->output_buffer, "%s: %s\r\n", 379 header->key, header->value); 380 } 381 evbuffer_add(evcon->output_buffer, "\r\n", 2); 382 383 if (EVBUFFER_LENGTH(req->output_buffer) > 0) { 384 evbuffer_add_buffer(evcon->output_buffer, req->output_buffer); 385 } 386} 387 388/* Separated host, port and file from URI */ 389 390int /* FIXME: needed? */ 391evrtsp_hostportfile(char *url, char **phost, u_short *pport, char **pfile) 392{ 393 /* XXX not threadsafe. */ 394 static char host[1024]; 395 static char file[1024]; 396 char *p; 397 const char *p2; 398 int len; 399 int ret; 400 u_short port; 401 402 len = strlen(RTSP_PREFIX); 403 if (strncasecmp(url, RTSP_PREFIX, len)) 404 return (-1); 405 406 url += len; 407 408 /* We might overrun */ 409 ret = evutil_snprintf(host, sizeof(host), "%s", url); 410 if ((ret < 0) || (ret >= sizeof(host))) 411 return (-1); 412 413 p = strchr(host, '/'); 414 if (p != NULL) { 415 *p = '\0'; 416 p2 = p + 1; 417 } else 418 p2 = NULL; 419 420 if (pfile != NULL) { 421 /* Generate request file */ 422 if (p2 == NULL) 423 p2 = ""; 424 evutil_snprintf(file, sizeof(file), "/%s", p2); 425 } 426 427 p = strchr(host, ':'); 428 if (p != NULL) { 429 *p = '\0'; 430 port = atoi(p + 1); 431 432 if (port == 0) 433 return (-1); 434 } else 435 return -1; 436 437 if (phost != NULL) 438 *phost = host; 439 if (pport != NULL) 440 *pport = port; 441 if (pfile != NULL) 442 *pfile = file; 443 444 return (0); 445} 446 447void 448evrtsp_connection_fail(struct evrtsp_connection *evcon, 449 enum evrtsp_connection_error error) 450{ 451 struct evrtsp_request* req = TAILQ_FIRST(&evcon->requests); 452 void (*cb)(struct evrtsp_request *, void *); 453 void *cb_arg; 454 assert(req != NULL); 455 456 /* save the callback for later; the cb might free our object */ 457 cb = req->cb; 458 cb_arg = req->cb_arg; 459 460 TAILQ_REMOVE(&evcon->requests, req, next); 461 evrtsp_request_free(req); 462 463 /* xxx: maybe we should fail all requests??? */ 464 465 /* reset the connection */ 466 evrtsp_connection_reset(evcon); 467 468 /* We are trying the next request that was queued on us */ 469 if (TAILQ_FIRST(&evcon->requests) != NULL) 470 evrtsp_connection_connect(evcon); 471 472 /* inform the user */ 473 if (cb != NULL) 474 (*cb)(NULL, cb_arg); 475} 476 477void 478evrtsp_write(int fd, short what, void *arg) 479{ 480 struct evrtsp_connection *evcon = arg; 481 int n; 482 483 if (what == EV_TIMEOUT) { 484 evrtsp_connection_fail(evcon, EVCON_RTSP_TIMEOUT); 485 return; 486 } 487 488 n = evbuffer_write(evcon->output_buffer, fd); 489 if (n == -1) { 490 event_debug(("%s: evbuffer_write", __func__)); 491 evrtsp_connection_fail(evcon, EVCON_RTSP_EOF); 492 return; 493 } 494 495 if (n == 0) { 496 event_debug(("%s: write nothing", __func__)); 497 evrtsp_connection_fail(evcon, EVCON_RTSP_EOF); 498 return; 499 } 500 501 if (EVBUFFER_LENGTH(evcon->output_buffer) != 0) { 502 evrtsp_add_event(&evcon->ev, 503 evcon->timeout, RTSP_WRITE_TIMEOUT); 504 return; 505 } 506 507 /* Activate our call back */ 508 if (evcon->cb != NULL) 509 (*evcon->cb)(evcon, evcon->cb_arg); 510} 511 512/** 513 * Advance the connection state. 514 * - If this is an outgoing connection, we've just processed the response; 515 * idle or close the connection. 516 */ 517static void 518evrtsp_connection_done(struct evrtsp_connection *evcon) 519{ 520 struct evrtsp_request *req = TAILQ_FIRST(&evcon->requests); 521 522 /* idle or close the connection */ 523 TAILQ_REMOVE(&evcon->requests, req, next); 524 req->evcon = NULL; 525 526 evcon->state = EVCON_IDLE; 527 528 if (TAILQ_FIRST(&evcon->requests) != NULL) { 529 /* 530 * We have more requests; reset the connection 531 * and deal with the next request. 532 */ 533 if (!evrtsp_connected(evcon)) 534 evrtsp_connection_connect(evcon); 535 else 536 evrtsp_request_dispatch(evcon); 537 } else { 538 /* 539 * The connection is going to be persistent, but we 540 * need to detect if the other side closes it. 541 */ 542 evrtsp_connection_start_detectclose(evcon); 543 } 544 545 /* notify the user of the request */ 546 (*req->cb)(req, req->cb_arg); 547 548 evrtsp_request_free(req); 549} 550 551static void /* FIXME: needed? */ 552evrtsp_read_trailer(struct evrtsp_connection *evcon, struct evrtsp_request *req) 553{ 554 struct evbuffer *buf = evcon->input_buffer; 555 556 switch (evrtsp_parse_headers(req, buf)) { 557 case DATA_CORRUPTED: 558 evrtsp_connection_fail(evcon, EVCON_RTSP_INVALID_HEADER); 559 break; 560 case ALL_DATA_READ: 561 event_del(&evcon->ev); 562 evrtsp_connection_done(evcon); 563 break; 564 case MORE_DATA_EXPECTED: 565 default: 566 evrtsp_add_event(&evcon->ev, evcon->timeout, 567 RTSP_READ_TIMEOUT); 568 break; 569 } 570} 571 572static void 573evrtsp_read_body(struct evrtsp_connection *evcon, struct evrtsp_request *req) 574{ 575 struct evbuffer *buf = evcon->input_buffer; 576 577 if (req->ntoread < 0) { 578 /* Read until connection close. */ 579 evbuffer_add_buffer(req->input_buffer, buf); 580 } else if (EVBUFFER_LENGTH(buf) >= req->ntoread) { 581 /* Completed content length */ 582 evbuffer_add(req->input_buffer, EVBUFFER_DATA(buf), 583 (size_t)req->ntoread); 584 evbuffer_drain(buf, (size_t)req->ntoread); 585 req->ntoread = 0; 586 evrtsp_connection_done(evcon); 587 return; 588 } 589 /* Read more! */ 590 event_set(&evcon->ev, evcon->fd, EV_READ, evrtsp_read, evcon); 591 EVRTSP_BASE_SET(evcon, &evcon->ev); 592 evrtsp_add_event(&evcon->ev, evcon->timeout, RTSP_READ_TIMEOUT); 593} 594 595/* 596 * Reads data into a buffer structure until no more data 597 * can be read on the file descriptor or we have read all 598 * the data that we wanted to read. 599 * Execute callback when done. 600 */ 601 602void 603evrtsp_read(int fd, short what, void *arg) 604{ 605 struct evrtsp_connection *evcon = arg; 606 struct evrtsp_request *req = TAILQ_FIRST(&evcon->requests); 607 struct evbuffer *buf = evcon->input_buffer; 608 int n; 609 610 if (what == EV_TIMEOUT) { 611 evrtsp_connection_fail(evcon, EVCON_RTSP_TIMEOUT); 612 return; 613 } 614 n = evbuffer_read(buf, fd, -1); 615 event_debug(("%s: got %d on %d\n", __func__, n, fd)); 616 617 if (n == -1) { 618 if (errno != EINTR && errno != EAGAIN) { 619 event_debug(("%s: evbuffer_read", __func__)); 620 evrtsp_connection_fail(evcon, EVCON_RTSP_EOF); 621 } else { 622 evrtsp_add_event(&evcon->ev, evcon->timeout, 623 RTSP_READ_TIMEOUT); 624 } 625 return; 626 } else if (n == 0) { 627 /* Connection closed */ 628 evcon->state = EVCON_DISCONNECTED; 629 evrtsp_connection_done(evcon); 630 return; 631 } 632 633 switch (evcon->state) { 634 case EVCON_READING_FIRSTLINE: 635 evrtsp_read_firstline(evcon, req); 636 break; 637 case EVCON_READING_HEADERS: 638 evrtsp_read_header(evcon, req); 639 break; 640 case EVCON_READING_BODY: 641 evrtsp_read_body(evcon, req); 642 break; 643 case EVCON_READING_TRAILER: 644 evrtsp_read_trailer(evcon, req); 645 break; 646 case EVCON_DISCONNECTED: 647 case EVCON_CONNECTING: 648 case EVCON_IDLE: 649 case EVCON_WRITING: 650 default: 651 event_errx(1, "%s: illegal connection state %d", 652 __func__, evcon->state); 653 } 654} 655 656static void 657evrtsp_write_connectioncb(struct evrtsp_connection *evcon, void *arg) 658{ 659 /* This is after writing the request to the server */ 660 struct evrtsp_request *req = TAILQ_FIRST(&evcon->requests); 661 assert(req != NULL); 662 663 assert(evcon->state == EVCON_WRITING); 664 665 /* We are done writing our header and are now expecting the response */ 666 req->kind = EVRTSP_RESPONSE; 667 668 evrtsp_start_read(evcon); 669} 670 671 672 673/* 674 * Clean up a connection object 675 */ 676 677void 678evrtsp_connection_free(struct evrtsp_connection *evcon) 679{ 680 struct evrtsp_request *req; 681 682 /* notify interested parties that this connection is going down */ 683 if (evcon->fd != -1) { 684 if (evrtsp_connected(evcon) && evcon->closecb != NULL) 685 (*evcon->closecb)(evcon, evcon->closecb_arg); 686 } 687 688 /* remove all requests that might be queued on this connection */ 689 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) { 690 TAILQ_REMOVE(&evcon->requests, req, next); 691 evrtsp_request_free(req); 692 } 693 694 if (event_initialized(&evcon->close_ev)) 695 event_del(&evcon->close_ev); 696 697 if (event_initialized(&evcon->ev)) 698 event_del(&evcon->ev); 699 700 if (evcon->fd != -1) 701 EVUTIL_CLOSESOCKET(evcon->fd); 702 703 if (evcon->bind_address != NULL) 704 free(evcon->bind_address); 705 706 if (evcon->address != NULL) 707 free(evcon->address); 708 709 if (evcon->input_buffer != NULL) 710 evbuffer_free(evcon->input_buffer); 711 712 if (evcon->output_buffer != NULL) 713 evbuffer_free(evcon->output_buffer); 714 715 free(evcon); 716} 717 718static void 719evrtsp_request_dispatch(struct evrtsp_connection* evcon) 720{ 721 struct evrtsp_request *req = TAILQ_FIRST(&evcon->requests); 722 723 /* this should not usually happy but it's possible */ 724 if (req == NULL) 725 return; 726 727 /* delete possible close detection events */ 728 evrtsp_connection_stop_detectclose(evcon); 729 730 /* we assume that the connection is connected already */ 731 assert(evcon->state == EVCON_IDLE); 732 733 evcon->state = EVCON_WRITING; 734 735 /* Create the header from the store arguments */ 736 evrtsp_make_header(evcon, req); 737 738 evrtsp_write_buffer(evcon, evrtsp_write_connectioncb, NULL); 739} 740 741/* Reset our connection state */ 742void 743evrtsp_connection_reset(struct evrtsp_connection *evcon) 744{ 745 if (event_initialized(&evcon->ev)) 746 event_del(&evcon->ev); 747 748 if (evcon->fd != -1) { 749 /* inform interested parties about connection close */ 750 if (evrtsp_connected(evcon) && evcon->closecb != NULL) 751 (*evcon->closecb)(evcon, evcon->closecb_arg); 752 753 EVUTIL_CLOSESOCKET(evcon->fd); 754 evcon->fd = -1; 755 } 756 evcon->state = EVCON_DISCONNECTED; 757 758 evbuffer_drain(evcon->input_buffer, 759 EVBUFFER_LENGTH(evcon->input_buffer)); 760 evbuffer_drain(evcon->output_buffer, 761 EVBUFFER_LENGTH(evcon->output_buffer)); 762} 763 764static void 765evrtsp_detect_close_cb(int fd, short what, void *arg) 766{ 767 struct evrtsp_connection *evcon = arg; 768 769 evrtsp_connection_reset(evcon); 770} 771 772static void 773evrtsp_connection_start_detectclose(struct evrtsp_connection *evcon) 774{ 775 evcon->flags |= EVRTSP_CON_CLOSEDETECT; 776 777 if (event_initialized(&evcon->close_ev)) 778 event_del(&evcon->close_ev); 779 event_set(&evcon->close_ev, evcon->fd, EV_READ, 780 evrtsp_detect_close_cb, evcon); 781 EVRTSP_BASE_SET(evcon, &evcon->close_ev); 782 event_add(&evcon->close_ev, NULL); 783} 784 785static void 786evrtsp_connection_stop_detectclose(struct evrtsp_connection *evcon) 787{ 788 evcon->flags &= ~EVRTSP_CON_CLOSEDETECT; 789 event_del(&evcon->close_ev); 790} 791 792/* 793 * Call back for asynchronous connection attempt. 794 */ 795 796static void 797evrtsp_connectioncb(int fd, short what, void *arg) 798{ 799 struct evrtsp_connection *evcon = arg; 800 int error; 801 socklen_t errsz = sizeof(error); 802 803 if (what == EV_TIMEOUT) { 804 event_debug(("%s: connection timeout for \"%s:%d\" on %d", 805 __func__, evcon->address, evcon->port, evcon->fd)); 806 goto cleanup; 807 } 808 809 /* Check if the connection completed */ 810 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error, 811 &errsz) == -1) { 812 event_debug(("%s: getsockopt for \"%s:%d\" on %d", 813 __func__, evcon->address, evcon->port, evcon->fd)); 814 goto cleanup; 815 } 816 817 if (error) { 818 event_debug(("%s: connect failed for \"%s:%d\" on %d: %s", 819 __func__, evcon->address, evcon->port, evcon->fd, 820 strerror(error))); 821 goto cleanup; 822 } 823 824 /* We are connected to the server now */ 825 event_debug(("%s: connected to \"%s:%d\" on %d\n", 826 __func__, evcon->address, evcon->port, evcon->fd)); 827 828 evcon->state = EVCON_IDLE; 829 830 /* try to start requests that have queued up on this connection */ 831 evrtsp_request_dispatch(evcon); 832 return; 833 834 cleanup: 835 evrtsp_connection_reset(evcon); 836 837 /* for now, we just signal all requests by executing their callbacks */ 838 while (TAILQ_FIRST(&evcon->requests) != NULL) { 839 struct evrtsp_request *request = TAILQ_FIRST(&evcon->requests); 840 TAILQ_REMOVE(&evcon->requests, request, next); 841 request->evcon = NULL; 842 843 /* we might want to set an error here */ 844 request->cb(request, request->cb_arg); 845 evrtsp_request_free(request); 846 } 847} 848 849/* 850 * Check if we got a valid response code. 851 */ 852 853static int 854evrtsp_valid_response_code(int code) 855{ 856 if (code == 0) 857 return (0); 858 859 return (1); 860} 861 862/* Parses the status line of an RTSP server */ 863 864static int 865evrtsp_parse_response_line(struct evrtsp_request *req, char *line) 866{ 867 char *protocol; 868 char *number; 869 const char *readable = ""; 870 871 protocol = strsep(&line, " "); 872 if (line == NULL) 873 return (-1); 874 number = strsep(&line, " "); 875 if (line != NULL) 876 readable = line; 877 878 if (strcmp(protocol, "RTSP/1.0") == 0) { 879 req->major = 1; 880 req->minor = 0; 881 } else if (strcmp(protocol, "RTSP/1.1") == 0) { 882 req->major = 1; 883 req->minor = 1; 884 } else { 885 event_debug(("%s: bad protocol \"%s\"", 886 __func__, protocol)); 887 return (-1); 888 } 889 890 req->response_code = atoi(number); 891 if (!evrtsp_valid_response_code(req->response_code)) { 892 event_debug(("%s: bad response code \"%s\"", 893 __func__, number)); 894 return (-1); 895 } 896 897 if ((req->response_code_line = strdup(readable)) == NULL) 898 event_err(1, "%s: strdup", __func__); 899 900 return (0); 901} 902 903const char * 904evrtsp_find_header(const struct evkeyvalq *headers, const char *key) 905{ 906 struct evkeyval *header; 907 908 TAILQ_FOREACH(header, headers, next) { 909 if (strcasecmp(header->key, key) == 0) 910 return (header->value); 911 } 912 913 return (NULL); 914} 915 916void 917evrtsp_clear_headers(struct evkeyvalq *headers) 918{ 919 struct evkeyval *header; 920 921 for (header = TAILQ_FIRST(headers); 922 header != NULL; 923 header = TAILQ_FIRST(headers)) { 924 TAILQ_REMOVE(headers, header, next); 925 free(header->key); 926 free(header->value); 927 free(header); 928 } 929} 930 931/* 932 * Returns 0, if the header was successfully removed. 933 * Returns -1, if the header could not be found. 934 */ 935 936int 937evrtsp_remove_header(struct evkeyvalq *headers, const char *key) 938{ 939 struct evkeyval *header; 940 941 TAILQ_FOREACH(header, headers, next) { 942 if (strcasecmp(header->key, key) == 0) 943 break; 944 } 945 946 if (header == NULL) 947 return (-1); 948 949 /* Free and remove the header that we found */ 950 TAILQ_REMOVE(headers, header, next); 951 free(header->key); 952 free(header->value); 953 free(header); 954 955 return (0); 956} 957 958static int 959evrtsp_header_is_valid_value(const char *value) 960{ 961 const char *p = value; 962 963 while ((p = strpbrk(p, "\r\n")) != NULL) { 964 /* we really expect only one new line */ 965 p += strspn(p, "\r\n"); 966 /* we expect a space or tab for continuation */ 967 if (*p != ' ' && *p != '\t') 968 return (0); 969 } 970 return (1); 971} 972 973int 974evrtsp_add_header(struct evkeyvalq *headers, 975 const char *key, const char *value) 976{ 977 event_debug(("%s: key: %s val: %s\n", __func__, key, value)); 978 979 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) { 980 /* drop illegal headers */ 981 event_debug(("%s: dropping illegal header key\n", __func__)); 982 return (-1); 983 } 984 985 if (!evrtsp_header_is_valid_value(value)) { 986 event_debug(("%s: dropping illegal header value\n", __func__)); 987 return (-1); 988 } 989 990 return (evrtsp_add_header_internal(headers, key, value)); 991} 992 993static int 994evrtsp_add_header_internal(struct evkeyvalq *headers, 995 const char *key, const char *value) 996{ 997 struct evkeyval *header = calloc(1, sizeof(struct evkeyval)); 998 999 if (header == NULL) { 1000 event_warn("%s: calloc", __func__); 1001 return (-1); 1002 } 1003 if ((header->key = strdup(key)) == NULL) { 1004 free(header); 1005 event_warn("%s: strdup", __func__); 1006 return (-1); 1007 } 1008 if ((header->value = strdup(value)) == NULL) { 1009 free(header->key); 1010 free(header); 1011 event_warn("%s: strdup", __func__); 1012 return (-1); 1013 } 1014 1015 TAILQ_INSERT_TAIL(headers, header, next); 1016 1017 return (0); 1018} 1019 1020/* 1021 * Parses header lines from a request or a response into the specified 1022 * request object given an event buffer. 1023 * 1024 * Returns 1025 * DATA_CORRUPTED on error 1026 * MORE_DATA_EXPECTED when we need to read more headers 1027 * ALL_DATA_READ when all headers have been read. 1028 */ 1029 1030enum message_read_status 1031evrtsp_parse_firstline(struct evrtsp_request *req, struct evbuffer *buffer) 1032{ 1033 char *line; 1034 enum message_read_status status = ALL_DATA_READ; 1035 1036 line = evbuffer_readline(buffer); 1037 if (line == NULL) 1038 return (MORE_DATA_EXPECTED); 1039 1040 switch (req->kind) { 1041 case EVRTSP_RESPONSE: 1042 if (evrtsp_parse_response_line(req, line) == -1) 1043 status = DATA_CORRUPTED; 1044 break; 1045 default: 1046 status = DATA_CORRUPTED; 1047 } 1048 1049 free(line); 1050 return (status); 1051} 1052 1053static int 1054evrtsp_append_to_last_header(struct evkeyvalq *headers, const char *line) 1055{ 1056 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq); 1057 char *newval; 1058 size_t old_len, line_len; 1059 1060 if (header == NULL) 1061 return (-1); 1062 1063 old_len = strlen(header->value); 1064 line_len = strlen(line); 1065 1066 newval = realloc(header->value, old_len + line_len + 1); 1067 if (newval == NULL) 1068 return (-1); 1069 1070 memcpy(newval + old_len, line, line_len + 1); 1071 header->value = newval; 1072 1073 return (0); 1074} 1075 1076enum message_read_status 1077evrtsp_parse_headers(struct evrtsp_request *req, struct evbuffer* buffer) 1078{ 1079 char *line; 1080 enum message_read_status status = MORE_DATA_EXPECTED; 1081 1082 struct evkeyvalq* headers = req->input_headers; 1083 while ((line = evbuffer_readline(buffer)) 1084 != NULL) { 1085 char *skey, *svalue; 1086 1087 if (*line == '\0') { /* Last header - Done */ 1088 status = ALL_DATA_READ; 1089 free(line); 1090 break; 1091 } 1092 1093 /* Check if this is a continuation line */ 1094 if (*line == ' ' || *line == '\t') { 1095 if (evrtsp_append_to_last_header(headers, line) == -1) 1096 goto error; 1097 free(line); 1098 continue; 1099 } 1100 1101 /* Processing of header lines */ 1102 svalue = line; 1103 skey = strsep(&svalue, ":"); 1104 if (svalue == NULL) 1105 goto error; 1106 1107 svalue += strspn(svalue, " "); 1108 1109 if (evrtsp_add_header(headers, skey, svalue) == -1) 1110 goto error; 1111 1112 free(line); 1113 } 1114 1115 return (status); 1116 1117 error: 1118 free(line); 1119 return (DATA_CORRUPTED); 1120} 1121 1122static int 1123evrtsp_get_body_length(struct evrtsp_request *req) 1124{ 1125 struct evkeyvalq *headers = req->input_headers; 1126 const char *content_length; 1127 1128 content_length = evrtsp_find_header(headers, "Content-Length"); 1129 1130 if (content_length == NULL) { 1131 /* If there is no Content-Length: header, a value of 0 is assumed, per spec. */ 1132 req->ntoread = 0; 1133 } else { 1134 char *endp; 1135 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10); 1136 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) { 1137 event_debug(("%s: illegal content length: %s", 1138 __func__, content_length)); 1139 return (-1); 1140 } 1141 req->ntoread = ntoread; 1142 } 1143 1144 event_debug(("%s: bytes to read: %lld (in buffer %ld)\n", 1145 __func__, req->ntoread, 1146 EVBUFFER_LENGTH(req->evcon->input_buffer))); 1147 1148 return (0); 1149} 1150 1151static void 1152evrtsp_get_body(struct evrtsp_connection *evcon, struct evrtsp_request *req) 1153{ 1154 evcon->state = EVCON_READING_BODY; 1155 if (evrtsp_get_body_length(req) == -1) { 1156 evrtsp_connection_fail(evcon, EVCON_RTSP_INVALID_HEADER); 1157 return; 1158 } 1159 1160 evrtsp_read_body(evcon, req); 1161} 1162 1163static void 1164evrtsp_read_firstline(struct evrtsp_connection *evcon, 1165 struct evrtsp_request *req) 1166{ 1167 enum message_read_status res; 1168 1169 res = evrtsp_parse_firstline(req, evcon->input_buffer); 1170 if (res == DATA_CORRUPTED) { 1171 /* Error while reading, terminate */ 1172 event_debug(("%s: bad header lines on %d\n", 1173 __func__, evcon->fd)); 1174 evrtsp_connection_fail(evcon, EVCON_RTSP_INVALID_HEADER); 1175 return; 1176 } else if (res == MORE_DATA_EXPECTED) { 1177 /* Need more header lines */ 1178 evrtsp_add_event(&evcon->ev, 1179 evcon->timeout, RTSP_READ_TIMEOUT); 1180 return; 1181 } 1182 1183 evcon->state = EVCON_READING_HEADERS; 1184 evrtsp_read_header(evcon, req); 1185} 1186 1187static void 1188evrtsp_read_header(struct evrtsp_connection *evcon, struct evrtsp_request *req) 1189{ 1190 enum message_read_status res; 1191 int fd = evcon->fd; 1192 1193 res = evrtsp_parse_headers(req, evcon->input_buffer); 1194 if (res == DATA_CORRUPTED) { 1195 /* Error while reading, terminate */ 1196 event_debug(("%s: bad header lines on %d\n", __func__, fd)); 1197 evrtsp_connection_fail(evcon, EVCON_RTSP_INVALID_HEADER); 1198 return; 1199 } else if (res == MORE_DATA_EXPECTED) { 1200 /* Need more header lines */ 1201 evrtsp_add_event(&evcon->ev, 1202 evcon->timeout, RTSP_READ_TIMEOUT); 1203 return; 1204 } 1205 1206 /* Done reading headers, do the real work */ 1207 switch (req->kind) { 1208 case EVRTSP_RESPONSE: 1209 event_debug(("%s: start of read body on %d\n", 1210 __func__, fd)); 1211 evrtsp_get_body(evcon, req); 1212 break; 1213 1214 default: 1215 event_warnx("%s: bad header on %d", __func__, fd); 1216 evrtsp_connection_fail(evcon, EVCON_RTSP_INVALID_HEADER); 1217 break; 1218 } 1219} 1220 1221/* 1222 * Creates a TCP connection to the specified port and executes a callback 1223 * when finished. Failure or sucess is indicate by the passed connection 1224 * object. 1225 * 1226 * Although this interface accepts a hostname, it is intended to take 1227 * only numeric hostnames so that non-blocking DNS resolution can 1228 * happen elsewhere. 1229 */ 1230 1231struct evrtsp_connection * 1232evrtsp_connection_new(const char *address, unsigned short port) 1233{ 1234 struct evrtsp_connection *evcon = NULL; 1235 char *intf; 1236 char *addr; 1237 unsigned char scratch[16]; 1238 int family; 1239 1240 if ((addr = strdup(address)) == NULL) { 1241 event_warn("%s: strdup failed", __func__); 1242 goto error; 1243 } 1244 1245 intf = strchr(addr, '%'); 1246 if (intf) 1247 *intf = '\0'; 1248 1249 if (inet_pton(AF_INET6, addr, scratch) == 1) 1250 family = AF_INET6; 1251 else if (inet_pton(AF_INET, addr, scratch) == 1) 1252 family = AF_INET; 1253 else { 1254 free(addr); 1255 event_warn("%s: address is neither IPv6 nor IPv4", __func__); 1256 return NULL; 1257 } 1258 1259 if (intf) 1260 *intf = '%'; 1261 1262 event_debug(("Attempting connection to %s:%d\n", address, port)); 1263 1264 if ((evcon = calloc(1, sizeof(struct evrtsp_connection))) == NULL) { 1265 free(addr); 1266 event_warn("%s: calloc failed", __func__); 1267 goto error; 1268 } 1269 1270 evcon->fd = -1; 1271 evcon->port = port; 1272 1273 evcon->timeout = -1; 1274 1275 evcon->cseq = 1; 1276 1277 evcon->family = family; 1278 evcon->address = addr; 1279 1280 if ((evcon->input_buffer = evbuffer_new()) == NULL) { 1281 event_warn("%s: evbuffer_new failed", __func__); 1282 goto error; 1283 } 1284 1285 if ((evcon->output_buffer = evbuffer_new()) == NULL) { 1286 event_warn("%s: evbuffer_new failed", __func__); 1287 goto error; 1288 } 1289 1290 evcon->state = EVCON_DISCONNECTED; 1291 TAILQ_INIT(&evcon->requests); 1292 1293 return (evcon); 1294 1295 error: 1296 if (evcon != NULL) 1297 evrtsp_connection_free(evcon); 1298 return (NULL); 1299} 1300 1301void evrtsp_connection_set_base(struct evrtsp_connection *evcon, 1302 struct event_base *base) 1303{ 1304 assert(evcon->base == NULL); 1305 assert(evcon->state == EVCON_DISCONNECTED); 1306 evcon->base = base; 1307} 1308 1309void 1310evrtsp_connection_set_timeout(struct evrtsp_connection *evcon, 1311 int timeout_in_secs) 1312{ 1313 evcon->timeout = timeout_in_secs; 1314} 1315 1316void 1317evrtsp_connection_set_closecb(struct evrtsp_connection *evcon, 1318 void (*cb)(struct evrtsp_connection *, void *), void *cbarg) 1319{ 1320 evcon->closecb = cb; 1321 evcon->closecb_arg = cbarg; 1322} 1323 1324void 1325evrtsp_connection_get_local_address(struct evrtsp_connection *evcon, 1326 char **address, u_short *port) 1327{ 1328 union { 1329 struct sockaddr_storage ss; 1330 struct sockaddr sa; 1331 struct sockaddr_in sin; 1332 struct sockaddr_in6 sin6; 1333 } addr; 1334 socklen_t slen; 1335 int ret; 1336 1337 *address = NULL; 1338 *port = 0; 1339 1340 if (!evrtsp_connected(evcon)) 1341 return; 1342 1343 slen = sizeof(struct sockaddr_storage); 1344 ret = getsockname(evcon->fd, &addr.sa, &slen); 1345 if (ret < 0) 1346 return; 1347 1348 name_from_addr(&addr.sa, slen, address, NULL); 1349 1350 if (!*address) 1351 return; 1352 1353 switch (addr.ss.ss_family) 1354 { 1355 case AF_INET: 1356 *port = ntohs(addr.sin.sin_port); 1357 break; 1358 1359#ifdef AF_INET6 1360 case AF_INET6: 1361 *port = ntohs(addr.sin6.sin6_port); 1362 break; 1363#endif 1364 1365 default: 1366 free(*address); 1367 address = NULL; 1368 1369 event_err(1, "%s: unhandled address family\n", __func__); 1370 return; 1371 } 1372} 1373 1374void 1375evrtsp_connection_get_peer(struct evrtsp_connection *evcon, 1376 char **address, u_short *port) 1377{ 1378 *address = evcon->address; 1379 *port = evcon->port; 1380} 1381 1382int 1383evrtsp_connection_connect(struct evrtsp_connection *evcon) 1384{ 1385 if (evcon->state == EVCON_CONNECTING) 1386 return (0); 1387 1388 evrtsp_connection_reset(evcon); 1389 1390 evcon->fd = bind_socket(evcon->family, 1391 evcon->bind_address, evcon->bind_port, 0 /*reuse*/); 1392 if (evcon->fd == -1) { 1393 event_debug(("%s: failed to bind to \"%s\"", 1394 __func__, evcon->bind_address)); 1395 return (-1); 1396 } 1397 1398 if (socket_connect(evcon->fd, evcon->address, evcon->port) == -1) { 1399 EVUTIL_CLOSESOCKET(evcon->fd); evcon->fd = -1; 1400 return (-1); 1401 } 1402 1403 /* Set up a callback for successful connection setup */ 1404 event_set(&evcon->ev, evcon->fd, EV_WRITE, evrtsp_connectioncb, evcon); 1405 EVRTSP_BASE_SET(evcon, &evcon->ev); 1406 evrtsp_add_event(&evcon->ev, evcon->timeout, RTSP_CONNECT_TIMEOUT); 1407 1408 evcon->state = EVCON_CONNECTING; 1409 1410 return (0); 1411} 1412 1413/* 1414 * Starts an RTSP request on the provided evrtsp_connection object. 1415 * If the connection object is not connected to the server already, 1416 * this will start the connection. 1417 */ 1418 1419int 1420evrtsp_make_request(struct evrtsp_connection *evcon, 1421 struct evrtsp_request *req, 1422 enum evrtsp_cmd_type type, const char *uri) 1423{ 1424 /* We are making a request */ 1425 req->kind = EVRTSP_REQUEST; 1426 req->type = type; 1427 if (req->uri != NULL) 1428 free(req->uri); 1429 if ((req->uri = strdup(uri)) == NULL) 1430 event_err(1, "%s: strdup", __func__); 1431 1432 /* Set the protocol version if it is not supplied */ 1433 if (!req->major && !req->minor) { 1434 req->major = 1; 1435 req->minor = 0; 1436 } 1437 1438 assert(req->evcon == NULL); 1439 req->evcon = evcon; 1440 assert(!(req->flags & EVRTSP_REQ_OWN_CONNECTION)); 1441 1442 TAILQ_INSERT_TAIL(&evcon->requests, req, next); 1443 1444 /* If the connection object is not connected; make it so */ 1445 if (!evrtsp_connected(evcon)) 1446 return (evrtsp_connection_connect(evcon)); 1447 1448 /* 1449 * If it's connected already and we are the first in the queue, 1450 * then we can dispatch this request immediately. Otherwise, it 1451 * will be dispatched once the pending requests are completed. 1452 */ 1453 if (TAILQ_FIRST(&evcon->requests) == req) 1454 evrtsp_request_dispatch(evcon); 1455 1456 return (0); 1457} 1458 1459/* 1460 * Reads data from file descriptor into request structure 1461 * Request structure needs to be set up correctly. 1462 */ 1463 1464void 1465evrtsp_start_read(struct evrtsp_connection *evcon) 1466{ 1467 /* Set up an event to read the headers */ 1468 if (event_initialized(&evcon->ev)) 1469 event_del(&evcon->ev); 1470 event_set(&evcon->ev, evcon->fd, EV_READ, evrtsp_read, evcon); 1471 EVRTSP_BASE_SET(evcon, &evcon->ev); 1472 1473 evrtsp_add_event(&evcon->ev, evcon->timeout, RTSP_READ_TIMEOUT); 1474 evcon->state = EVCON_READING_FIRSTLINE; 1475} 1476 1477static void 1478evrtsp_send_done(struct evrtsp_connection *evcon, void *arg) 1479{ 1480 struct evrtsp_request *req = TAILQ_FIRST(&evcon->requests); 1481 TAILQ_REMOVE(&evcon->requests, req, next); 1482 1483 /* delete possible close detection events */ 1484 evrtsp_connection_stop_detectclose(evcon); 1485 1486 assert(req->flags & EVRTSP_REQ_OWN_CONNECTION); 1487 evrtsp_request_free(req); 1488} 1489 1490/* Requires that headers and response code are already set up */ 1491 1492static inline void 1493evrtsp_send(struct evrtsp_request *req, struct evbuffer *databuf) 1494{ 1495 struct evrtsp_connection *evcon = req->evcon; 1496 1497 if (evcon == NULL) { 1498 evrtsp_request_free(req); 1499 return; 1500 } 1501 1502 assert(TAILQ_FIRST(&evcon->requests) == req); 1503 1504 /* xxx: not sure if we really should expose the data buffer this way */ 1505 if (databuf != NULL) 1506 evbuffer_add_buffer(req->output_buffer, databuf); 1507 1508 /* Adds headers to the response */ 1509 evrtsp_make_header(evcon, req); 1510 1511 evrtsp_write_buffer(evcon, evrtsp_send_done, NULL); 1512} 1513 1514/* 1515 * Request related functions 1516 */ 1517 1518struct evrtsp_request * 1519evrtsp_request_new(void (*cb)(struct evrtsp_request *, void *), void *arg) 1520{ 1521 struct evrtsp_request *req = NULL; 1522 1523 /* Allocate request structure */ 1524 if ((req = calloc(1, sizeof(struct evrtsp_request))) == NULL) { 1525 event_warn("%s: calloc", __func__); 1526 goto error; 1527 } 1528 1529 req->kind = EVRTSP_RESPONSE; 1530 req->input_headers = calloc(1, sizeof(struct evkeyvalq)); 1531 if (req->input_headers == NULL) { 1532 event_warn("%s: calloc", __func__); 1533 goto error; 1534 } 1535 TAILQ_INIT(req->input_headers); 1536 1537 req->output_headers = calloc(1, sizeof(struct evkeyvalq)); 1538 if (req->output_headers == NULL) { 1539 event_warn("%s: calloc", __func__); 1540 goto error; 1541 } 1542 TAILQ_INIT(req->output_headers); 1543 1544 if ((req->input_buffer = evbuffer_new()) == NULL) { 1545 event_warn("%s: evbuffer_new", __func__); 1546 goto error; 1547 } 1548 1549 if ((req->output_buffer = evbuffer_new()) == NULL) { 1550 event_warn("%s: evbuffer_new", __func__); 1551 goto error; 1552 } 1553 1554 req->cb = cb; 1555 req->cb_arg = arg; 1556 1557 return (req); 1558 1559 error: 1560 if (req != NULL) 1561 evrtsp_request_free(req); 1562 return (NULL); 1563} 1564 1565void 1566evrtsp_request_free(struct evrtsp_request *req) 1567{ 1568 if (req->uri != NULL) 1569 free(req->uri); 1570 if (req->response_code_line != NULL) 1571 free(req->response_code_line); 1572 1573 evrtsp_clear_headers(req->input_headers); 1574 free(req->input_headers); 1575 1576 evrtsp_clear_headers(req->output_headers); 1577 free(req->output_headers); 1578 1579 if (req->input_buffer != NULL) 1580 evbuffer_free(req->input_buffer); 1581 1582 if (req->output_buffer != NULL) 1583 evbuffer_free(req->output_buffer); 1584 1585 free(req); 1586} 1587 1588/* 1589 * Allows for inspection of the request URI 1590 */ 1591 1592const char * 1593evrtsp_request_uri(struct evrtsp_request *req) { 1594 if (req->uri == NULL) 1595 event_debug(("%s: request %p has no uri\n", __func__, req)); 1596 return (req->uri); 1597} 1598 1599/* 1600 * Network helper functions that we do not want to export to the rest of 1601 * the world. 1602 */ 1603#if 0 /* Unused */ 1604static struct addrinfo * 1605addr_from_name(char *address) 1606{ 1607#ifdef _EVENT_HAVE_GETADDRINFO 1608 struct addrinfo ai, *aitop; 1609 int ai_result; 1610 1611 memset(&ai, 0, sizeof(ai)); 1612 ai.ai_family = AF_INET; 1613 ai.ai_socktype = SOCK_RAW; 1614 ai.ai_flags = 0; 1615 if ((ai_result = getaddrinfo(address, NULL, &ai, &aitop)) != 0) { 1616 if ( ai_result == EAI_SYSTEM ) 1617 event_warn("getaddrinfo"); 1618 else 1619 event_warnx("getaddrinfo: %s", gai_strerror(ai_result)); 1620 } 1621 1622 return (aitop); 1623#else 1624 assert(0); 1625 return NULL; /* XXXXX Use gethostbyname, if this function is ever used. */ 1626#endif 1627} 1628#endif 1629 1630static void 1631name_from_addr(struct sockaddr *sa, socklen_t salen, 1632 char **phost, char **pport) 1633{ 1634 char ntop[NI_MAXHOST]; 1635 char strport[NI_MAXSERV]; 1636 int ni_result; 1637 1638#ifdef _EVENT_HAVE_GETNAMEINFO 1639 ni_result = getnameinfo(sa, salen, 1640 ntop, sizeof(ntop), strport, sizeof(strport), 1641 NI_NUMERICHOST|NI_NUMERICSERV); 1642 1643 if (ni_result != 0) { 1644 if (ni_result == EAI_SYSTEM) 1645 event_err(1, "getnameinfo failed"); 1646 else 1647 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result)); 1648 return; 1649 } 1650#else 1651 ni_result = fake_getnameinfo(sa, salen, 1652 ntop, sizeof(ntop), strport, sizeof(strport), 1653 NI_NUMERICHOST|NI_NUMERICSERV); 1654 if (ni_result != 0) 1655 return; 1656#endif 1657 if (phost) 1658 *phost = strdup(ntop); 1659 if (pport) 1660 *pport = strdup(strport); 1661} 1662 1663/* Create a non-blocking socket and bind it */ 1664/* todo: rename this function */ 1665static int 1666bind_socket_ai(int family, struct addrinfo *ai, int reuse) 1667{ 1668 int fd, on = 1, r; 1669 int serrno; 1670 1671 if (ai) 1672 family = ai->ai_family; 1673 1674 /* Create listen socket */ 1675 fd = socket(family, SOCK_STREAM, 0); 1676 if (fd == -1) { 1677 event_warn("socket"); 1678 return (-1); 1679 } 1680 1681 if (evutil_make_socket_nonblocking(fd) < 0) 1682 goto out; 1683 1684#ifndef WIN32 1685 if (fcntl(fd, F_SETFD, 1) == -1) { 1686 event_warn("fcntl(F_SETFD)"); 1687 goto out; 1688 } 1689#endif 1690 1691 if (family == AF_INET6) 1692 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); 1693 1694 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)); 1695 if (reuse) { 1696 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 1697 (void *)&on, sizeof(on)); 1698 } 1699 1700 if (ai != NULL) { 1701 r = bind(fd, ai->ai_addr, ai->ai_addrlen); 1702 if (r == -1) 1703 goto out; 1704 } 1705 1706 return (fd); 1707 1708 out: 1709 serrno = EVUTIL_SOCKET_ERROR(); 1710 EVUTIL_CLOSESOCKET(fd); 1711 EVUTIL_SET_SOCKET_ERROR(serrno); 1712 return (-1); 1713} 1714 1715static struct addrinfo * 1716make_addrinfo(const char *address, u_short port) 1717{ 1718 struct addrinfo *aitop = NULL; 1719 1720#ifdef _EVENT_HAVE_GETADDRINFO 1721 struct addrinfo ai; 1722 char strport[NI_MAXSERV]; 1723 int ai_result; 1724 1725 memset(&ai, 0, sizeof(ai)); 1726 ai.ai_family = AF_UNSPEC; 1727 ai.ai_socktype = SOCK_STREAM; 1728 ai.ai_flags = AI_PASSIVE; /* turn NULL host name into INADDR_ANY */ 1729 evutil_snprintf(strport, sizeof(strport), "%d", port); 1730 if ((ai_result = getaddrinfo(address, strport, &ai, &aitop)) != 0) { 1731 if ( ai_result == EAI_SYSTEM ) 1732 event_warn("getaddrinfo"); 1733 else 1734 event_warnx("getaddrinfo: %s", gai_strerror(ai_result)); 1735 return (NULL); 1736 } 1737#else 1738 static int cur; 1739 static struct addrinfo ai[2]; /* We will be returning the address of some of this memory so it has to last even after this call. */ 1740 if (++cur == 2) cur = 0; /* allow calling this function twice */ 1741 1742 if (fake_getaddrinfo(address, &ai[cur]) < 0) { 1743 event_warn("fake_getaddrinfo"); 1744 return (NULL); 1745 } 1746 aitop = &ai[cur]; 1747 ((struct sockaddr_in *) aitop->ai_addr)->sin_port = htons(port); 1748#endif 1749 1750 return (aitop); 1751} 1752 1753static int 1754bind_socket(int family, const char *address, u_short port, int reuse) 1755{ 1756 int fd; 1757 struct addrinfo *aitop = NULL; 1758 1759 /* just create an unbound socket */ 1760 if (address == NULL && port == 0) 1761 return bind_socket_ai(family, NULL, 0); 1762 1763 aitop = make_addrinfo(address, port); 1764 1765 if (aitop == NULL) 1766 return (-1); 1767 1768 fd = bind_socket_ai(family, aitop, reuse); 1769 1770#ifdef _EVENT_HAVE_GETADDRINFO 1771 freeaddrinfo(aitop); 1772#else 1773 fake_freeaddrinfo(aitop); 1774#endif 1775 1776 return (fd); 1777} 1778 1779static int 1780socket_connect(int fd, const char *address, unsigned short port) 1781{ 1782 struct addrinfo *ai = make_addrinfo(address, port); 1783 int res = -1; 1784 1785 if (ai == NULL) { 1786 event_debug(("%s: make_addrinfo: \"%s:%d\"", 1787 __func__, address, port)); 1788 return (-1); 1789 } 1790 1791 if (connect(fd, ai->ai_addr, ai->ai_addrlen) == -1) { 1792#ifdef WIN32 1793 int tmp_error = WSAGetLastError(); 1794 if (tmp_error != WSAEWOULDBLOCK && tmp_error != WSAEINVAL && 1795 tmp_error != WSAEINPROGRESS) { 1796 goto out; 1797 } 1798#else 1799 if (errno != EINPROGRESS) { 1800 goto out; 1801 } 1802#endif 1803 } 1804 1805 /* everything is fine */ 1806 res = 0; 1807 1808out: 1809#ifdef _EVENT_HAVE_GETADDRINFO 1810 freeaddrinfo(ai); 1811#else 1812 fake_freeaddrinfo(ai); 1813#endif 1814 1815 return (res); 1816} 1817