~ubuntu-branches/ubuntu/utopic/forked-daapd/utopic-proposed

« back to all changes in this revision

Viewing changes to src/evrtsp/rtsp-libevent20.c

  • Committer: Package Import Robot
  • Author(s): Balint Reczey
  • Date: 2014-05-31 23:17:37 UTC
  • mfrom: (21.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20140531231737-6qc0k8zi8d9bqv09
Tags: 20.0+git20140530+gc740e6e-1
* Switch to new upstream using a development snapshot
* Adopt package in the name of the Debian Multimedia Maintainers.
  Thanks to Julien Blache for maintaining the package for long years!
  (Closes: #688538)
* Bump compat level to 9
* Update homepage to new upstream
* Add packaging VCS info
* Use libevent instead of Grand Central Dispatch (Closes: #644839, #739503)
* Drop patch for Libav 9 compatibility since upstream supports
  Libav 10 already (Closes: #739239)
* Switch debian/rules to debhelper style
* Build-depend on libavresample-dev
* Source init functions in init script
* Override false positive Lintian warnings about shlibs
* Bump standards version without changes

Show diffs side-by-side

added added

removed removed

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