1 /*
2 * RTSP protocol handler. This file is part of Shairport Sync
3 * Copyright (c) James Laird 2013
4
5 * Modifications associated with audio synchronization, mutithreading and
6 * metadata handling copyright (c) Mike Brady 2014-2020
7 * All rights reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or
14 * sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 * OTHER DEALINGS IN THE SOFTWARE.
28 */
29
30 #include <arpa/inet.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <memory.h>
34 #include <netdb.h>
35 #include <netinet/in.h>
36 #include <poll.h>
37 #include <pthread.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <sys/select.h>
42 #include <sys/socket.h>
43 #include <sys/stat.h>
44 #include <sys/types.h>
45 #include <unistd.h>
46
47 #include "config.h"
48
49 #ifdef CONFIG_OPENSSL
50 #include <openssl/md5.h>
51 #endif
52
53 #ifdef CONFIG_MBEDTLS
54 #include <mbedtls/md5.h>
55 #include <mbedtls/version.h>
56 #endif
57
58 #ifdef CONFIG_POLARSSL
59 #include <polarssl/md5.h>
60 #endif
61
62 #include "common.h"
63 #include "player.h"
64 #include "rtp.h"
65 #include "rtsp.h"
66
67 #ifdef CONFIG_METADATA_HUB
68 #include "metadata_hub.h"
69 #endif
70
71 #ifdef CONFIG_MQTT
72 #include "mqtt.h"
73 #endif
74
75 #ifdef AF_INET6
76 #define INETx_ADDRSTRLEN INET6_ADDRSTRLEN
77 #else
78 #define INETx_ADDRSTRLEN INET_ADDRSTRLEN
79 #endif
80
81 #define METADATA_SNDBUF (4 * 1024 * 1024)
82
83 enum rtsp_read_request_response {
84 rtsp_read_request_response_ok,
85 rtsp_read_request_response_immediate_shutdown_requested,
86 rtsp_read_request_response_bad_packet,
87 rtsp_read_request_response_channel_closed,
88 rtsp_read_request_response_read_error,
89 rtsp_read_request_response_error
90 };
91
92 rtsp_conn_info *playing_conn;
93 rtsp_conn_info **conns;
94
95 int metadata_running = 0;
96
97 // always lock use this when accessing the playing conn value
98 static pthread_mutex_t playing_conn_lock = PTHREAD_MUTEX_INITIALIZER;
99
100 // every time we want to retain or release a reference count, lock it with this
101 // if a reference count is read as zero, it means the it's being deallocated.
102 static pthread_mutex_t reference_counter_lock = PTHREAD_MUTEX_INITIALIZER;
103
104 // only one thread is allowed to use the player at once.
105 // it monitors the request variable (at least when interrupted)
106 // static pthread_mutex_t playing_mutex = PTHREAD_MUTEX_INITIALIZER;
107 // static int please_shutdown = 0;
108 // static pthread_t playing_thread = 0;
109
110 int RTSP_connection_index = 1;
111
112 #ifdef CONFIG_METADATA
113 typedef struct {
114 pthread_mutex_t pc_queue_lock;
115 pthread_cond_t pc_queue_item_added_signal;
116 pthread_cond_t pc_queue_item_removed_signal;
117 char *name;
118 size_t item_size; // number of bytes in each item
119 uint32_t count; // number of items in the queue
120 uint32_t capacity; // maximum number of items
121 uint32_t toq; // first item to take
122 uint32_t eoq; // free space at end of queue
123 void *items; // a pointer to where the items are actually stored
124 } pc_queue; // producer-consumer queue
125 #endif
126
127 static int msg_indexes = 1;
128
129 typedef struct {
130 int index_number;
131 uint32_t referenceCount; // we might start using this...
132 unsigned int nheaders;
133 char *name[16];
134 char *value[16];
135
136 int contentlength;
137 char *content;
138
139 // for requests
140 char method[16];
141
142 // for responses
143 int respcode;
144 } rtsp_message;
145
146 #ifdef CONFIG_METADATA
147 typedef struct {
148 uint32_t type;
149 uint32_t code;
150 char *data;
151 uint32_t length;
152 rtsp_message *carrier;
153 } metadata_package;
154
pc_queue_init(pc_queue * the_queue,char * items,size_t item_size,uint32_t number_of_items,const char * name)155 void pc_queue_init(pc_queue *the_queue, char *items, size_t item_size, uint32_t number_of_items,
156 const char *name) {
157 if (name)
158 debug(2, "Creating metadata queue \"%s\".", name);
159 else
160 debug(1, "Creating an unnamed metadata queue.");
161 pthread_mutex_init(&the_queue->pc_queue_lock, NULL);
162 pthread_cond_init(&the_queue->pc_queue_item_added_signal, NULL);
163 pthread_cond_init(&the_queue->pc_queue_item_removed_signal, NULL);
164 the_queue->item_size = item_size;
165 the_queue->items = items;
166 the_queue->count = 0;
167 the_queue->capacity = number_of_items;
168 the_queue->toq = 0;
169 the_queue->eoq = 0;
170 if (name == NULL)
171 the_queue->name = NULL;
172 else
173 the_queue->name = strdup(name);
174 }
175
pc_queue_delete(pc_queue * the_queue)176 void pc_queue_delete(pc_queue *the_queue) {
177 if (the_queue->name)
178 debug(2, "Deleting metadata queue \"%s\".", the_queue->name);
179 else
180 debug(1, "Deleting an unnamed metadata queue.");
181 if (the_queue->name != NULL)
182 free(the_queue->name);
183 // debug(2, "destroying pc_queue_item_removed_signal");
184 pthread_cond_destroy(&the_queue->pc_queue_item_removed_signal);
185 // debug(2, "destroying pc_queue_item_added_signal");
186 pthread_cond_destroy(&the_queue->pc_queue_item_added_signal);
187 // debug(2, "destroying pc_queue_lock");
188 pthread_mutex_destroy(&the_queue->pc_queue_lock);
189 // debug(2, "destroying signals and locks done");
190 }
191
192 int send_metadata(uint32_t type, uint32_t code, char *data, uint32_t length, rtsp_message *carrier,
193 int block);
194
send_ssnc_metadata(uint32_t code,char * data,uint32_t length,int block)195 int send_ssnc_metadata(uint32_t code, char *data, uint32_t length, int block) {
196 return send_metadata('ssnc', code, data, length, NULL, block);
197 }
198
pc_queue_cleanup_handler(void * arg)199 void pc_queue_cleanup_handler(void *arg) {
200 // debug(1, "pc_queue_cleanup_handler called.");
201 pc_queue *the_queue = (pc_queue *)arg;
202 int rc = pthread_mutex_unlock(&the_queue->pc_queue_lock);
203 if (rc)
204 debug(1, "Error unlocking for pc_queue_add_item or pc_queue_get_item.");
205 }
206
pc_queue_add_item(pc_queue * the_queue,const void * the_stuff,int block)207 int pc_queue_add_item(pc_queue *the_queue, const void *the_stuff, int block) {
208 int response = 0;
209 int rc;
210 if (the_queue) {
211 if (block == 0) {
212 rc = debug_mutex_lock(&the_queue->pc_queue_lock, 10000, 2);
213 if (rc == EBUSY)
214 return EBUSY;
215 } else
216 rc = pthread_mutex_lock(&the_queue->pc_queue_lock);
217 if (rc)
218 debug(1, "Error locking for pc_queue_add_item");
219 pthread_cleanup_push(pc_queue_cleanup_handler, (void *)the_queue);
220 // leave this out if you want this to return if the queue is already full
221 // irrespective of the block flag.
222 /*
223 while (the_queue->count == the_queue->capacity) {
224 rc = pthread_cond_wait(&the_queue->pc_queue_item_removed_signal,
225 &the_queue->pc_queue_lock); if (rc) debug(1, "Error waiting for item to be removed");
226 }
227 */
228 if (the_queue->count < the_queue->capacity) {
229 uint32_t i = the_queue->eoq;
230 void *p = the_queue->items + the_queue->item_size * i;
231 // void * p = &the_queue->qbase + the_queue->item_size*the_queue->eoq;
232 memcpy(p, the_stuff, the_queue->item_size);
233
234 // update the pointer
235 i++;
236 if (i == the_queue->capacity)
237 // fold pointer if necessary
238 i = 0;
239 the_queue->eoq = i;
240 the_queue->count++;
241 // debug(2,"metadata queue+ \"%s\" %d/%d.", the_queue->name, the_queue->count,
242 // the_queue->capacity);
243 if (the_queue->count == the_queue->capacity)
244 debug(3, "metadata queue \"%s\": is now full with %d items in it!", the_queue->name,
245 the_queue->count);
246 rc = pthread_cond_signal(&the_queue->pc_queue_item_added_signal);
247 if (rc)
248 debug(1, "metadata queue \"%s\": error signalling after pc_queue_add_item",
249 the_queue->name);
250 } else {
251 response = EWOULDBLOCK; // a bit arbitrary, this.
252 debug(3,
253 "metadata queue \"%s\": is already full with %d items in it. Not adding this item to "
254 "the queue.",
255 the_queue->name, the_queue->count);
256 }
257 pthread_cleanup_pop(1); // unlock the queue lock.
258 } else {
259 debug(1, "Adding an item to a NULL queue");
260 }
261 return response;
262 }
263
pc_queue_get_item(pc_queue * the_queue,void * the_stuff)264 int pc_queue_get_item(pc_queue *the_queue, void *the_stuff) {
265 int rc;
266 if (the_queue) {
267 rc = pthread_mutex_lock(&the_queue->pc_queue_lock);
268 if (rc)
269 debug(1, "metadata queue \"%s\": error locking for pc_queue_get_item", the_queue->name);
270 pthread_cleanup_push(pc_queue_cleanup_handler, (void *)the_queue);
271 while (the_queue->count == 0) {
272 rc = pthread_cond_wait(&the_queue->pc_queue_item_added_signal, &the_queue->pc_queue_lock);
273 if (rc)
274 debug(1, "metadata queue \"%s\": error waiting for item to be added", the_queue->name);
275 }
276 uint32_t i = the_queue->toq;
277 // void * p = &the_queue->qbase + the_queue->item_size*the_queue->toq;
278 void *p = the_queue->items + the_queue->item_size * i;
279 memcpy(the_stuff, p, the_queue->item_size);
280
281 // update the pointer
282 i++;
283 if (i == the_queue->capacity)
284 // fold pointer if necessary
285 i = 0;
286 the_queue->toq = i;
287 the_queue->count--;
288 debug(3, "metadata queue- \"%s\" %d/%d.", the_queue->name, the_queue->count,
289 the_queue->capacity);
290 rc = pthread_cond_signal(&the_queue->pc_queue_item_removed_signal);
291 if (rc)
292 debug(1, "metadata queue \"%s\": error signalling after pc_queue_get_item", the_queue->name);
293 pthread_cleanup_pop(1); // unlock the queue lock.
294 } else {
295 debug(1, "Removing an item from a NULL queue");
296 }
297 return 0;
298 }
299
300 #endif
301
have_player(rtsp_conn_info * conn)302 int have_player(rtsp_conn_info *conn) {
303 int response = 0;
304 debug_mutex_lock(&playing_conn_lock, 1000000, 3);
305 if (playing_conn == conn) // this connection definitely has the play lock
306 response = 1;
307 debug_mutex_unlock(&playing_conn_lock, 3);
308 return response;
309 }
310
player_watchdog_thread_cleanup_handler(void * arg)311 void player_watchdog_thread_cleanup_handler(void *arg) {
312 rtsp_conn_info *conn = (rtsp_conn_info *)arg;
313 debug(3, "Connection %d: Watchdog Exit.", conn->connection_number);
314 }
315
player_watchdog_thread_code(void * arg)316 void *player_watchdog_thread_code(void *arg) {
317 pthread_cleanup_push(player_watchdog_thread_cleanup_handler, arg);
318 rtsp_conn_info *conn = (rtsp_conn_info *)arg;
319 do {
320 usleep(2000000); // check every two seconds
321 // debug(3, "Connection %d: Check the thread is doing something...", conn->connection_number);
322 if ((config.dont_check_timeout == 0) && (config.timeout != 0)) {
323 debug_mutex_lock(&conn->watchdog_mutex, 1000, 0);
324 uint64_t last_watchdog_bark_time = conn->watchdog_bark_time;
325 debug_mutex_unlock(&conn->watchdog_mutex, 0);
326 if (last_watchdog_bark_time != 0) {
327 uint64_t time_since_last_bark =
328 (get_absolute_time_in_ns() - last_watchdog_bark_time) / 1000000000;
329 uint64_t ct = config.timeout; // go from int to 64-bit int
330
331 if (time_since_last_bark >= ct) {
332 conn->watchdog_barks++;
333 if (conn->watchdog_barks == 1) {
334 // debuglev = 3; // tell us everything.
335 debug(1,
336 "Connection %d: As Yeats almost said, \"Too long a silence / can make a stone "
337 "of the heart\".",
338 conn->connection_number);
339 conn->stop = 1;
340 pthread_cancel(conn->thread);
341 } else if (conn->watchdog_barks == 3) {
342 if ((config.cmd_unfixable) && (conn->unfixable_error_reported == 0)) {
343 conn->unfixable_error_reported = 1;
344 command_execute(config.cmd_unfixable, "unable_to_cancel_play_session", 1);
345 } else {
346 warn("an unrecoverable error, \"unable_to_cancel_play_session\", has been detected.",
347 conn->connection_number);
348 }
349 }
350 }
351 }
352 }
353 } while (1);
354 pthread_cleanup_pop(0); // should never happen
355 pthread_exit(NULL);
356 }
357
358 void ask_other_rtsp_conversation_threads_to_stop(pthread_t except_this_thread);
359
rtsp_request_shutdown_stream(void)360 void rtsp_request_shutdown_stream(void) {
361 debug(1, "Request to shut down all rtsp conversation threads");
362 ask_other_rtsp_conversation_threads_to_stop(0); // i.e. ask all playing threads to stop
363 }
364
365 // keep track of the threads we have spawned so we can join() them
366 static int nconns = 0;
track_thread(rtsp_conn_info * conn)367 static void track_thread(rtsp_conn_info *conn) {
368 conns = realloc(conns, sizeof(rtsp_conn_info *) * (nconns + 1));
369 if (conns) {
370 conns[nconns] = conn;
371 nconns++;
372 } else {
373 die("could not reallocate memnory for \"conns\" in rtsp.c.");
374 }
375 }
376
cancel_all_RTSP_threads(void)377 void cancel_all_RTSP_threads(void) {
378 int i;
379 for (i = 0; i < nconns; i++) {
380 debug(2, "Connection %d: cancelling.", conns[i]->connection_number);
381 pthread_cancel(conns[i]->thread);
382 }
383 for (i = 0; i < nconns; i++) {
384 debug(2, "Connection %d: joining.", conns[i]->connection_number);
385 pthread_join(conns[i]->thread, NULL);
386 free(conns[i]);
387 }
388 }
389
cleanup_threads(void)390 void cleanup_threads(void) {
391 void *retval;
392 int i;
393 // debug(2, "culling threads.");
394 for (i = 0; i < nconns;) {
395 if (conns[i]->running == 0) {
396 debug(3, "found RTSP connection thread %d in a non-running state.",
397 conns[i]->connection_number);
398 pthread_join(conns[i]->thread, &retval);
399 debug(3, "RTSP connection thread %d deleted...", conns[i]->connection_number);
400 free(conns[i]);
401 nconns--;
402 if (nconns)
403 conns[i] = conns[nconns];
404 } else {
405 i++;
406 }
407 }
408 }
409
410 // ask all rtsp_conversation threads to stop -- there should be at most one, but
411 // ya never know.
412
ask_other_rtsp_conversation_threads_to_stop(pthread_t except_this_thread)413 void ask_other_rtsp_conversation_threads_to_stop(pthread_t except_this_thread) {
414 int i;
415 debug(1, "asking playing threads to stop");
416 for (i = 0; i < nconns; i++) {
417 if (((except_this_thread == 0) || (pthread_equal(conns[i]->thread, except_this_thread) == 0)) &&
418 (conns[i]->running != 0)) {
419 pthread_cancel(conns[i]->thread);
420 pthread_join(conns[i]->thread, NULL);
421 debug(1, "Connection %d: asked to stop.", conns[i]->connection_number);
422 // conns[i]->stop = 1;
423 // pthread_kill(conns[i]->thread, SIGUSR1);
424 }
425 }
426 }
427
428 // park a null at the line ending, and return the next line pointer
429 // accept \r, \n, or \r\n
nextline(char * in,int inbuf)430 static char *nextline(char *in, int inbuf) {
431 char *out = NULL;
432 while (inbuf) {
433 if (*in == '\r') {
434 *in++ = 0;
435 out = in;
436 inbuf--;
437 }
438 if ((*in == '\n') && (inbuf)) {
439 *in++ = 0;
440 out = in;
441 }
442
443 if (out)
444 break;
445
446 in++;
447 inbuf--;
448 }
449 return out;
450 }
451
msg_retain(rtsp_message * msg)452 void msg_retain(rtsp_message *msg) {
453 int rc = pthread_mutex_lock(&reference_counter_lock);
454 if (rc)
455 debug(1, "Error %d locking reference counter lock");
456 if (msg > (rtsp_message *)0x00010000) {
457 msg->referenceCount++;
458 debug(3, "msg_free increment reference counter message %d to %d.", msg->index_number,
459 msg->referenceCount);
460 // debug(1,"msg_retain -- item %d reference count %d.", msg->index_number, msg->referenceCount);
461 rc = pthread_mutex_unlock(&reference_counter_lock);
462 if (rc)
463 debug(1, "Error %d unlocking reference counter lock");
464 } else {
465 debug(1, "invalid rtsp_message pointer 0x%x passed to retain", (uintptr_t)msg);
466 }
467 }
468
msg_init(void)469 rtsp_message *msg_init(void) {
470 rtsp_message *msg = malloc(sizeof(rtsp_message));
471 if (msg) {
472 memset(msg, 0, sizeof(rtsp_message));
473 msg->referenceCount = 1; // from now on, any access to this must be protected with the lock
474 msg->index_number = msg_indexes++;
475 debug(3, "msg_init message %d", msg->index_number);
476 } else {
477 die("msg_init -- can not allocate memory for rtsp_message %d.", msg_indexes);
478 }
479 // debug(1,"msg_init -- create item %d.", msg->index_number);
480 return msg;
481 }
482
msg_add_header(rtsp_message * msg,char * name,char * value)483 int msg_add_header(rtsp_message *msg, char *name, char *value) {
484 if (msg->nheaders >= sizeof(msg->name) / sizeof(char *)) {
485 warn("too many headers?!");
486 return 1;
487 }
488
489 msg->name[msg->nheaders] = strdup(name);
490 msg->value[msg->nheaders] = strdup(value);
491 msg->nheaders++;
492
493 return 0;
494 }
495
msg_get_header(rtsp_message * msg,char * name)496 char *msg_get_header(rtsp_message *msg, char *name) {
497 unsigned int i;
498 for (i = 0; i < msg->nheaders; i++)
499 if (!strcasecmp(msg->name[i], name))
500 return msg->value[i];
501 return NULL;
502 }
503
debug_print_msg_headers(int level,rtsp_message * msg)504 void debug_print_msg_headers(int level, rtsp_message *msg) {
505 unsigned int i;
506 for (i = 0; i < msg->nheaders; i++) {
507 debug(level, " Type: \"%s\", content: \"%s\"", msg->name[i], msg->value[i]);
508 }
509 }
510
511 /*
512 static void debug_print_msg_content(int level, rtsp_message *msg) {
513 if (msg->contentlength) {
514 char *obf = malloc(msg->contentlength * 2 + 1);
515 if (obf) {
516 char *obfp = obf;
517 int obfc;
518 for (obfc = 0; obfc < msg->contentlength; obfc++) {
519 snprintf(obfp, 3, "%02X", msg->content[obfc]);
520 obfp += 2;
521 };
522 *obfp = 0;
523 debug(level, "Content (hex): \"%s\"", obf);
524 free(obf);
525 } else {
526 debug(level, "Can't allocate space for debug buffer");
527 }
528 } else {
529 debug(level, "No content");
530 }
531 }
532 */
533
msg_free(rtsp_message ** msgh)534 void msg_free(rtsp_message **msgh) {
535 debug_mutex_lock(&reference_counter_lock, 1000, 0);
536 if (*msgh > (rtsp_message *)0x00010000) {
537 rtsp_message *msg = *msgh;
538 msg->referenceCount--;
539 if (msg->referenceCount)
540 debug(3, "msg_free decrement reference counter message %d to %d", msg->index_number,
541 msg->referenceCount);
542 if (msg->referenceCount == 0) {
543 unsigned int i;
544 for (i = 0; i < msg->nheaders; i++) {
545 free(msg->name[i]);
546 free(msg->value[i]);
547 }
548 if (msg->content)
549 free(msg->content);
550 // debug(1,"msg_free item %d -- free.",msg->index_number);
551 uintptr_t index = (msg->index_number) & 0xFFFF;
552 if (index == 0)
553 index = 0x10000; // ensure it doesn't fold to zero.
554 *msgh =
555 (rtsp_message *)(index); // put a version of the index number of the freed message in here
556 debug(3, "msg_free freed message %d", msg->index_number);
557 free(msg);
558 } else {
559 // debug(1,"msg_free item %d -- decrement reference to
560 // %d.",msg->index_number,msg->referenceCount);
561 }
562 } else if (*msgh != NULL) {
563 debug(1,
564 "msg_free: error attempting to free an allocated but already-freed rtsp_message, number "
565 "%d.",
566 (uintptr_t)*msgh);
567 }
568 debug_mutex_unlock(&reference_counter_lock, 0);
569 }
570
msg_handle_line(rtsp_message ** pmsg,char * line)571 int msg_handle_line(rtsp_message **pmsg, char *line) {
572 rtsp_message *msg = *pmsg;
573
574 if (!msg) {
575 msg = msg_init();
576 *pmsg = msg;
577 char *sp, *p;
578 sp = NULL; // this is to quieten a compiler warning
579
580 debug(3, "RTSP Message Received: \"%s\".", line);
581
582 p = strtok_r(line, " ", &sp);
583 if (!p)
584 goto fail;
585 strncpy(msg->method, p, sizeof(msg->method) - 1);
586
587 p = strtok_r(NULL, " ", &sp);
588 if (!p)
589 goto fail;
590
591 p = strtok_r(NULL, " ", &sp);
592 if (!p)
593 goto fail;
594 if (strcmp(p, "RTSP/1.0"))
595 goto fail;
596
597 return -1;
598 }
599
600 if (strlen(line)) {
601 char *p;
602 p = strstr(line, ": ");
603 if (!p) {
604 warn("bad header: >>%s<<", line);
605 goto fail;
606 }
607 *p = 0;
608 p += 2;
609 msg_add_header(msg, line, p);
610 debug(3, " %s: %s.", line, p);
611 return -1;
612 } else {
613 char *cl = msg_get_header(msg, "Content-Length");
614 if (cl)
615 return atoi(cl);
616 else
617 return 0;
618 }
619
620 fail:
621 debug(3, "msg_handle_line fail");
622 msg_free(pmsg);
623 *pmsg = NULL;
624 return 0;
625 }
626
rtsp_read_request(rtsp_conn_info * conn,rtsp_message ** the_packet)627 enum rtsp_read_request_response rtsp_read_request(rtsp_conn_info *conn, rtsp_message **the_packet) {
628
629 *the_packet = NULL; // need this for error handling
630
631 enum rtsp_read_request_response reply = rtsp_read_request_response_ok;
632 ssize_t buflen = 4096;
633 int release_buffer = 0; // on exit, don't deallocate the buffer if everything was okay
634 char *buf = malloc(buflen + 1); // add a NUL at the end
635 if (!buf) {
636 warn("Connection %d: rtsp_read_request: can't get a buffer.", conn->connection_number);
637 return (rtsp_read_request_response_error);
638 }
639 pthread_cleanup_push(malloc_cleanup, buf);
640 ssize_t nread;
641 ssize_t inbuf = 0;
642 int msg_size = -1;
643
644 while (msg_size < 0) {
645 if (conn->stop != 0) {
646 debug(3, "Connection %d: shutdown requested.", conn->connection_number);
647 reply = rtsp_read_request_response_immediate_shutdown_requested;
648 goto shutdown;
649 }
650
651 nread = read(conn->fd, buf + inbuf, buflen - inbuf);
652
653 if (nread == 0) {
654 // a blocking read that returns zero means eof -- implies connection closed
655 debug(3, "Connection %d: -- connection closed.", conn->connection_number);
656 reply = rtsp_read_request_response_channel_closed;
657 goto shutdown;
658 }
659
660 if (nread < 0) {
661 if (errno == EINTR)
662 continue;
663 if (errno == EAGAIN) {
664 debug(1, "Connection %d: getting Error 11 -- EAGAIN from a blocking read!",
665 conn->connection_number);
666 continue;
667 }
668 if (errno != ECONNRESET) {
669 char errorstring[1024];
670 strerror_r(errno, (char *)errorstring, sizeof(errorstring));
671 debug(1, "Connection %d: rtsp_read_request_response_read_error %d: \"%s\".",
672 conn->connection_number, errno, (char *)errorstring);
673 }
674 reply = rtsp_read_request_response_read_error;
675 goto shutdown;
676 }
677
678 /* // this outputs the message received
679 {
680 void *pt = malloc(nread+1);
681 memset(pt, 0, nread+1);
682 memcpy(pt, buf + inbuf, nread);
683 debug(1, "Incoming string on port: \"%s\"",pt);
684 free(pt);
685 }
686 */
687
688 inbuf += nread;
689
690 char *next;
691 while (msg_size < 0 && (next = nextline(buf, inbuf))) {
692 msg_size = msg_handle_line(the_packet, buf);
693
694 if (!(*the_packet)) {
695 debug(1, "Connection %d: rtsp_read_request can't find an RTSP header.",
696 conn->connection_number);
697 reply = rtsp_read_request_response_bad_packet;
698 goto shutdown;
699 }
700
701 inbuf -= next - buf;
702 if (inbuf)
703 memmove(buf, next, inbuf);
704 }
705 }
706
707 if (msg_size > buflen) {
708 buf = realloc(buf, msg_size + 1);
709 if (!buf) {
710 warn("Connection %d: too much content.", conn->connection_number);
711 reply = rtsp_read_request_response_error;
712 goto shutdown;
713 }
714 buflen = msg_size;
715 }
716
717 uint64_t threshold_time =
718 get_absolute_time_in_ns() + ((uint64_t)15000000000); // i.e. fifteen seconds from now
719 int warning_message_sent = 0;
720
721 const size_t max_read_chunk = 1024 * 1024 / 16;
722 while (inbuf < msg_size) {
723
724 // we are going to read the stream in chunks and time how long it takes to
725 // do so.
726 // If it's taking too long, (and we find out about it), we will send an
727 // error message as
728 // metadata
729
730 if (warning_message_sent == 0) {
731 uint64_t time_now = get_absolute_time_in_ns();
732 if (time_now > threshold_time) { // it's taking too long
733 debug(1, "Error receiving metadata from source -- transmission seems "
734 "to be stalled.");
735 #ifdef CONFIG_METADATA
736 send_ssnc_metadata('stal', NULL, 0, 1);
737 #endif
738 warning_message_sent = 1;
739 }
740 }
741
742 if (conn->stop != 0) {
743 debug(1, "RTSP shutdown requested.");
744 reply = rtsp_read_request_response_immediate_shutdown_requested;
745 goto shutdown;
746 }
747 size_t read_chunk = msg_size - inbuf;
748 if (read_chunk > max_read_chunk)
749 read_chunk = max_read_chunk;
750 usleep(80000); // wait about 80 milliseconds between reads of up to about 64 kB
751 nread = read(conn->fd, buf + inbuf, read_chunk);
752 if (!nread) {
753 reply = rtsp_read_request_response_error;
754 goto shutdown;
755 }
756 if (nread < 0) {
757 if (errno == EINTR)
758 continue;
759 if (errno == EAGAIN) {
760 debug(1, "Getting Error 11 -- EAGAIN from a blocking read!");
761 continue;
762 }
763 if (errno != ECONNRESET) {
764 char errorstring[1024];
765 strerror_r(errno, (char *)errorstring, sizeof(errorstring));
766 debug(1, "Connection %d: rtsp_read_request_response_read_error %d: \"%s\".",
767 conn->connection_number, errno, (char *)errorstring);
768 }
769 reply = rtsp_read_request_response_read_error;
770 goto shutdown;
771 }
772 inbuf += nread;
773 }
774
775 rtsp_message *msg = *the_packet;
776 msg->contentlength = inbuf;
777 msg->content = buf;
778 char *jp = inbuf + buf;
779 *jp = '\0';
780 *the_packet = msg;
781 shutdown:
782 if (reply != rtsp_read_request_response_ok) {
783 msg_free(the_packet);
784 release_buffer = 1; // allow the buffer to be released
785 }
786 pthread_cleanup_pop(release_buffer);
787 return reply;
788 }
789
msg_write_response(int fd,rtsp_message * resp)790 int msg_write_response(int fd, rtsp_message *resp) {
791 char pkt[2048];
792 int pktfree = sizeof(pkt);
793 char *p = pkt;
794 int n;
795 unsigned int i;
796
797 n = snprintf(p, pktfree, "RTSP/1.0 %d %s\r\n", resp->respcode,
798 resp->respcode == 200 ? "OK" : "Unauthorized");
799 // debug(1, "sending response: %s", pkt);
800 pktfree -= n;
801 p += n;
802
803 for (i = 0; i < resp->nheaders; i++) {
804 // debug(3, " %s: %s.", resp->name[i], resp->value[i]);
805 n = snprintf(p, pktfree, "%s: %s\r\n", resp->name[i], resp->value[i]);
806 pktfree -= n;
807 p += n;
808 if (pktfree <= 1024) {
809 debug(1, "Attempted to write overlong RTSP packet 1");
810 return -1;
811 }
812 }
813
814 // Here, if there's content, write the Content-Length header ...
815
816 if (resp->contentlength) {
817 debug(1, "Responding with content of length %d", resp->contentlength);
818 n = snprintf(p, pktfree, "Content-Length: %d\r\n", resp->contentlength);
819 pktfree -= n;
820 p += n;
821 if (pktfree <= 1024) {
822 debug(1, "Attempted to write overlong RTSP packet 2");
823 return -2;
824 }
825 debug(1, "Content is \"%s\"", resp->content);
826 memcpy(p, resp->content, resp->contentlength);
827 pktfree -= resp->contentlength;
828 p += resp->contentlength;
829 }
830
831 n = snprintf(p, pktfree, "\r\n");
832 pktfree -= n;
833 p += n;
834
835 if (pktfree <= 1024) {
836 debug(1, "Attempted to write overlong RTSP packet 3");
837 return -3;
838 }
839 ssize_t reply = write(fd, pkt, p - pkt);
840 if (reply == -1) {
841 char errorstring[1024];
842 strerror_r(errno, (char *)errorstring, sizeof(errorstring));
843 debug(1, "msg_write_response error %d: \"%s\".", errno, (char *)errorstring);
844 return -4;
845 }
846 if (reply != p - pkt) {
847 debug(1, "msg_write_response error -- requested bytes: %d not fully written: %d.", p - pkt,
848 reply);
849 return -5;
850 }
851 return 0;
852 }
853
handle_record(rtsp_conn_info * conn,rtsp_message * req,rtsp_message * resp)854 void handle_record(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
855 debug(2, "Connection %d: RECORD", conn->connection_number);
856 if (have_player(conn)) {
857 if (conn->player_thread)
858 warn("Connection %d: RECORD: Duplicate RECORD message -- ignored", conn->connection_number);
859 else
860 player_play(conn); // the thread better be 0
861
862 resp->respcode = 200;
863 // I think this is for telling the client what the absolute minimum latency
864 // actually is,
865 // and when the client specifies a latency, it should be added to this figure.
866
867 // Thus, [the old version of] AirPlay's latency figure of 77175, when added to 11025 gives you
868 // exactly 88200
869 // and iTunes' latency figure of 88553, when added to 11025 gives you 99578,
870 // pretty close to the 99400 we guessed.
871
872 msg_add_header(resp, "Audio-Latency", "11025");
873
874 char *p;
875 uint32_t rtptime = 0;
876 char *hdr = msg_get_header(req, "RTP-Info");
877
878 if (hdr) {
879 // debug(1,"FLUSH message received: \"%s\".",hdr);
880 // get the rtp timestamp
881 p = strstr(hdr, "rtptime=");
882 if (p) {
883 p = strchr(p, '=');
884 if (p) {
885 rtptime = uatoi(p + 1); // unsigned integer -- up to 2^32-1
886 // rtptime--;
887 // debug(1,"RTSP Flush Requested by handle_record: %u.",rtptime);
888 player_flush(rtptime, conn);
889 }
890 }
891 }
892 } else {
893 warn("Connection %d RECORD received without having the player (no ANNOUNCE?)",
894 conn->connection_number);
895 resp->respcode = 451;
896 }
897 }
898
handle_options(rtsp_conn_info * conn,rtsp_message * req,rtsp_message * resp)899 void handle_options(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *req,
900 rtsp_message *resp) {
901 debug(3, "Connection %d: OPTIONS", conn->connection_number);
902 resp->respcode = 200;
903 msg_add_header(resp, "Public",
904 "ANNOUNCE, SETUP, RECORD, "
905 "PAUSE, FLUSH, TEARDOWN, "
906 "OPTIONS, GET_PARAMETER, SET_PARAMETER");
907 }
908
handle_teardown(rtsp_conn_info * conn,rtsp_message * req,rtsp_message * resp)909 void handle_teardown(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *req,
910 rtsp_message *resp) {
911 debug(2, "Connection %d: TEARDOWN", conn->connection_number);
912 if (have_player(conn)) {
913 resp->respcode = 200;
914 msg_add_header(resp, "Connection", "close");
915 debug(
916 3,
917 "TEARDOWN: synchronously terminating the player thread of RTSP conversation thread %d (2).",
918 conn->connection_number);
919 player_stop(conn);
920 debug(3, "TEARDOWN: successful termination of playing thread of RTSP conversation thread %d.",
921 conn->connection_number);
922 } else {
923 warn("Connection %d TEARDOWN received without having the player (no ANNOUNCE?)",
924 conn->connection_number);
925 resp->respcode = 451;
926 }
927 }
928
handle_flush(rtsp_conn_info * conn,rtsp_message * req,rtsp_message * resp)929 void handle_flush(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
930 debug(3, "Connection %d: FLUSH", conn->connection_number);
931 if (have_player(conn)) {
932 char *p = NULL;
933 uint32_t rtptime = 0;
934 char *hdr = msg_get_header(req, "RTP-Info");
935
936 if (hdr) {
937 // debug(1,"FLUSH message received: \"%s\".",hdr);
938 // get the rtp timestamp
939 p = strstr(hdr, "rtptime=");
940 if (p) {
941 p = strchr(p, '=');
942 if (p)
943 rtptime = uatoi(p + 1); // unsigned integer -- up to 2^32-1
944 }
945 }
946 // debug(1,"RTSP Flush Requested: %u.",rtptime);
947
948 // the following is now done better by the player_flush routine as a 'pfls'
949 /*
950 #ifdef CONFIG_METADATA
951 if (p)
952 send_metadata('ssnc', 'flsr', p + 1, strlen(p + 1), req, 1);
953 else
954 send_metadata('ssnc', 'flsr', NULL, 0, NULL, 0);
955 #endif
956 */
957
958 player_flush(rtptime, conn); // will not crash even it there is no player thread.
959 resp->respcode = 200;
960
961 } else {
962 warn("Connection %d FLUSH received without having the player (no ANNOUNCE?)",
963 conn->connection_number);
964 resp->respcode = 451;
965 }
966 }
967
handle_setup(rtsp_conn_info * conn,rtsp_message * req,rtsp_message * resp)968 void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
969 debug(3, "Connection %d: SETUP", conn->connection_number);
970 resp->respcode = 451; // invalid arguments -- expect them
971 if (have_player(conn)) {
972 uint16_t cport, tport;
973 char *ar = msg_get_header(req, "Active-Remote");
974 if (ar) {
975 debug(2, "Connection %d: SETUP -- Active-Remote string seen: \"%s\".",
976 conn->connection_number, ar);
977 // get the active remote
978 if (conn->dacp_active_remote) // this is in case SETUP was previously called
979 free(conn->dacp_active_remote);
980 conn->dacp_active_remote = strdup(ar);
981 #ifdef CONFIG_METADATA
982 send_metadata('ssnc', 'acre', ar, strlen(ar), req, 1);
983 #endif
984 } else {
985 debug(2, "Connection %d: SETUP -- Note: no Active-Remote information the SETUP Record.",
986 conn->connection_number);
987 if (conn->dacp_active_remote) { // this is in case SETUP was previously called
988 free(conn->dacp_active_remote);
989 conn->dacp_active_remote = NULL;
990 }
991 }
992
993 ar = msg_get_header(req, "DACP-ID");
994 if (ar) {
995 debug(2, "Connection %d: SETUP -- DACP-ID string seen: \"%s\".", conn->connection_number, ar);
996 if (conn->dacp_id) // this is in case SETUP was previously called
997 free(conn->dacp_id);
998 conn->dacp_id = strdup(ar);
999 #ifdef CONFIG_METADATA
1000 send_metadata('ssnc', 'daid', ar, strlen(ar), req, 1);
1001 #endif
1002 } else {
1003 debug(2, "Connection %d: SETUP doesn't include DACP-ID string information.",
1004 conn->connection_number);
1005 if (conn->dacp_id) { // this is in case SETUP was previously called
1006 free(conn->dacp_id);
1007 conn->dacp_id = NULL;
1008 }
1009 }
1010
1011 char *hdr = msg_get_header(req, "Transport");
1012 if (hdr) {
1013 char *p;
1014 p = strstr(hdr, "control_port=");
1015 if (p) {
1016 p = strchr(p, '=') + 1;
1017 cport = atoi(p);
1018
1019 p = strstr(hdr, "timing_port=");
1020 if (p) {
1021 p = strchr(p, '=') + 1;
1022 tport = atoi(p);
1023
1024 if (conn->rtp_running) {
1025 if ((conn->remote_control_port != cport) || (conn->remote_timing_port != tport)) {
1026 warn("Connection %d: Duplicate SETUP message with different control (old %u, new %u) "
1027 "or "
1028 "timing (old %u, new "
1029 "%u) ports! This is probably fatal!",
1030 conn->connection_number, conn->remote_control_port, cport,
1031 conn->remote_timing_port, tport);
1032 } else {
1033 warn("Connection %d: Duplicate SETUP message with the same control (%u) and timing "
1034 "(%u) "
1035 "ports. This is "
1036 "probably not fatal.",
1037 conn->connection_number, conn->remote_control_port, conn->remote_timing_port);
1038 }
1039 } else {
1040 rtp_setup(&conn->local, &conn->remote, cport, tport, conn);
1041 }
1042 if (conn->local_audio_port != 0) {
1043
1044 char resphdr[256] = "";
1045 snprintf(resphdr, sizeof(resphdr),
1046 "RTP/AVP/"
1047 "UDP;unicast;interleaved=0-1;mode=record;control_port=%d;"
1048 "timing_port=%d;server_"
1049 "port=%d",
1050 conn->local_control_port, conn->local_timing_port, conn->local_audio_port);
1051
1052 msg_add_header(resp, "Transport", resphdr);
1053
1054 msg_add_header(resp, "Session", "1");
1055
1056 resp->respcode = 200; // it all worked out okay
1057 debug(1,
1058 "Connection %d: SETUP DACP-ID \"%s\" from %s to %s with UDP ports Control: "
1059 "%d, Timing: %d and Audio: %d.",
1060 conn->connection_number, conn->dacp_id, &conn->client_ip_string,
1061 &conn->self_ip_string, conn->local_control_port, conn->local_timing_port,
1062 conn->local_audio_port);
1063
1064 } else {
1065 debug(1, "Connection %d: SETUP seems to specify a null audio port.",
1066 conn->connection_number);
1067 }
1068 } else {
1069 debug(1, "Connection %d: SETUP doesn't specify a timing_port.", conn->connection_number);
1070 }
1071 } else {
1072 debug(1, "Connection %d: SETUP doesn't specify a control_port.", conn->connection_number);
1073 }
1074 } else {
1075 debug(1, "Connection %d: SETUP doesn't contain a Transport header.", conn->connection_number);
1076 }
1077 if (resp->respcode != 200) {
1078 debug(1, "Connection %d: SETUP error -- releasing the player lock.", conn->connection_number);
1079 debug_mutex_lock(&playing_conn_lock, 1000000, 3);
1080 if (playing_conn == conn) // if we have the player
1081 playing_conn = NULL; // let it go
1082 debug_mutex_unlock(&playing_conn_lock, 3);
1083 }
1084
1085 } else {
1086 warn("Connection %d SETUP received without having the player (no ANNOUNCE?)",
1087 conn->connection_number);
1088 }
1089 }
1090
1091 /*
1092 static void handle_ignore(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
1093 debug(1, "Connection thread %d: IGNORE", conn->connection_number);
1094 resp->respcode = 200;
1095 }
1096 */
1097
handle_set_parameter_parameter(rtsp_conn_info * conn,rtsp_message * req,rtsp_message * resp)1098 void handle_set_parameter_parameter(rtsp_conn_info *conn, rtsp_message *req,
1099 __attribute__((unused)) rtsp_message *resp) {
1100
1101 char *cp = req->content;
1102 int cp_left = req->contentlength;
1103 /*
1104 int k = cp_left;
1105 if (k>max_bytes)
1106 k = max_bytes;
1107 for (i = 0; i < k; i++)
1108 snprintf((char *)buf + 2 * i, 3, "%02x", cp[i]);
1109 debug(1, "handle_set_parameter_parameter: \"%s\".",buf);
1110 */
1111
1112 char *next;
1113 while (cp_left && cp) {
1114 next = nextline(cp, cp_left);
1115 // note: "next" will return NULL if there is no \r or \n or \r\n at the end of this
1116 // but we are always guaranteed that if cp is not null, it will be pointing to something
1117 // NUL-terminated
1118
1119 if (next)
1120 cp_left -= (next - cp);
1121 else
1122 cp_left = 0;
1123
1124 if (!strncmp(cp, "volume: ", strlen("volume: "))) {
1125 float volume = atof(cp + strlen("volume: "));
1126 // debug(2, "AirPlay request to set volume to: %f.", volume);
1127 player_volume(volume, conn);
1128 } else
1129 #ifdef CONFIG_METADATA
1130 if (!strncmp(cp, "progress: ", strlen("progress: "))) {
1131 char *progress = cp + strlen("progress: ");
1132 // debug(2, "progress: \"%s\"",progress); // rtpstampstart/rtpstampnow/rtpstampend 44100 per
1133 // second
1134 send_ssnc_metadata('prgr', progress, strlen(progress), 1);
1135
1136 } else
1137 #endif
1138 {
1139 debug(1, "unrecognised parameter: \"%s\" (%d)\n", cp, strlen(cp));
1140 }
1141 cp = next;
1142 }
1143 }
1144
1145 #ifdef CONFIG_METADATA
1146 // Metadata is not used by shairport-sync.
1147 // Instead we send all metadata to a fifo pipe, so that other apps can listen to
1148 // the pipe and use the metadata.
1149
1150 // We use two 4-character codes to identify each piece of data and we send the
1151 // data itself, if any,
1152 // in base64 form.
1153
1154 // The first 4-character code, called the "type", is either:
1155 // 'core' for all the regular metadadata coming from iTunes, etc., or
1156 // 'ssnc' (for 'shairport-sync') for all metadata coming from Shairport Sync
1157 // itself, such as
1158 // start/end delimiters, etc.
1159
1160 // For 'core' metadata, the second 4-character code is the 4-character metadata
1161 // code coming from
1162 // iTunes etc.
1163 // For 'ssnc' metadata, the second 4-character code is used to distinguish the
1164 // messages.
1165
1166 // Cover art is not tagged in the same way as other metadata, it seems, so is
1167 // sent as an 'ssnc' type
1168 // metadata message with the code 'PICT'
1169 // Here are the 'ssnc' codes defined so far:
1170 // 'PICT' -- the payload is a picture, either a JPEG or a PNG. Check the
1171 // first few bytes to see
1172 // which.
1173 // 'abeg' -- active mode entered. No arguments
1174 // 'aend' -- active mode exited. No arguments
1175 // 'pbeg' -- play stream begin. No arguments
1176 // 'pend' -- play stream end. No arguments
1177 // 'pfls' -- play stream flush. The argument is an unsigned 32-bit
1178 // frame number. It seems that all frames up to but not
1179 // including this frame are to be flushed.
1180 //
1181 // 'prsm' -- play stream resume. No arguments
1182 // `pffr` -- the first frame of a play session has been received and has been validly
1183 // timed.
1184 // 'pvol' -- play volume. The volume is sent as a string --
1185 // "airplay_volume,volume,lowest_volume,highest_volume"
1186 // volume, lowest_volume and highest_volume are given in dB.
1187 // The "airplay_volume" is what's sent to the player, and is from
1188 // 0.00 down to -30.00,
1189 // with -144.00 meaning mute.
1190 // This is linear on the volume control slider of iTunes or iOS
1191 // AirPlay.
1192 // 'prgr' -- progress -- this is metadata from AirPlay consisting of RTP
1193 // timestamps for the start
1194 // of the current play sequence, the current play point and the end of the
1195 // play sequence.
1196 // I guess the timestamps wrap at 2^32.
1197 // 'mdst' -- a sequence of metadata is about to start; will have, as data,
1198 // the rtptime associated with the metadata, if available
1199 // 'mden' -- a sequence of metadata has ended; will have, as data, the
1200 // rtptime associated with the metadata, if available
1201 // 'pcst' -- a picture is about to be sent; will have, as data, the rtptime
1202 // associated with the picture, if available
1203 // 'pcen' -- a picture has been sent; will have, as data, the rtptime
1204 // associated with the metadata, if available
1205 // 'snam' -- A device -- e.g. "Joe's iPhone" -- has opened a play session.
1206 // Specifically, it's the "X-Apple-Client-Name" string
1207 // 'snua' -- A "user agent" -- e.g. "iTunes/12..." -- has opened a play
1208 // session. Specifically, it's the "User-Agent" string
1209 // The next two two tokens are to facilitate remote control of the source.
1210 // There is some information at http://nto.github.io/AirPlay.html about
1211 // remote control of the source.
1212 //
1213 // 'daid' -- this is the source's DACP-ID (if it has one -- it's not
1214 // guaranteed), useful if you want to remotely control the source. Use this
1215 // string to identify the source's remote control on the network.
1216 // 'acre' -- this is the source's Active-Remote token, necessary if you want
1217 // to send commands to the source's remote control (if it has one).
1218 // `clip` -- the payload is the IP number of the client, i.e. the sender of audio.
1219 // Can be an IPv4 or an IPv6 number.
1220 // `svip` -- the payload is the IP number of the server, i.e. the player itself.
1221 // Can be an IPv4 or an IPv6 number.
1222 // `dapo` -- the payload is the port number (as text) on the server to which remote
1223 // control commands should be sent. It is 3689 for iTunes but varies for iOS devices.
1224
1225 // A special sub-protocol is used for sending large data items over UDP
1226 // If the payload exceeded 4 MB, it is chunked using the following format:
1227 // "ssnc", "chnk", packet_ix, packet_counts, packet_tag, packet_type, chunked_data.
1228 // Notice that the number of items is different to the standard
1229
1230 // including a simple base64 encoder to minimise malloc/free activity
1231
1232 // From Stack Overflow, with thanks:
1233 // http://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c
1234 // minor mods to make independent of C99.
1235 // more significant changes make it not malloc memory
1236 // needs to initialise the docoding table first
1237
1238 // add _so to end of name to avoid confusion with polarssl's implementation
1239
1240 static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
1241 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
1242 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
1243 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
1244 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
1245
1246 static size_t mod_table[] = {0, 2, 1};
1247
1248 // pass in a pointer to the data, its length, a pointer to the output buffer and
1249 // a pointer to an int
1250 // containing its maximum length
1251 // the actual length will be returned.
1252
base64_encode_so(const unsigned char * data,size_t input_length,char * encoded_data,size_t * output_length)1253 char *base64_encode_so(const unsigned char *data, size_t input_length, char *encoded_data,
1254 size_t *output_length) {
1255
1256 size_t calculated_output_length = 4 * ((input_length + 2) / 3);
1257 if (calculated_output_length > *output_length)
1258 return (NULL);
1259 *output_length = calculated_output_length;
1260
1261 size_t i, j;
1262 for (i = 0, j = 0; i < input_length;) {
1263
1264 uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0;
1265 uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0;
1266 uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0;
1267
1268 uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
1269
1270 encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
1271 encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
1272 encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
1273 encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
1274 }
1275
1276 for (i = 0; i < mod_table[input_length % 3]; i++)
1277 encoded_data[*output_length - 1 - i] = '=';
1278
1279 return encoded_data;
1280 }
1281
1282 // with thanks!
1283 //
1284
1285 static int fd = -1;
1286 // static int dirty = 0;
1287
1288 pc_queue metadata_queue;
1289 #define metadata_queue_size 500
1290 metadata_package metadata_queue_items[metadata_queue_size];
1291 pthread_t metadata_thread;
1292
1293 #ifdef CONFIG_METADATA_HUB
1294 pc_queue metadata_hub_queue;
1295 #define metadata_hub_queue_size 500
1296 metadata_package metadata_hub_queue_items[metadata_hub_queue_size];
1297 pthread_t metadata_hub_thread;
1298 #endif
1299
1300 #ifdef CONFIG_MQTT
1301 pc_queue metadata_mqtt_queue;
1302 #define metadata_mqtt_queue_size 500
1303 metadata_package metadata_mqtt_queue_items[metadata_mqtt_queue_size];
1304 pthread_t metadata_mqtt_thread;
1305 #endif
1306
1307 static int metadata_sock = -1;
1308 static struct sockaddr_in metadata_sockaddr;
1309 static char *metadata_sockmsg;
1310 pc_queue metadata_multicast_queue;
1311 #define metadata_multicast_queue_size 500
1312 metadata_package metadata_multicast_queue_items[metadata_queue_size];
1313 pthread_t metadata_multicast_thread;
1314
metadata_create_multicast_socket(void)1315 void metadata_create_multicast_socket(void) {
1316 if (config.metadata_enabled == 0)
1317 return;
1318
1319 // Unlike metadata pipe, socket is opened once and stays open,
1320 // so we can call it in create
1321 if (config.metadata_sockaddr && config.metadata_sockport) {
1322 metadata_sock = socket(AF_INET, SOCK_DGRAM, 0);
1323 if (metadata_sock < 0) {
1324 debug(1, "Could not open metadata socket");
1325 } else {
1326 int buffer_size = METADATA_SNDBUF;
1327 setsockopt(metadata_sock, SOL_SOCKET, SO_SNDBUF, &buffer_size, sizeof(buffer_size));
1328 bzero((char *)&metadata_sockaddr, sizeof(metadata_sockaddr));
1329 metadata_sockaddr.sin_family = AF_INET;
1330 metadata_sockaddr.sin_addr.s_addr = inet_addr(config.metadata_sockaddr);
1331 metadata_sockaddr.sin_port = htons(config.metadata_sockport);
1332 metadata_sockmsg = malloc(config.metadata_sockmsglength);
1333 if (metadata_sockmsg) {
1334 memset(metadata_sockmsg, 0, config.metadata_sockmsglength);
1335 } else {
1336 die("Could not malloc metadata multicast socket buffer");
1337 }
1338 }
1339 }
1340 }
1341
metadata_delete_multicast_socket(void)1342 void metadata_delete_multicast_socket(void) {
1343 if (config.metadata_enabled == 0)
1344 return;
1345 shutdown(metadata_sock, SHUT_RDWR); // we want to immediately deallocate the buffer
1346 close(metadata_sock);
1347 if (metadata_sockmsg)
1348 free(metadata_sockmsg);
1349 }
1350
metadata_open(void)1351 void metadata_open(void) {
1352 if (config.metadata_enabled == 0)
1353 return;
1354
1355 size_t pl = strlen(config.metadata_pipename) + 1;
1356
1357 char *path = malloc(pl + 1);
1358 snprintf(path, pl + 1, "%s", config.metadata_pipename);
1359
1360 fd = try_to_open_pipe_for_writing(path);
1361 free(path);
1362 }
1363
metadata_close(void)1364 static void metadata_close(void) {
1365 if (fd < 0)
1366 return;
1367 close(fd);
1368 fd = -1;
1369 }
1370
metadata_multicast_process(uint32_t type,uint32_t code,char * data,uint32_t length)1371 void metadata_multicast_process(uint32_t type, uint32_t code, char *data, uint32_t length) {
1372 // debug(1, "Process multicast metadata with type %x, code %x and length %u.", type, code,
1373 // length);
1374 if (metadata_sock >= 0 && length < config.metadata_sockmsglength - 8) {
1375 char *ptr = metadata_sockmsg;
1376 uint32_t v;
1377 v = htonl(type);
1378 memcpy(ptr, &v, 4);
1379 ptr += 4;
1380 v = htonl(code);
1381 memcpy(ptr, &v, 4);
1382 ptr += 4;
1383 memcpy(ptr, data, length);
1384 sendto(metadata_sock, metadata_sockmsg, length + 8, 0, (struct sockaddr *)&metadata_sockaddr,
1385 sizeof(metadata_sockaddr));
1386 } else if (metadata_sock >= 0) {
1387 // send metadata in numbered chunks using the protocol:
1388 // ("ssnc", "chnk", packet_ix, packet_counts, packet_tag, packet_type, chunked_data)
1389
1390 uint32_t chunk_ix = 0;
1391 uint32_t chunk_total = length / (config.metadata_sockmsglength - 24);
1392 if (chunk_total * (config.metadata_sockmsglength - 24) < length) {
1393 chunk_total++;
1394 }
1395 uint32_t remaining = length;
1396 uint32_t v;
1397 char *data_crsr = data;
1398 do {
1399 char *ptr = metadata_sockmsg;
1400 memcpy(ptr, "ssncchnk", 8);
1401 ptr += 8;
1402 v = htonl(chunk_ix);
1403 memcpy(ptr, &v, 4);
1404 ptr += 4;
1405 v = htonl(chunk_total);
1406 memcpy(ptr, &v, 4);
1407 ptr += 4;
1408 v = htonl(type);
1409 memcpy(ptr, &v, 4);
1410 ptr += 4;
1411 v = htonl(code);
1412 memcpy(ptr, &v, 4);
1413 ptr += 4;
1414 size_t datalen = remaining;
1415 if (datalen > config.metadata_sockmsglength - 24) {
1416 datalen = config.metadata_sockmsglength - 24;
1417 }
1418 memcpy(ptr, data_crsr, datalen);
1419 data_crsr += datalen;
1420 sendto(metadata_sock, metadata_sockmsg, datalen + 24, 0,
1421 (struct sockaddr *)&metadata_sockaddr, sizeof(metadata_sockaddr));
1422 chunk_ix++;
1423 remaining -= datalen;
1424 if (remaining == 0)
1425 break;
1426 } while (1);
1427 }
1428 }
1429
metadata_process(uint32_t type,uint32_t code,char * data,uint32_t length)1430 void metadata_process(uint32_t type, uint32_t code, char *data, uint32_t length) {
1431 // debug(1, "Process metadata with type %x, code %x and length %u.", type, code, length);
1432 int ret = 0;
1433 // readers may go away and come back
1434
1435 if (fd < 0)
1436 metadata_open();
1437 if (fd < 0)
1438 return;
1439 char thestring[1024];
1440 snprintf(thestring, 1024, "<item><type>%x</type><code>%x</code><length>%u</length>", type, code,
1441 length);
1442 // ret = non_blocking_write(fd, thestring, strlen(thestring));
1443 ret = write(fd, thestring, strlen(thestring));
1444 if (ret < 0) {
1445 // debug(1,"metadata_process error %d exit 1",ret);
1446 return;
1447 }
1448 if ((data != NULL) && (length > 0)) {
1449 snprintf(thestring, 1024, "\n<data encoding=\"base64\">\n");
1450 // ret = non_blocking_write(fd, thestring, strlen(thestring));
1451 ret = write(fd, thestring, strlen(thestring));
1452 if (ret < 0) {
1453 // debug(1,"metadata_process error %d exit 2",ret);
1454 return;
1455 }
1456 // here, we write the data in base64 form using our nice base64 encoder
1457 // but, we break it into lines of 76 output characters, except for the last
1458 // one.
1459 // thus, we send groups of (76/4)*3 = 57 bytes to the encoder at a time
1460 size_t remaining_count = length;
1461 char *remaining_data = data;
1462 // size_t towrite_count;
1463 char outbuf[76];
1464 while ((remaining_count) && (ret >= 0)) {
1465 size_t towrite_count = remaining_count;
1466 if (towrite_count > 57)
1467 towrite_count = 57;
1468 size_t outbuf_size = 76; // size of output buffer on entry, length of result on exit
1469 if (base64_encode_so((unsigned char *)remaining_data, towrite_count, outbuf, &outbuf_size) ==
1470 NULL)
1471 debug(1, "Error encoding base64 data.");
1472 // debug(1,"Remaining count: %d ret: %d, outbuf_size:
1473 // %d.",remaining_count,ret,outbuf_size);
1474 // ret = non_blocking_write(fd, outbuf, outbuf_size);
1475 ret = write(fd, outbuf, outbuf_size);
1476 if (ret < 0) {
1477 // debug(1,"metadata_process error %d exit 3",ret);
1478 return;
1479 }
1480 remaining_data += towrite_count;
1481 remaining_count -= towrite_count;
1482 }
1483 snprintf(thestring, 1024, "</data>");
1484 // ret = non_blocking_write(fd, thestring, strlen(thestring));
1485 ret = write(fd, thestring, strlen(thestring));
1486 if (ret < 0) {
1487 // debug(1,"metadata_process error %d exit 4",ret);
1488 return;
1489 }
1490 }
1491 snprintf(thestring, 1024, "</item>\n");
1492 // ret = non_blocking_write(fd, thestring, strlen(thestring));
1493 ret = write(fd, thestring, strlen(thestring));
1494 if (ret < 0) {
1495 // debug(1,"metadata_process error %d exit 5",ret);
1496 return;
1497 }
1498 }
1499
metadata_pack_cleanup_function(void * arg)1500 void metadata_pack_cleanup_function(void *arg) {
1501 // debug(1, "metadata_pack_cleanup_function called");
1502 metadata_package *pack = (metadata_package *)arg;
1503 if (pack->carrier)
1504 msg_free(&pack->carrier); // release the message
1505 else if (pack->data)
1506 free(pack->data);
1507 // debug(1, "metadata_pack_cleanup_function exit");
1508 }
1509
metadata_thread_cleanup_function(void * arg)1510 void metadata_thread_cleanup_function(__attribute__((unused)) void *arg) {
1511 // debug(2, "metadata_thread_cleanup_function called");
1512 metadata_close();
1513 pc_queue_delete(&metadata_queue);
1514 }
1515
metadata_thread_function(void * ignore)1516 void *metadata_thread_function(__attribute__((unused)) void *ignore) {
1517 // create a pc_queue for passing information to a threaded metadata handler
1518 pc_queue_init(&metadata_queue, (char *)&metadata_queue_items, sizeof(metadata_package),
1519 metadata_queue_size, "pipe");
1520 metadata_create_multicast_socket();
1521 metadata_package pack;
1522 pthread_cleanup_push(metadata_thread_cleanup_function, NULL);
1523 while (1) {
1524 pc_queue_get_item(&metadata_queue, &pack);
1525 pthread_cleanup_push(metadata_pack_cleanup_function, (void *)&pack);
1526 if (config.metadata_enabled) {
1527 if (pack.carrier) {
1528 debug(3, " pipe: type %x, code %x, length %u, message %d.", pack.type, pack.code,
1529 pack.length, pack.carrier->index_number);
1530 } else {
1531 debug(3, " pipe: type %x, code %x, length %u.", pack.type, pack.code, pack.length);
1532 }
1533 metadata_process(pack.type, pack.code, pack.data, pack.length);
1534 debug(3, " pipe: done.");
1535 }
1536 pthread_cleanup_pop(1);
1537 }
1538 pthread_cleanup_pop(1); // will never happen
1539 pthread_exit(NULL);
1540 }
1541
metadata_multicast_thread_cleanup_function(void * arg)1542 void metadata_multicast_thread_cleanup_function(__attribute__((unused)) void *arg) {
1543 // debug(2, "metadata_multicast_thread_cleanup_function called");
1544 metadata_delete_multicast_socket();
1545 pc_queue_delete(&metadata_multicast_queue);
1546 }
1547
metadata_multicast_thread_function(void * ignore)1548 void *metadata_multicast_thread_function(__attribute__((unused)) void *ignore) {
1549 // create a pc_queue for passing information to a threaded metadata handler
1550 pc_queue_init(&metadata_multicast_queue, (char *)&metadata_multicast_queue_items,
1551 sizeof(metadata_package), metadata_multicast_queue_size, "multicast");
1552 metadata_create_multicast_socket();
1553 metadata_package pack;
1554 pthread_cleanup_push(metadata_multicast_thread_cleanup_function, NULL);
1555 while (1) {
1556 pc_queue_get_item(&metadata_multicast_queue, &pack);
1557 pthread_cleanup_push(metadata_pack_cleanup_function, (void *)&pack);
1558 if (config.metadata_enabled) {
1559 if (pack.carrier) {
1560 debug(3,
1561 " multicast: type "
1562 "%x, code %x, length %u, message %d.",
1563 pack.type, pack.code, pack.length, pack.carrier->index_number);
1564 } else {
1565 debug(3,
1566 " multicast: type "
1567 "%x, code %x, length %u.",
1568 pack.type, pack.code, pack.length);
1569 }
1570 metadata_multicast_process(pack.type, pack.code, pack.data, pack.length);
1571 debug(3,
1572 " multicast: done.");
1573 }
1574 pthread_cleanup_pop(1);
1575 }
1576 pthread_cleanup_pop(1); // will never happen
1577 pthread_exit(NULL);
1578 }
1579
1580 #ifdef CONFIG_METADATA_HUB
metadata_hub_close(void)1581 void metadata_hub_close(void) {}
1582
metadata_hub_thread_cleanup_function(void * arg)1583 void metadata_hub_thread_cleanup_function(__attribute__((unused)) void *arg) {
1584 // debug(2, "metadata_hub_thread_cleanup_function called");
1585 metadata_hub_close();
1586 pc_queue_delete(&metadata_hub_queue);
1587 }
1588
metadata_hub_thread_function(void * ignore)1589 void *metadata_hub_thread_function(__attribute__((unused)) void *ignore) {
1590 // create a pc_queue for passing information to a threaded metadata handler
1591 pc_queue_init(&metadata_hub_queue, (char *)&metadata_hub_queue_items, sizeof(metadata_package),
1592 metadata_hub_queue_size, "hub");
1593 metadata_package pack;
1594 pthread_cleanup_push(metadata_hub_thread_cleanup_function, NULL);
1595 while (1) {
1596 pc_queue_get_item(&metadata_hub_queue, &pack);
1597 pthread_cleanup_push(metadata_pack_cleanup_function, (void *)&pack);
1598 if (pack.carrier) {
1599 debug(3, " hub: type %x, code %x, length %u, message %d.", pack.type,
1600 pack.code, pack.length, pack.carrier->index_number);
1601 } else {
1602 debug(3, " hub: type %x, code %x, length %u.", pack.type, pack.code,
1603 pack.length);
1604 }
1605 metadata_hub_process_metadata(pack.type, pack.code, pack.data, pack.length);
1606 debug(3, " hub: done.");
1607 pthread_cleanup_pop(1);
1608 }
1609 pthread_cleanup_pop(1); // will never happen
1610 pthread_exit(NULL);
1611 }
1612 #endif
1613
1614 #ifdef CONFIG_MQTT
metadata_mqtt_close(void)1615 void metadata_mqtt_close(void) {}
1616
metadata_mqtt_thread_cleanup_function(void * arg)1617 void metadata_mqtt_thread_cleanup_function(__attribute__((unused)) void *arg) {
1618 // debug(2, "metadata_mqtt_thread_cleanup_function called");
1619 metadata_mqtt_close();
1620 pc_queue_delete(&metadata_mqtt_queue);
1621 // debug(2, "metadata_mqtt_thread_cleanup_function done");
1622 }
1623
metadata_mqtt_thread_function(void * ignore)1624 void *metadata_mqtt_thread_function(__attribute__((unused)) void *ignore) {
1625 // create a pc_queue for passing information to a threaded metadata handler
1626 pc_queue_init(&metadata_mqtt_queue, (char *)&metadata_mqtt_queue_items, sizeof(metadata_package),
1627 metadata_mqtt_queue_size, "mqtt");
1628 metadata_package pack;
1629 pthread_cleanup_push(metadata_mqtt_thread_cleanup_function, NULL);
1630 while (1) {
1631 pc_queue_get_item(&metadata_mqtt_queue, &pack);
1632 pthread_cleanup_push(metadata_pack_cleanup_function, (void *)&pack);
1633 if (config.mqtt_enabled) {
1634 if (pack.carrier) {
1635 debug(3,
1636 " mqtt: type %x, code %x, length %u, message "
1637 "%d.",
1638 pack.type, pack.code, pack.length, pack.carrier->index_number);
1639 } else {
1640 debug(3, " mqtt: type %x, code %x, length %u.",
1641 pack.type, pack.code, pack.length);
1642 }
1643 mqtt_process_metadata(pack.type, pack.code, pack.data, pack.length);
1644 debug(3, " mqtt: done.");
1645 }
1646
1647 pthread_cleanup_pop(1);
1648 }
1649 pthread_cleanup_pop(1); // will never happen
1650 pthread_exit(NULL);
1651 }
1652 #endif
1653
metadata_init(void)1654 void metadata_init(void) {
1655 int ret;
1656 if (config.metadata_enabled) {
1657 // create the metadata pipe, if necessary
1658 size_t pl = strlen(config.metadata_pipename) + 1;
1659 char *path = malloc(pl + 1);
1660 snprintf(path, pl + 1, "%s", config.metadata_pipename);
1661 mode_t oldumask = umask(000);
1662 if (mkfifo(path, 0666) && errno != EEXIST)
1663 die("Could not create metadata pipe \"%s\".", path);
1664 umask(oldumask);
1665 debug(1, "metadata pipe name is \"%s\".", path);
1666
1667 // try to open it
1668 fd = try_to_open_pipe_for_writing(path);
1669 // we check that it's not a "real" error. From the "man 2 open" page:
1670 // "ENXIO O_NONBLOCK | O_WRONLY is set, the named file is a FIFO, and no process has the FIFO
1671 // open for reading." Which is okay.
1672 if ((fd == -1) && (errno != ENXIO)) {
1673 char errorstring[1024];
1674 strerror_r(errno, (char *)errorstring, sizeof(errorstring));
1675 debug(1, "metadata_hub_thread_function -- error %d (\"%s\") opening pipe: \"%s\".", errno,
1676 (char *)errorstring, path);
1677 warn("can not open metadata pipe -- error %d (\"%s\") opening pipe: \"%s\".", errno,
1678 (char *)errorstring, path);
1679 }
1680 free(path);
1681 int ret;
1682 ret = pthread_create(&metadata_thread, NULL, metadata_thread_function, NULL);
1683 if (ret)
1684 debug(1, "Failed to create metadata thread!");
1685
1686 ret =
1687 pthread_create(&metadata_multicast_thread, NULL, metadata_multicast_thread_function, NULL);
1688 if (ret)
1689 debug(1, "Failed to create metadata multicast thread!");
1690 }
1691 #ifdef CONFIG_METADATA_HUB
1692 ret = pthread_create(&metadata_hub_thread, NULL, metadata_hub_thread_function, NULL);
1693 if (ret)
1694 debug(1, "Failed to create metadata hub thread!");
1695 #endif
1696 #ifdef CONFIG_MQTT
1697 ret = pthread_create(&metadata_mqtt_thread, NULL, metadata_mqtt_thread_function, NULL);
1698 if (ret)
1699 debug(1, "Failed to create metadata mqtt thread!");
1700 #endif
1701 metadata_running = 1;
1702 }
1703
metadata_stop(void)1704 void metadata_stop(void) {
1705 if (metadata_running) {
1706 debug(2, "metadata_stop called.");
1707 #ifdef CONFIG_MQTT
1708 // debug(2, "metadata stop mqtt thread.");
1709 pthread_cancel(metadata_mqtt_thread);
1710 pthread_join(metadata_mqtt_thread, NULL);
1711 // debug(2, "metadata stop mqtt done.");
1712 #endif
1713 #ifdef CONFIG_METADATA_HUB
1714 // debug(2, "metadata stop hub thread.");
1715 pthread_cancel(metadata_hub_thread);
1716 pthread_join(metadata_hub_thread, NULL);
1717 // debug(2, "metadata stop hub done.");
1718 #endif
1719 if (config.metadata_enabled) {
1720 // debug(2, "metadata stop multicast thread.");
1721 if (metadata_multicast_thread) {
1722 pthread_cancel(metadata_multicast_thread);
1723 pthread_join(metadata_multicast_thread, NULL);
1724 // debug(2, "metadata stop multicast done.");
1725 }
1726 if (metadata_thread) {
1727 // debug(2, "metadata stop metadata_thread thread.");
1728 pthread_cancel(metadata_thread);
1729 pthread_join(metadata_thread, NULL);
1730 // debug(2, "metadata_stop finished successfully.");
1731 }
1732 }
1733 }
1734 }
1735
send_metadata_to_queue(pc_queue * queue,uint32_t type,uint32_t code,char * data,uint32_t length,rtsp_message * carrier,int block)1736 int send_metadata_to_queue(pc_queue *queue, uint32_t type, uint32_t code, char *data,
1737 uint32_t length, rtsp_message *carrier, int block) {
1738
1739 // parameters: type, code, pointer to data or NULL, length of data or NULL,
1740 // the rtsp_message or
1741 // NULL
1742 // the rtsp_message is sent for 'core' messages, because it contains the data
1743 // and must not be
1744 // freed until the data has been read. So, it is passed to send_metadata to be
1745 // retained,
1746 // sent to the thread where metadata is processed and released (and probably
1747 // freed).
1748
1749 // The rtsp_message is also sent for certain non-'core' messages.
1750
1751 // The reading of the parameters is a bit complex
1752 // If the rtsp_message field is non-null, then it represents an rtsp_message
1753 // and the data pointer is assumed to point to something within it.
1754 // The reference counter of the rtsp_message is incremented here and
1755 // should be decremented by the metadata handler when finished.
1756 // If the reference count reduces to zero, the message will be freed.
1757
1758 // If the rtsp_message is NULL, then if the pointer is non-null then the data it
1759 // points to, of the length specified, is memcpy'd and passed to the metadata
1760 // handler. The handler should free it when done.
1761 // If the rtsp_message is NULL and the pointer is also NULL, nothing further
1762 // is done.
1763
1764 metadata_package pack;
1765 pack.type = type;
1766 pack.code = code;
1767 pack.length = length;
1768 pack.carrier = carrier;
1769 pack.data = data;
1770 if (pack.carrier) {
1771 msg_retain(pack.carrier);
1772 } else {
1773 if (data)
1774 pack.data = memdup(data, length); // only if it's not a null
1775 }
1776 int rc = pc_queue_add_item(queue, &pack, block);
1777 if (rc != 0) {
1778 if (pack.carrier) {
1779 if (rc == EWOULDBLOCK)
1780 debug(2,
1781 "metadata queue \"%s\" full, dropping message item: type %x, code %x, data %x, "
1782 "length %u, message %d.",
1783 queue->name, pack.type, pack.code, pack.data, pack.length,
1784 pack.carrier->index_number);
1785 msg_free(&pack.carrier);
1786 } else {
1787 if (rc == EWOULDBLOCK)
1788 debug(
1789 2,
1790 "metadata queue \"%s\" full, dropping data item: type %x, code %x, data %x, length %u.",
1791 queue->name, pack.type, pack.code, pack.data, pack.length);
1792 if (pack.data)
1793 free(pack.data);
1794 }
1795 }
1796 return rc;
1797 }
1798
send_metadata(uint32_t type,uint32_t code,char * data,uint32_t length,rtsp_message * carrier,int block)1799 int send_metadata(uint32_t type, uint32_t code, char *data, uint32_t length, rtsp_message *carrier,
1800 int block) {
1801 int rc;
1802 if (config.metadata_enabled) {
1803 rc = send_metadata_to_queue(&metadata_queue, type, code, data, length, carrier, block);
1804 rc =
1805 send_metadata_to_queue(&metadata_multicast_queue, type, code, data, length, carrier, block);
1806 }
1807
1808 #ifdef CONFIG_METADATA_HUB
1809 rc = send_metadata_to_queue(&metadata_hub_queue, type, code, data, length, carrier, block);
1810 #endif
1811
1812 #ifdef CONFIG_MQTT
1813 rc = send_metadata_to_queue(&metadata_mqtt_queue, type, code, data, length, carrier, block);
1814 #endif
1815
1816 return rc;
1817 }
1818
handle_set_parameter_metadata(rtsp_conn_info * conn,rtsp_message * req,rtsp_message * resp)1819 static void handle_set_parameter_metadata(__attribute__((unused)) rtsp_conn_info *conn,
1820 rtsp_message *req,
1821 __attribute__((unused)) rtsp_message *resp) {
1822 char *cp = req->content;
1823 unsigned int cl = req->contentlength;
1824
1825 unsigned int off = 8;
1826
1827 uint32_t itag, vl;
1828 while (off < cl) {
1829 // pick up the metadata tag as an unsigned longint
1830 memcpy(&itag, (uint32_t *)(cp + off), sizeof(uint32_t)); /* can be misaligned, thus memcpy */
1831 itag = ntohl(itag);
1832 off += sizeof(uint32_t);
1833
1834 // pick up the length of the data
1835 memcpy(&vl, (uint32_t *)(cp + off), sizeof(uint32_t)); /* can be misaligned, thus memcpy */
1836 vl = ntohl(vl);
1837 off += sizeof(uint32_t);
1838
1839 // pass the data over
1840 if (vl == 0)
1841 send_metadata('core', itag, NULL, 0, NULL, 1);
1842 else
1843 send_metadata('core', itag, (char *)(cp + off), vl, req, 1);
1844
1845 // move on to the next item
1846 off += vl;
1847 }
1848 }
1849
1850 #endif
1851
handle_get_parameter(rtsp_conn_info * conn,rtsp_message * req,rtsp_message * resp)1852 static void handle_get_parameter(__attribute__((unused)) rtsp_conn_info *conn, rtsp_message *req,
1853 rtsp_message *resp) {
1854 // debug(1, "Connection %d: GET_PARAMETER", conn->connection_number);
1855 // debug_print_msg_headers(1,req);
1856 // debug_print_msg_content(1,req);
1857
1858 if ((req->content) && (req->contentlength == strlen("volume\r\n")) &&
1859 strstr(req->content, "volume") == req->content) {
1860 // debug(1,"Current volume sought");
1861 char *p = malloc(128); // will be automatically deallocated with the response is deleted
1862 if (p) {
1863 resp->content = p;
1864 resp->contentlength = snprintf(p, 128, "\r\nvolume: %.6f\r\n", config.airplay_volume);
1865 } else {
1866 debug(1, "Couldn't allocate space for a response.");
1867 }
1868 }
1869 resp->respcode = 200;
1870 }
1871
handle_set_parameter(rtsp_conn_info * conn,rtsp_message * req,rtsp_message * resp)1872 static void handle_set_parameter(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
1873 debug(3, "Connection %d: SET_PARAMETER", conn->connection_number);
1874 // if (!req->contentlength)
1875 // debug(1, "received empty SET_PARAMETER request.");
1876
1877 // debug_print_msg_headers(1,req);
1878
1879 char *ct = msg_get_header(req, "Content-Type");
1880
1881 if (ct) {
1882 // debug(2, "SET_PARAMETER Content-Type:\"%s\".", ct);
1883
1884 #ifdef CONFIG_METADATA
1885 // It seems that the rtptime of the message is used as a kind of an ID that
1886 // can be used
1887 // to link items of metadata, including pictures, that refer to the same
1888 // entity.
1889 // If they refer to the same item, they have the same rtptime.
1890 // So we send the rtptime before and after both the metadata items and the
1891 // picture item
1892 // get the rtptime
1893 char *p = NULL;
1894 char *hdr = msg_get_header(req, "RTP-Info");
1895
1896 if (hdr) {
1897 p = strstr(hdr, "rtptime=");
1898 if (p) {
1899 p = strchr(p, '=');
1900 }
1901 }
1902
1903 // not all items have RTP-time stuff in them, which is okay
1904
1905 if (!strncmp(ct, "application/x-dmap-tagged", 25)) {
1906 debug(3, "received metadata tags in SET_PARAMETER request.");
1907 if (p == NULL)
1908 debug(1, "Missing RTP-Time info for metadata");
1909 if (p)
1910 send_metadata('ssnc', 'mdst', p + 1, strlen(p + 1), req, 1); // metadata starting
1911 else
1912 send_metadata('ssnc', 'mdst', NULL, 0, NULL,
1913 0); // metadata starting, if rtptime is not available
1914
1915 handle_set_parameter_metadata(conn, req, resp);
1916
1917 if (p)
1918 send_metadata('ssnc', 'mden', p + 1, strlen(p + 1), req, 1); // metadata ending
1919 else
1920 send_metadata('ssnc', 'mden', NULL, 0, NULL,
1921 0); // metadata starting, if rtptime is not available
1922
1923 } else if (!strncmp(ct, "image", 5)) {
1924 // Some server simply ignore the md field from the TXT record. If The
1925 // config says 'please, do not include any cover art', we are polite and
1926 // do not write them to the pipe.
1927 if (config.get_coverart) {
1928 // debug(1, "received image in SET_PARAMETER request.");
1929 // note: the image/type tag isn't reliable, so it's not being sent
1930 // -- best look at the first few bytes of the image
1931 if (p == NULL)
1932 debug(1, "Missing RTP-Time info for picture item");
1933 if (p)
1934 send_metadata('ssnc', 'pcst', p + 1, strlen(p + 1), req, 1); // picture starting
1935 else
1936 send_metadata('ssnc', 'pcst', NULL, 0, NULL,
1937 0); // picture starting, if rtptime is not available
1938
1939 send_metadata('ssnc', 'PICT', req->content, req->contentlength, req, 1);
1940
1941 if (p)
1942 send_metadata('ssnc', 'pcen', p + 1, strlen(p + 1), req, 1); // picture ending
1943 else
1944 send_metadata('ssnc', 'pcen', NULL, 0, NULL,
1945 0); // picture ending, if rtptime is not available
1946 } else {
1947 debug(1, "Ignore received picture item (include_cover_art = no).");
1948 }
1949 } else
1950 #endif
1951 if (!strncmp(ct, "text/parameters", 15)) {
1952 // debug(2, "received parameters in SET_PARAMETER request.");
1953 handle_set_parameter_parameter(conn, req, resp); // this could be volume or progress
1954 } else {
1955 debug(1, "received unknown Content-Type \"%s\" in SET_PARAMETER request.", ct);
1956 }
1957 } else {
1958 debug(1, "missing Content-Type header in SET_PARAMETER request.");
1959 }
1960 resp->respcode = 200;
1961 }
1962
handle_announce(rtsp_conn_info * conn,rtsp_message * req,rtsp_message * resp)1963 static void handle_announce(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
1964 debug(3, "Connection %d: ANNOUNCE", conn->connection_number);
1965
1966 int have_the_player = 0;
1967 int should_wait = 0; // this will be true if you're trying to break in to the current session
1968 int interrupting_current_session = 0;
1969
1970 // try to become the current playing_conn
1971
1972 debug_mutex_lock(&playing_conn_lock, 1000000, 3); // get it
1973
1974 if (playing_conn == NULL) {
1975 playing_conn = conn;
1976 have_the_player = 1;
1977 } else if (playing_conn == conn) {
1978 have_the_player = 1;
1979 warn("Duplicate ANNOUNCE, by the look of it!");
1980 } else if (playing_conn->stop) {
1981 debug(1, "Connection %d ANNOUNCE is waiting for connection %d to shut down.",
1982 conn->connection_number, playing_conn->connection_number);
1983 should_wait = 1;
1984 } else if (config.allow_session_interruption == 1) {
1985 debug(2, "Connection %d: ANNOUNCE: asking playing connection %d to shut down.",
1986 conn->connection_number, playing_conn->connection_number);
1987 playing_conn->stop = 1;
1988 interrupting_current_session = 1;
1989 should_wait = 1;
1990 pthread_cancel(playing_conn->thread); // asking the RTSP thread to exit
1991 }
1992 debug_mutex_unlock(&playing_conn_lock, 3);
1993
1994 if (should_wait) {
1995 int time_remaining = 3000000; // must be signed, as it could go negative...
1996
1997 while ((time_remaining > 0) && (have_the_player == 0)) {
1998 debug_mutex_lock(&playing_conn_lock, 1000000, 3); // get it
1999 if (playing_conn == NULL) {
2000 playing_conn = conn;
2001 have_the_player = 1;
2002 }
2003 debug_mutex_unlock(&playing_conn_lock, 3);
2004
2005 if (have_the_player == 0) {
2006 usleep(100000);
2007 time_remaining -= 100000;
2008 }
2009 }
2010
2011 if ((have_the_player == 1) && (interrupting_current_session == 1)) {
2012 debug(2, "Connection %d: ANNOUNCE got the player", conn->connection_number);
2013 } else {
2014 debug(2, "Connection %d: ANNOUNCE failed to get the player", conn->connection_number);
2015 }
2016 }
2017
2018 if (have_the_player) {
2019 debug(3, "Connection %d: ANNOUNCE has acquired play lock.", conn->connection_number);
2020
2021 // now, if this new session did not break in, then it's okay to reset the next UDP ports
2022 // to the start of the range
2023
2024 if (interrupting_current_session == 0) { // will be zero if it wasn't waiting to break in
2025 resetFreeUDPPort();
2026 }
2027
2028 /*
2029 {
2030 char *cp = req->content;
2031 int cp_left = req->contentlength;
2032 while (cp_left > 1) {
2033 if (strlen(cp) != 0)
2034 debug(1,">>>>>> %s", cp);
2035 cp += strlen(cp) + 1;
2036 cp_left -= strlen(cp) + 1;
2037 }
2038 }
2039 */
2040
2041 conn->stream.type = ast_unknown;
2042 resp->respcode = 456; // 456 - Header Field Not Valid for Resource
2043 char *pssid = NULL;
2044 char *paesiv = NULL;
2045 char *prsaaeskey = NULL;
2046 char *pfmtp = NULL;
2047 char *pminlatency = NULL;
2048 char *pmaxlatency = NULL;
2049 // char *pAudioMediaInfo = NULL;
2050 char *pUncompressedCDAudio = NULL;
2051 char *cp = req->content;
2052 int cp_left = req->contentlength;
2053 char *next;
2054 while (cp_left && cp) {
2055 next = nextline(cp, cp_left);
2056 cp_left -= next - cp;
2057
2058 if (!strncmp(cp, "a=rtpmap:96 L16/44100/2", strlen("a=rtpmap:96 L16/44100/2")))
2059 pUncompressedCDAudio = cp + strlen("a=rtpmap:96 L16/44100/2");
2060
2061 // if (!strncmp(cp, "m=audio", strlen("m=audio")))
2062 // pAudioMediaInfo = cp + strlen("m=audio");
2063
2064 if (!strncmp(cp, "o=iTunes", strlen("o=iTunes")))
2065 pssid = cp + strlen("o=iTunes");
2066
2067 if (!strncmp(cp, "a=fmtp:", strlen("a=fmtp:")))
2068 pfmtp = cp + strlen("a=fmtp:");
2069
2070 if (!strncmp(cp, "a=aesiv:", strlen("a=aesiv:")))
2071 paesiv = cp + strlen("a=aesiv:");
2072
2073 if (!strncmp(cp, "a=rsaaeskey:", strlen("a=rsaaeskey:")))
2074 prsaaeskey = cp + strlen("a=rsaaeskey:");
2075
2076 if (!strncmp(cp, "a=min-latency:", strlen("a=min-latency:")))
2077 pminlatency = cp + strlen("a=min-latency:");
2078
2079 if (!strncmp(cp, "a=max-latency:", strlen("a=max-latency:")))
2080 pmaxlatency = cp + strlen("a=max-latency:");
2081
2082 cp = next;
2083 }
2084
2085 if (pUncompressedCDAudio) {
2086 debug(2, "An uncompressed PCM stream has been detected.");
2087 conn->stream.type = ast_uncompressed;
2088 conn->max_frames_per_packet = 352; // number of audio frames per packet.
2089 conn->input_rate = 44100;
2090 conn->input_num_channels = 2;
2091 conn->input_bit_depth = 16;
2092 conn->input_bytes_per_frame = conn->input_num_channels * ((conn->input_bit_depth + 7) / 8);
2093
2094 /*
2095 int y = strlen(pAudioMediaInfo);
2096 if (y > 0) {
2097 char obf[4096];
2098 if (y > 4096)
2099 y = 4096;
2100 char *p = pAudioMediaInfo;
2101 char *obfp = obf;
2102 int obfc;
2103 for (obfc = 0; obfc < y; obfc++) {
2104 snprintf(obfp, 3, "%02X", (unsigned int)*p);
2105 p++;
2106 obfp += 2;
2107 };
2108 *obfp = 0;
2109 debug(1, "AudioMediaInfo: \"%s\".", obf);
2110 }
2111 */
2112 }
2113
2114 if (pssid) {
2115 uint32_t ssid = uatoi(pssid);
2116 debug(3, "Synchronisation Source Identifier: %08X,%u", ssid, ssid);
2117 }
2118
2119 if (pminlatency) {
2120 conn->minimum_latency = atoi(pminlatency);
2121 debug(3, "Minimum latency %d specified", conn->minimum_latency);
2122 }
2123
2124 if (pmaxlatency) {
2125 conn->maximum_latency = atoi(pmaxlatency);
2126 debug(3, "Maximum latency %d specified", conn->maximum_latency);
2127 }
2128
2129 if ((paesiv == NULL) && (prsaaeskey == NULL)) {
2130 // debug(1,"Unencrypted session requested?");
2131 conn->stream.encrypted = 0;
2132 } else {
2133 conn->stream.encrypted = 1;
2134 // debug(1,"Encrypted session requested");
2135 }
2136
2137 if (conn->stream.encrypted) {
2138 int len, keylen;
2139 uint8_t *aesiv = base64_dec(paesiv, &len);
2140 if (len != 16) {
2141 warn("client announced aeskey of %d bytes, wanted 16", len);
2142 free(aesiv);
2143 goto out;
2144 }
2145 memcpy(conn->stream.aesiv, aesiv, 16);
2146 free(aesiv);
2147
2148 uint8_t *rsaaeskey = base64_dec(prsaaeskey, &len);
2149 uint8_t *aeskey = rsa_apply(rsaaeskey, len, &keylen, RSA_MODE_KEY);
2150 free(rsaaeskey);
2151 if (keylen != 16) {
2152 warn("client announced rsaaeskey of %d bytes, wanted 16", keylen);
2153 free(aeskey);
2154 goto out;
2155 }
2156 memcpy(conn->stream.aeskey, aeskey, 16);
2157 free(aeskey);
2158 }
2159
2160 if (pfmtp) {
2161 conn->stream.type = ast_apple_lossless;
2162 debug(3, "An ALAC stream has been detected.");
2163
2164 // Set reasonable connection defaults
2165 conn->stream.fmtp[0] = 96;
2166 conn->stream.fmtp[1] = 352;
2167 conn->stream.fmtp[2] = 0;
2168 conn->stream.fmtp[3] = 16;
2169 conn->stream.fmtp[4] = 40;
2170 conn->stream.fmtp[5] = 10;
2171 conn->stream.fmtp[6] = 14;
2172 conn->stream.fmtp[7] = 2;
2173 conn->stream.fmtp[8] = 255;
2174 conn->stream.fmtp[9] = 0;
2175 conn->stream.fmtp[10] = 0;
2176 conn->stream.fmtp[11] = 44100;
2177
2178 unsigned int i = 0;
2179 unsigned int max_param = sizeof(conn->stream.fmtp) / sizeof(conn->stream.fmtp[0]);
2180 char *found;
2181 while ((found = strsep(&pfmtp, " \t")) != NULL && i < max_param) {
2182 conn->stream.fmtp[i++] = atoi(found);
2183 }
2184 // here we should check the sanity of the fmtp values
2185 // for (i = 0; i < sizeof(conn->stream.fmtp) / sizeof(conn->stream.fmtp[0]); i++)
2186 // debug(1," fmtp[%2d] is: %10d",i,conn->stream.fmtp[i]);
2187
2188 // set the parameters of the player (as distinct from the parameters of the decoder -- that's
2189 // done later).
2190 conn->max_frames_per_packet = conn->stream.fmtp[1]; // number of audio frames per packet.
2191 conn->input_rate = conn->stream.fmtp[11];
2192 conn->input_num_channels = conn->stream.fmtp[7];
2193 conn->input_bit_depth = conn->stream.fmtp[3];
2194 conn->input_bytes_per_frame = conn->input_num_channels * ((conn->input_bit_depth + 7) / 8);
2195 }
2196
2197 if (conn->stream.type == ast_unknown) {
2198 warn("Can not process the following ANNOUNCE message:");
2199 // print each line of the request content
2200 // the problem is that nextline has replace all returns, newlines, etc. by
2201 // NULLs
2202 char *cp = req->content;
2203 int cp_left = req->contentlength;
2204 while (cp_left > 1) {
2205 if (strlen(cp) != 0)
2206 warn(" %s", cp);
2207 cp += strlen(cp) + 1;
2208 cp_left -= strlen(cp) + 1;
2209 }
2210 goto out;
2211 }
2212
2213 char *hdr = msg_get_header(req, "X-Apple-Client-Name");
2214 if (hdr) {
2215 debug(1, "Play connection from device named \"%s\" on RTSP conversation thread %d.", hdr,
2216 conn->connection_number);
2217 #ifdef CONFIG_METADATA
2218 send_metadata('ssnc', 'snam', hdr, strlen(hdr), req, 1);
2219 #endif
2220 }
2221 hdr = msg_get_header(req, "User-Agent");
2222 if (hdr) {
2223 conn->UserAgent = strdup(hdr);
2224 debug(2, "Play connection from user agent \"%s\" on RTSP conversation thread %d.", hdr,
2225 conn->connection_number);
2226 // if the user agent is AirPlay and has a version number of 353 or less (from iOS 11.1,2)
2227 // use the older way of calculating the latency
2228
2229 char *p = strstr(hdr, "AirPlay");
2230 if (p) {
2231 p = strchr(p, '/');
2232 if (p) {
2233 conn->AirPlayVersion = atoi(p + 1);
2234 debug(2, "AirPlay version %d detected.", conn->AirPlayVersion);
2235 }
2236 }
2237
2238 #ifdef CONFIG_METADATA
2239 send_metadata('ssnc', 'snua', hdr, strlen(hdr), req, 1);
2240 #endif
2241 }
2242 resp->respcode = 200;
2243 } else {
2244 resp->respcode = 453;
2245 debug(1, "Connection %d: ANNOUNCE failed because another connection is already playing.",
2246 conn->connection_number);
2247 }
2248
2249 out:
2250 if (resp->respcode != 200 && resp->respcode != 453) {
2251 debug(1, "Connection %d: Error in handling ANNOUNCE. Unlocking the play lock.",
2252 conn->connection_number);
2253 debug_mutex_lock(&playing_conn_lock, 1000000, 3); // get it
2254 if (playing_conn == conn) // if we managed to acquire it
2255 playing_conn = NULL; // let it go
2256 debug_mutex_unlock(&playing_conn_lock, 3);
2257 }
2258 }
2259
2260 static struct method_handler {
2261 char *method;
2262 void (*handler)(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp);
2263 } method_handlers[] = {{"OPTIONS", handle_options},
2264 {"ANNOUNCE", handle_announce},
2265 {"FLUSH", handle_flush},
2266 {"TEARDOWN", handle_teardown},
2267 {"SETUP", handle_setup},
2268 {"GET_PARAMETER", handle_get_parameter},
2269 {"SET_PARAMETER", handle_set_parameter},
2270 {"RECORD", handle_record},
2271 {NULL, NULL}};
2272
apple_challenge(int fd,rtsp_message * req,rtsp_message * resp)2273 static void apple_challenge(int fd, rtsp_message *req, rtsp_message *resp) {
2274 char *hdr = msg_get_header(req, "Apple-Challenge");
2275 if (!hdr)
2276 return;
2277
2278 SOCKADDR fdsa;
2279 socklen_t sa_len = sizeof(fdsa);
2280 getsockname(fd, (struct sockaddr *)&fdsa, &sa_len);
2281
2282 int chall_len;
2283 uint8_t *chall = base64_dec(hdr, &chall_len);
2284 if (chall == NULL)
2285 die("null chall in apple_challenge");
2286 uint8_t buf[48], *bp = buf;
2287 int i;
2288 memset(buf, 0, sizeof(buf));
2289
2290 if (chall_len > 16) {
2291 warn("oversized Apple-Challenge!");
2292 free(chall);
2293 return;
2294 }
2295 memcpy(bp, chall, chall_len);
2296 free(chall);
2297 bp += chall_len;
2298
2299 #ifdef AF_INET6
2300 if (fdsa.SAFAMILY == AF_INET6) {
2301 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)(&fdsa);
2302 memcpy(bp, sa6->sin6_addr.s6_addr, 16);
2303 bp += 16;
2304 } else
2305 #endif
2306 {
2307 struct sockaddr_in *sa = (struct sockaddr_in *)(&fdsa);
2308 memcpy(bp, &sa->sin_addr.s_addr, 4);
2309 bp += 4;
2310 }
2311
2312 for (i = 0; i < 6; i++)
2313 *bp++ = config.hw_addr[i];
2314
2315 int buflen, resplen;
2316 buflen = bp - buf;
2317 if (buflen < 0x20)
2318 buflen = 0x20;
2319
2320 uint8_t *challresp = rsa_apply(buf, buflen, &resplen, RSA_MODE_AUTH);
2321 char *encoded = base64_enc(challresp, resplen);
2322 if (encoded == NULL)
2323 die("could not allocate memory for \"encoded\"");
2324 // strip the padding.
2325 char *padding = strchr(encoded, '=');
2326 if (padding)
2327 *padding = 0;
2328
2329 msg_add_header(resp, "Apple-Response", encoded); // will be freed when the response is freed.
2330 free(challresp);
2331 free(encoded);
2332 }
2333
make_nonce(void)2334 static char *make_nonce(void) {
2335 uint8_t random[8];
2336 int fd = open("/dev/urandom", O_RDONLY);
2337 if (fd < 0)
2338 die("could not open /dev/urandom!");
2339 // int ignore =
2340 if (read(fd, random, sizeof(random)) != sizeof(random))
2341 debug(1, "Error reading /dev/urandom");
2342 close(fd);
2343 return base64_enc(random, 8); // returns a pointer to malloc'ed memory
2344 }
2345
rtsp_auth(char ** nonce,rtsp_message * req,rtsp_message * resp)2346 static int rtsp_auth(char **nonce, rtsp_message *req, rtsp_message *resp) {
2347
2348 if (!config.password)
2349 return 0;
2350 if (!*nonce) {
2351 *nonce = make_nonce();
2352 goto authenticate;
2353 }
2354
2355 char *hdr = msg_get_header(req, "Authorization");
2356 if (!hdr || strncmp(hdr, "Digest ", 7))
2357 goto authenticate;
2358
2359 char *realm = strstr(hdr, "realm=\"");
2360 char *username = strstr(hdr, "username=\"");
2361 char *response = strstr(hdr, "response=\"");
2362 char *uri = strstr(hdr, "uri=\"");
2363
2364 if (!realm || !username || !response || !uri)
2365 goto authenticate;
2366
2367 char *quote;
2368 realm = strchr(realm, '"') + 1;
2369 if (!(quote = strchr(realm, '"')))
2370 goto authenticate;
2371 *quote = 0;
2372 username = strchr(username, '"') + 1;
2373 if (!(quote = strchr(username, '"')))
2374 goto authenticate;
2375 *quote = 0;
2376 response = strchr(response, '"') + 1;
2377 if (!(quote = strchr(response, '"')))
2378 goto authenticate;
2379 *quote = 0;
2380 uri = strchr(uri, '"') + 1;
2381 if (!(quote = strchr(uri, '"')))
2382 goto authenticate;
2383 *quote = 0;
2384
2385 uint8_t digest_urp[16], digest_mu[16], digest_total[16];
2386
2387 #ifdef CONFIG_OPENSSL
2388 MD5_CTX ctx;
2389
2390 int oldState;
2391 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
2392 MD5_Init(&ctx);
2393 MD5_Update(&ctx, username, strlen(username));
2394 MD5_Update(&ctx, ":", 1);
2395 MD5_Update(&ctx, realm, strlen(realm));
2396 MD5_Update(&ctx, ":", 1);
2397 MD5_Update(&ctx, config.password, strlen(config.password));
2398 MD5_Final(digest_urp, &ctx);
2399 MD5_Init(&ctx);
2400 MD5_Update(&ctx, req->method, strlen(req->method));
2401 MD5_Update(&ctx, ":", 1);
2402 MD5_Update(&ctx, uri, strlen(uri));
2403 MD5_Final(digest_mu, &ctx);
2404 pthread_setcancelstate(oldState, NULL);
2405 #endif
2406
2407 #ifdef CONFIG_MBEDTLS
2408 #if MBEDTLS_VERSION_MINOR >= 7
2409 mbedtls_md5_context tctx;
2410 mbedtls_md5_starts_ret(&tctx);
2411 mbedtls_md5_update_ret(&tctx, (const unsigned char *)username, strlen(username));
2412 mbedtls_md5_update_ret(&tctx, (unsigned char *)":", 1);
2413 mbedtls_md5_update_ret(&tctx, (const unsigned char *)realm, strlen(realm));
2414 mbedtls_md5_update_ret(&tctx, (unsigned char *)":", 1);
2415 mbedtls_md5_update_ret(&tctx, (const unsigned char *)config.password, strlen(config.password));
2416 mbedtls_md5_finish_ret(&tctx, digest_urp);
2417 mbedtls_md5_starts_ret(&tctx);
2418 mbedtls_md5_update_ret(&tctx, (const unsigned char *)req->method, strlen(req->method));
2419 mbedtls_md5_update_ret(&tctx, (unsigned char *)":", 1);
2420 mbedtls_md5_update_ret(&tctx, (const unsigned char *)uri, strlen(uri));
2421 mbedtls_md5_finish_ret(&tctx, digest_mu);
2422 #else
2423 mbedtls_md5_context tctx;
2424 mbedtls_md5_starts(&tctx);
2425 mbedtls_md5_update(&tctx, (const unsigned char *)username, strlen(username));
2426 mbedtls_md5_update(&tctx, (unsigned char *)":", 1);
2427 mbedtls_md5_update(&tctx, (const unsigned char *)realm, strlen(realm));
2428 mbedtls_md5_update(&tctx, (unsigned char *)":", 1);
2429 mbedtls_md5_update(&tctx, (const unsigned char *)config.password, strlen(config.password));
2430 mbedtls_md5_finish(&tctx, digest_urp);
2431 mbedtls_md5_starts(&tctx);
2432 mbedtls_md5_update(&tctx, (const unsigned char *)req->method, strlen(req->method));
2433 mbedtls_md5_update(&tctx, (unsigned char *)":", 1);
2434 mbedtls_md5_update(&tctx, (const unsigned char *)uri, strlen(uri));
2435 mbedtls_md5_finish(&tctx, digest_mu);
2436 #endif
2437 #endif
2438
2439 #ifdef CONFIG_POLARSSL
2440 md5_context tctx;
2441 md5_starts(&tctx);
2442 md5_update(&tctx, (const unsigned char *)username, strlen(username));
2443 md5_update(&tctx, (unsigned char *)":", 1);
2444 md5_update(&tctx, (const unsigned char *)realm, strlen(realm));
2445 md5_update(&tctx, (unsigned char *)":", 1);
2446 md5_update(&tctx, (const unsigned char *)config.password, strlen(config.password));
2447 md5_finish(&tctx, digest_urp);
2448 md5_starts(&tctx);
2449 md5_update(&tctx, (const unsigned char *)req->method, strlen(req->method));
2450 md5_update(&tctx, (unsigned char *)":", 1);
2451 md5_update(&tctx, (const unsigned char *)uri, strlen(uri));
2452 md5_finish(&tctx, digest_mu);
2453 #endif
2454
2455 int i;
2456 unsigned char buf[33];
2457 for (i = 0; i < 16; i++)
2458 snprintf((char *)buf + 2 * i, 3, "%02x", digest_urp[i]);
2459
2460 #ifdef CONFIG_OPENSSL
2461 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
2462 MD5_Init(&ctx);
2463 MD5_Update(&ctx, buf, 32);
2464 MD5_Update(&ctx, ":", 1);
2465 MD5_Update(&ctx, *nonce, strlen(*nonce));
2466 MD5_Update(&ctx, ":", 1);
2467 for (i = 0; i < 16; i++)
2468 snprintf((char *)buf + 2 * i, 3, "%02x", digest_mu[i]);
2469 MD5_Update(&ctx, buf, 32);
2470 MD5_Final(digest_total, &ctx);
2471 pthread_setcancelstate(oldState, NULL);
2472 #endif
2473
2474 #ifdef CONFIG_MBEDTLS
2475 #if MBEDTLS_VERSION_MINOR >= 7
2476 mbedtls_md5_starts_ret(&tctx);
2477 mbedtls_md5_update_ret(&tctx, buf, 32);
2478 mbedtls_md5_update_ret(&tctx, (unsigned char *)":", 1);
2479 mbedtls_md5_update_ret(&tctx, (const unsigned char *)*nonce, strlen(*nonce));
2480 mbedtls_md5_update_ret(&tctx, (unsigned char *)":", 1);
2481 for (i = 0; i < 16; i++)
2482 snprintf((char *)buf + 2 * i, 3, "%02x", digest_mu[i]);
2483 mbedtls_md5_update_ret(&tctx, buf, 32);
2484 mbedtls_md5_finish_ret(&tctx, digest_total);
2485 #else
2486 mbedtls_md5_starts(&tctx);
2487 mbedtls_md5_update(&tctx, buf, 32);
2488 mbedtls_md5_update(&tctx, (unsigned char *)":", 1);
2489 mbedtls_md5_update(&tctx, (const unsigned char *)*nonce, strlen(*nonce));
2490 mbedtls_md5_update(&tctx, (unsigned char *)":", 1);
2491 for (i = 0; i < 16; i++)
2492 snprintf((char *)buf + 2 * i, 3, "%02x", digest_mu[i]);
2493 mbedtls_md5_update(&tctx, buf, 32);
2494 mbedtls_md5_finish(&tctx, digest_total);
2495 #endif
2496 #endif
2497
2498 #ifdef CONFIG_POLARSSL
2499 md5_starts(&tctx);
2500 md5_update(&tctx, buf, 32);
2501 md5_update(&tctx, (unsigned char *)":", 1);
2502 md5_update(&tctx, (const unsigned char *)*nonce, strlen(*nonce));
2503 md5_update(&tctx, (unsigned char *)":", 1);
2504 for (i = 0; i < 16; i++)
2505 snprintf((char *)buf + 2 * i, 3, "%02x", digest_mu[i]);
2506 md5_update(&tctx, buf, 32);
2507 md5_finish(&tctx, digest_total);
2508 #endif
2509
2510 for (i = 0; i < 16; i++)
2511 snprintf((char *)buf + 2 * i, 3, "%02x", digest_total[i]);
2512
2513 if (!strcmp(response, (const char *)buf))
2514 return 0;
2515 warn("Password authorization failed.");
2516
2517 authenticate:
2518 resp->respcode = 401;
2519 int hdrlen = strlen(*nonce) + 40;
2520 char *authhdr = malloc(hdrlen);
2521 snprintf(authhdr, hdrlen, "Digest realm=\"raop\", nonce=\"%s\"", *nonce);
2522 msg_add_header(resp, "WWW-Authenticate", authhdr);
2523 free(authhdr);
2524 return 1;
2525 }
2526
rtsp_conversation_thread_cleanup_function(void * arg)2527 void rtsp_conversation_thread_cleanup_function(void *arg) {
2528 rtsp_conn_info *conn = (rtsp_conn_info *)arg;
2529 int oldState;
2530 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
2531
2532 debug(3, "Connection %d: rtsp_conversation_thread_func_cleanup_function called.",
2533 conn->connection_number);
2534 if (conn->player_thread)
2535 player_stop(conn);
2536
2537 debug(3, "Closing timing, control and audio sockets...");
2538 if (conn->control_socket)
2539 close(conn->control_socket);
2540 if (conn->timing_socket)
2541 close(conn->timing_socket);
2542 if (conn->audio_socket)
2543 close(conn->audio_socket);
2544
2545 if (conn->fd > 0) {
2546 debug(3, "Connection %d: closing fd %d.", conn->connection_number, conn->fd);
2547 close(conn->fd);
2548 debug(3, "Connection %d: closed fd %d.", conn->connection_number, conn->fd);
2549 }
2550 if (conn->auth_nonce) {
2551 free(conn->auth_nonce);
2552 conn->auth_nonce = NULL;
2553 }
2554 rtp_terminate(conn);
2555
2556 if (conn->dacp_id) {
2557 free(conn->dacp_id);
2558 conn->dacp_id = NULL;
2559 }
2560
2561 if (conn->UserAgent) {
2562 free(conn->UserAgent);
2563 conn->UserAgent = NULL;
2564 }
2565
2566 // remove flow control and mutexes
2567 int rc = pthread_mutex_destroy(&conn->volume_control_mutex);
2568 if (rc)
2569 debug(1, "Connection %d: error %d destroying volume_control_mutex.", conn->connection_number,
2570 rc);
2571 rc = pthread_cond_destroy(&conn->flowcontrol);
2572 if (rc)
2573 debug(1, "Connection %d: error %d destroying flow control condition variable.",
2574 conn->connection_number, rc);
2575 rc = pthread_mutex_destroy(&conn->ab_mutex);
2576 if (rc)
2577 debug(1, "Connection %d: error %d destroying ab_mutex.", conn->connection_number, rc);
2578 rc = pthread_mutex_destroy(&conn->flush_mutex);
2579 if (rc)
2580 debug(1, "Connection %d: error %d destroying flush_mutex.", conn->connection_number, rc);
2581
2582 debug(3, "Cancel watchdog thread.");
2583 pthread_cancel(conn->player_watchdog_thread);
2584 debug(3, "Join watchdog thread.");
2585 pthread_join(conn->player_watchdog_thread, NULL);
2586 debug(3, "Delete watchdog mutex.");
2587 pthread_mutex_destroy(&conn->watchdog_mutex);
2588
2589 debug(3, "Connection %d: Checking play lock.", conn->connection_number);
2590 debug_mutex_lock(&playing_conn_lock, 1000000, 3); // get it
2591 if (playing_conn == conn) { // if it's ours
2592 debug(3, "Connection %d: Unlocking play lock.", conn->connection_number);
2593 playing_conn = NULL; // let it go
2594 }
2595 debug_mutex_unlock(&playing_conn_lock, 3);
2596
2597 debug(2, "Connection %d: terminated.", conn->connection_number);
2598 conn->running = 0;
2599 pthread_setcancelstate(oldState, NULL);
2600 }
2601
msg_cleanup_function(void * arg)2602 void msg_cleanup_function(void *arg) {
2603 // debug(3, "msg_cleanup_function called.");
2604 msg_free((rtsp_message **)arg);
2605 }
2606
rtsp_conversation_thread_func(void * pconn)2607 static void *rtsp_conversation_thread_func(void *pconn) {
2608 rtsp_conn_info *conn = pconn;
2609
2610 // create the watchdog mutex, initialise the watchdog time and start the watchdog thread;
2611 conn->watchdog_bark_time = get_absolute_time_in_ns();
2612 pthread_mutex_init(&conn->watchdog_mutex, NULL);
2613 pthread_create(&conn->player_watchdog_thread, NULL, &player_watchdog_thread_code, (void *)conn);
2614
2615 int rc = pthread_mutex_init(&conn->flush_mutex, NULL);
2616 if (rc)
2617 die("Connection %d: error %d initialising flush_mutex.", conn->connection_number, rc);
2618 rc = pthread_mutex_init(&conn->ab_mutex, NULL);
2619 if (rc)
2620 die("Connection %d: error %d initialising ab_mutex.", conn->connection_number, rc);
2621 // set the flowcontrol condition variable to wait on a monotonic clock
2622 #ifdef COMPILE_FOR_LINUX_AND_FREEBSD_AND_CYGWIN_AND_OPENBSD
2623 pthread_condattr_t attr;
2624 pthread_condattr_init(&attr);
2625 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); // can't do this in OS X, and don't need it.
2626 rc = pthread_cond_init(&conn->flowcontrol, &attr);
2627 #endif
2628 #ifdef COMPILE_FOR_OSX
2629 rc = pthread_cond_init(&conn->flowcontrol, NULL);
2630 #endif
2631 if (rc)
2632 die("Connection %d: error %d initialising flow control condition variable.",
2633 conn->connection_number, rc);
2634 rc = pthread_mutex_init(&conn->volume_control_mutex, NULL);
2635 if (rc)
2636 die("Connection %d: error %d initialising volume_control_mutex.", conn->connection_number, rc);
2637
2638 // nothing before this is cancellable
2639 pthread_cleanup_push(rtsp_conversation_thread_cleanup_function, (void *)conn);
2640
2641 rtp_initialise(conn);
2642 char *hdr = NULL;
2643
2644 enum rtsp_read_request_response reply;
2645
2646 int rtsp_read_request_attempt_count = 1; // 1 means exit immediately
2647 rtsp_message *req, *resp;
2648
2649 while (conn->stop == 0) {
2650 int debug_level = 3; // for printing the request and response
2651 reply = rtsp_read_request(conn, &req);
2652 if (reply == rtsp_read_request_response_ok) {
2653 pthread_cleanup_push(msg_cleanup_function, (void *)&req);
2654 resp = msg_init();
2655 pthread_cleanup_push(msg_cleanup_function, (void *)&resp);
2656 resp->respcode = 400;
2657
2658 if (strcmp(req->method, "OPTIONS") !=
2659 0) // the options message is very common, so don't log it until level 3
2660 debug_level = 2;
2661 debug(debug_level,
2662 "Connection %d: Received an RTSP Packet of type \"%s\":", conn->connection_number,
2663 req->method),
2664 debug_print_msg_headers(debug_level, req);
2665
2666 apple_challenge(conn->fd, req, resp);
2667 hdr = msg_get_header(req, "CSeq");
2668 if (hdr)
2669 msg_add_header(resp, "CSeq", hdr);
2670 // msg_add_header(resp, "Audio-Jack-Status", "connected; type=analog");
2671 msg_add_header(resp, "Server", "AirTunes/105.1");
2672
2673 if ((conn->authorized == 1) || (rtsp_auth(&conn->auth_nonce, req, resp)) == 0) {
2674 conn->authorized = 1; // it must have been authorized or didn't need a password
2675 struct method_handler *mh;
2676 int method_selected = 0;
2677 for (mh = method_handlers; mh->method; mh++) {
2678 if (!strcmp(mh->method, req->method)) {
2679 method_selected = 1;
2680 mh->handler(conn, req, resp);
2681 break;
2682 }
2683 }
2684 if (method_selected == 0) {
2685 debug(3, "Connection %d: Unrecognised and unhandled rtsp request \"%s\".",
2686 conn->connection_number, req->method);
2687
2688 int y = req->contentlength;
2689 if (y > 0) {
2690 char obf[4096];
2691 if (y > 4096)
2692 y = 4096;
2693 char *p = req->content;
2694 char *obfp = obf;
2695 int obfc;
2696 for (obfc = 0; obfc < y; obfc++) {
2697 snprintf(obfp, 3, "%02X", (unsigned int)*p);
2698 p++;
2699 obfp += 2;
2700 };
2701 *obfp = 0;
2702 debug(3, "Content: \"%s\".", obf);
2703 }
2704 }
2705 }
2706 debug(debug_level, "Connection %d: RTSP Response:", conn->connection_number);
2707 debug_print_msg_headers(debug_level, resp);
2708
2709 if (conn->stop == 0) {
2710 int err = msg_write_response(conn->fd, resp);
2711 if (err) {
2712 debug(1,
2713 "Connection %d: Unable to write an RTSP message response. Terminating the "
2714 "connection.",
2715 conn->connection_number);
2716 struct linger so_linger;
2717 so_linger.l_onoff = 1; // "true"
2718 so_linger.l_linger = 0;
2719 err = setsockopt(conn->fd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger);
2720 if (err)
2721 debug(1, "Could not set the RTSP socket to abort due to a write error on closing.");
2722 conn->stop = 1;
2723 // if (debuglev >= 1)
2724 // debuglev = 3; // see what happens next
2725 }
2726 }
2727 pthread_cleanup_pop(1);
2728 pthread_cleanup_pop(1);
2729 } else {
2730 int tstop = 0;
2731 if (reply == rtsp_read_request_response_immediate_shutdown_requested)
2732 tstop = 1;
2733 else if ((reply == rtsp_read_request_response_channel_closed) ||
2734 (reply == rtsp_read_request_response_read_error)) {
2735 if (conn->player_thread) {
2736 rtsp_read_request_attempt_count--;
2737 if (rtsp_read_request_attempt_count == 0) {
2738 tstop = 1;
2739 if (reply == rtsp_read_request_response_read_error) {
2740 struct linger so_linger;
2741 so_linger.l_onoff = 1; // "true"
2742 so_linger.l_linger = 0;
2743 int err = setsockopt(conn->fd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger);
2744 if (err)
2745 debug(1, "Could not set the RTSP socket to abort due to a read error on closing.");
2746 }
2747 // debuglev = 3; // see what happens next
2748 } else {
2749 if (reply == rtsp_read_request_response_channel_closed)
2750 debug(2,
2751 "Connection %d: RTSP channel unexpectedly closed -- will try again %d time(s).",
2752 conn->connection_number, rtsp_read_request_attempt_count);
2753 if (reply == rtsp_read_request_response_read_error)
2754 debug(2, "Connection %d: RTSP channel read error -- will try again %d time(s).",
2755 conn->connection_number, rtsp_read_request_attempt_count);
2756 usleep(20000);
2757 }
2758 } else {
2759 tstop = 1;
2760 }
2761 } else if (reply == rtsp_read_request_response_bad_packet) {
2762 char *response_text = "RTSP/1.0 400 Bad Request\r\nServer: AirTunes/105.1\r\n\r\n";
2763 ssize_t reply = write(conn->fd, response_text, strlen(response_text));
2764 if (reply == -1) {
2765 char errorstring[1024];
2766 strerror_r(errno, (char *)errorstring, sizeof(errorstring));
2767 debug(1, "rtsp_read_request_response_bad_packet write response error %d: \"%s\".", errno,
2768 (char *)errorstring);
2769 } else if (reply != (ssize_t)strlen(response_text)) {
2770 debug(1, "rtsp_read_request_response_bad_packet write %d bytes requested but %d written.",
2771 strlen(response_text), reply);
2772 }
2773 } else {
2774 debug(1, "Connection %d: rtsp_read_request error %d, packet ignored.",
2775 conn->connection_number, (int)reply);
2776 }
2777 if (tstop) {
2778 debug(3, "Connection %d: Terminate RTSP connection.", conn->connection_number);
2779 conn->stop = 1;
2780 }
2781 }
2782 }
2783 pthread_cleanup_pop(1);
2784 pthread_exit(NULL);
2785 }
2786
2787 /*
2788 // this function is not thread safe.
2789 static const char *format_address(struct sockaddr *fsa) {
2790 static char string[INETx_ADDRSTRLEN];
2791 void *addr;
2792 #ifdef AF_INET6
2793 if (fsa->sa_family == AF_INET6) {
2794 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)(fsa);
2795 addr = &(sa6->sin6_addr);
2796 } else
2797 #endif
2798 {
2799 struct sockaddr_in *sa = (struct sockaddr_in *)(fsa);
2800 addr = &(sa->sin_addr);
2801 }
2802 return inet_ntop(fsa->sa_family, addr, string, sizeof(string));
2803 }
2804 */
2805
rtsp_listen_loop_cleanup_handler(void * arg)2806 void rtsp_listen_loop_cleanup_handler(__attribute__((unused)) void *arg) {
2807 int oldState;
2808 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
2809 debug(2, "rtsp_listen_loop_cleanup_handler called.");
2810 cancel_all_RTSP_threads();
2811 int *sockfd = (int *)arg;
2812 mdns_unregister();
2813 if (sockfd)
2814 free(sockfd);
2815 pthread_setcancelstate(oldState, NULL);
2816 }
2817
rtsp_listen_loop(void)2818 void rtsp_listen_loop(void) {
2819 int oldState;
2820 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
2821 struct addrinfo hints, *info, *p;
2822 char portstr[6];
2823 int *sockfd = NULL;
2824 int nsock = 0;
2825 int i, ret;
2826
2827 playing_conn = NULL; // the data structure representing the connection that has the player.
2828
2829 memset(&hints, 0, sizeof(hints));
2830 hints.ai_family = AF_UNSPEC;
2831 hints.ai_socktype = SOCK_STREAM;
2832 hints.ai_flags = AI_PASSIVE;
2833
2834 snprintf(portstr, 6, "%d", config.port);
2835
2836 // debug(1,"listen socket port request is \"%s\".",portstr);
2837
2838 ret = getaddrinfo(NULL, portstr, &hints, &info);
2839 if (ret) {
2840 die("getaddrinfo failed: %s", gai_strerror(ret));
2841 }
2842
2843 for (p = info; p; p = p->ai_next) {
2844 ret = 0;
2845 int fd = socket(p->ai_family, p->ai_socktype, IPPROTO_TCP);
2846 int yes = 1;
2847
2848 // Handle socket open failures if protocol unavailable (or IPV6 not handled)
2849 if (fd == -1) {
2850 // debug(1, "Failed to get socket: fam=%d, %s\n", p->ai_family,
2851 // strerror(errno));
2852 continue;
2853 }
2854 // Set the RTSP socket to close on exec() of child processes
2855 // otherwise background run_this_before_play_begins or run_this_after_play_ends commands
2856 // that are sleeping prevent the daemon from being restarted because
2857 // the listening RTSP port is still in use.
2858 // See: https://github.com/mikebrady/shairport-sync/issues/329
2859 fcntl(fd, F_SETFD, FD_CLOEXEC);
2860 ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
2861
2862 struct timeval tv;
2863 tv.tv_sec = 3; // three seconds write timeout
2864 tv.tv_usec = 0;
2865 if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&tv, sizeof tv) == -1)
2866 debug(1, "Error %d setting send timeout for rtsp writeback.", errno);
2867
2868 if ((config.dont_check_timeout == 0) && (config.timeout != 0)) {
2869 tv.tv_sec = config.timeout; // 120 seconds read timeout by default.
2870 tv.tv_usec = 0;
2871 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof tv) == -1)
2872 debug(1, "Error %d setting read timeout for rtsp connection.", errno);
2873 }
2874 #ifdef IPV6_V6ONLY
2875 // some systems don't support v4 access on v6 sockets, but some do.
2876 // since we need to account for two sockets we might as well
2877 // always.
2878 if (p->ai_family == AF_INET6) {
2879 ret |= setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes));
2880 }
2881 #endif
2882
2883 if (!ret)
2884 ret = bind(fd, p->ai_addr, p->ai_addrlen);
2885
2886 // one of the address families will fail on some systems that
2887 // report its availability. do not complain.
2888
2889 if (ret) {
2890 char *family;
2891 #ifdef AF_INET6
2892 if (p->ai_family == AF_INET6) {
2893 family = "IPv6";
2894 } else
2895 #endif
2896 family = "IPv4";
2897 debug(1, "unable to listen on %s port %d. The error is: \"%s\".", family, config.port,
2898 strerror(errno));
2899 continue;
2900 }
2901
2902 listen(fd, 5);
2903 nsock++;
2904 sockfd = realloc(sockfd, nsock * sizeof(int));
2905 sockfd[nsock - 1] = fd;
2906 }
2907
2908 freeaddrinfo(info);
2909
2910 if (nsock) {
2911 int maxfd = -1;
2912 fd_set fds;
2913 FD_ZERO(&fds);
2914 for (i = 0; i < nsock; i++) {
2915 if (sockfd[i] > maxfd)
2916 maxfd = sockfd[i];
2917 }
2918
2919 mdns_register();
2920
2921 pthread_setcancelstate(oldState, NULL);
2922 int acceptfd;
2923 struct timeval tv;
2924 pthread_cleanup_push(rtsp_listen_loop_cleanup_handler, (void *)sockfd);
2925 do {
2926 pthread_testcancel();
2927 tv.tv_sec = 60;
2928 tv.tv_usec = 0;
2929
2930 for (i = 0; i < nsock; i++)
2931 FD_SET(sockfd[i], &fds);
2932
2933 ret = select(maxfd + 1, &fds, 0, 0, &tv);
2934 if (ret < 0) {
2935 if (errno == EINTR)
2936 continue;
2937 break;
2938 }
2939
2940 cleanup_threads();
2941
2942 acceptfd = -1;
2943 for (i = 0; i < nsock; i++) {
2944 if (FD_ISSET(sockfd[i], &fds)) {
2945 acceptfd = sockfd[i];
2946 break;
2947 }
2948 }
2949 if (acceptfd < 0) // timeout
2950 continue;
2951
2952 rtsp_conn_info *conn = malloc(sizeof(rtsp_conn_info));
2953 if (conn == 0)
2954 die("Couldn't allocate memory for an rtsp_conn_info record.");
2955 memset(conn, 0, sizeof(rtsp_conn_info));
2956 conn->connection_number = RTSP_connection_index++;
2957 socklen_t slen = sizeof(conn->remote);
2958
2959 conn->fd = accept(acceptfd, (struct sockaddr *)&conn->remote, &slen);
2960 if (conn->fd < 0) {
2961 debug(1, "Connection %d: New connection on port %d not accepted:", conn->connection_number,
2962 config.port);
2963 perror("failed to accept connection");
2964 free(conn);
2965 } else {
2966 SOCKADDR *local_info = (SOCKADDR *)&conn->local;
2967 socklen_t size_of_reply = sizeof(*local_info);
2968 memset(local_info, 0, sizeof(SOCKADDR));
2969 if (getsockname(conn->fd, (struct sockaddr *)local_info, &size_of_reply) == 0) {
2970
2971 // IPv4:
2972 if (local_info->SAFAMILY == AF_INET) {
2973 char ip4[INET_ADDRSTRLEN]; // space to hold the IPv4 string
2974 char remote_ip4[INET_ADDRSTRLEN]; // space to hold the IPv4 string
2975 struct sockaddr_in *sa = (struct sockaddr_in *)local_info;
2976 inet_ntop(AF_INET, &(sa->sin_addr), ip4, INET_ADDRSTRLEN);
2977 unsigned short int tport = ntohs(sa->sin_port);
2978 sa = (struct sockaddr_in *)&conn->remote;
2979 inet_ntop(AF_INET, &(sa->sin_addr), remote_ip4, INET_ADDRSTRLEN);
2980 unsigned short int rport = ntohs(sa->sin_port);
2981 debug(2, "Connection %d: new connection from %s:%u to self at %s:%u.",
2982 conn->connection_number, remote_ip4, rport, ip4, tport);
2983 }
2984 #ifdef AF_INET6
2985 if (local_info->SAFAMILY == AF_INET6) {
2986 // IPv6:
2987
2988 char ip6[INET6_ADDRSTRLEN]; // space to hold the IPv6 string
2989 char remote_ip6[INET6_ADDRSTRLEN]; // space to hold the IPv6 string
2990 struct sockaddr_in6 *sa6 =
2991 (struct sockaddr_in6 *)local_info; // pretend this is loaded with something
2992 inet_ntop(AF_INET6, &(sa6->sin6_addr), ip6, INET6_ADDRSTRLEN);
2993 u_int16_t tport = ntohs(sa6->sin6_port);
2994
2995 sa6 = (struct sockaddr_in6 *)&conn->remote; // pretend this is loaded with something
2996 inet_ntop(AF_INET6, &(sa6->sin6_addr), remote_ip6, INET6_ADDRSTRLEN);
2997 u_int16_t rport = ntohs(sa6->sin6_port);
2998 debug(2, "Connection %d: new connection from [%s]:%u to self at [%s]:%u.",
2999 conn->connection_number, remote_ip6, rport, ip6, tport);
3000 }
3001 #endif
3002
3003 } else {
3004 debug(1, "Error figuring out Shairport Sync's own IP number.");
3005 }
3006 // usleep(500000);
3007 // pthread_t rtsp_conversation_thread;
3008 // conn->thread = rtsp_conversation_thread;
3009 // conn->stop = 0; // record's memory has been zeroed
3010 // conn->authorized = 0; // record's memory has been zeroed
3011 // fcntl(conn->fd, F_SETFL, O_NONBLOCK);
3012
3013 ret = pthread_create(&conn->thread, NULL, rtsp_conversation_thread_func,
3014 conn); // also acts as a memory barrier
3015 if (ret) {
3016 char errorstring[1024];
3017 strerror_r(ret, (char *)errorstring, sizeof(errorstring));
3018 die("Connection %d: cannot create an RTSP conversation thread. Error %d: \"%s\".",
3019 conn->connection_number, ret, (char *)errorstring);
3020 }
3021 debug(3, "Successfully created RTSP receiver thread %d.", conn->connection_number);
3022 conn->running = 1; // this must happen before the thread is tracked
3023 track_thread(conn);
3024 }
3025 } while (1);
3026 pthread_cleanup_pop(1); // should never happen
3027 } else {
3028 die("could not establish a service on port %d -- program terminating. Is another instance of "
3029 "Shairport Sync running on this device?",
3030 config.port);
3031 }
3032 // debug(1, "Oops -- fell out of the RTSP select loop");
3033 }
3034