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