]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Add full teardown actions to RTSP stream cleanup to correctly close all connections.
authorMike Brady <4265913+mikebrady@users.noreply.github.com>
Sun, 12 Sep 2021 14:24:48 +0000 (15:24 +0100)
committerMike Brady <4265913+mikebrady@users.noreply.github.com>
Sun, 12 Sep 2021 14:24:48 +0000 (15:24 +0100)
rtp.c
rtsp.c

diff --git a/rtp.c b/rtp.c
index 618e068be71096d648bff5e4d201548aa8f26c7a..867923691d2035c37161fccdc59d0972d1629311 100644 (file)
--- a/rtp.c
+++ b/rtp.c
@@ -1564,6 +1564,7 @@ void rtp_ap2_control_handler_cleanup_handler(void *arg) {
   rtsp_conn_info *conn = (rtsp_conn_info *)arg;
   debug(2, "Connection %d: AP2 Control Receiver Cleanup.", conn->connection_number);
   close(conn->ap2_control_socket);
+          debug(1, "Connection %d: UDP control port %u closed.", conn->connection_number, conn->local_ap2_control_port);
   conn->ap2_control_socket = 0;
   conn->ap2_remote_control_socket_addr_length =
       0; // indicates to the control receiver thread that the socket address need to be
@@ -1748,8 +1749,9 @@ void *rtp_ap2_control_receiver(void *arg) {
 
 void rtp_realtime_audio_cleanup_handler(__attribute__((unused)) void *arg) {
   debug(2, "Realtime Audio Receiver Cleanup Start.");
-  rtsp_conn_info *conn = (rtsp_conn_info *)arg;
+  rtsp_conn_info *conn = (rtsp_conn_info *)arg;  
   close(conn->realtime_audio_socket);
+  debug(1, "Connection %d: closing realtime audio port %u", conn->local_realtime_audio_port);
   conn->realtime_audio_socket = 0;
   debug(2, "Realtime Audio Receiver Cleanup Done.");
 }
@@ -2028,6 +2030,7 @@ void rtp_buffered_audio_cleanup_handler(__attribute__((unused)) void *arg) {
   debug(2, "Buffered Audio Receiver Cleanup Start.");
   rtsp_conn_info *conn = (rtsp_conn_info *)arg;
   close(conn->buffered_audio_socket);
+  debug(1, "Connection %d: TCP Buffered Audio port closed: %u.", conn->connection_number, conn->local_buffered_audio_port);
   conn->buffered_audio_socket = 0;
   debug(2, "Buffered Audio Receiver Cleanup Done.");
 }
diff --git a/rtsp.c b/rtsp.c
index dccb21a6e7f5c416d2070aac2ba3f7aa99fb4de9..c8bec51cdb75356084877137daf156789b5a093a 100644 (file)
--- a/rtsp.c
+++ b/rtsp.c
@@ -658,16 +658,16 @@ void cancel_all_RTSP_threads(airplay_stream_c stream_category, int except_this_o
     if ((conns[i] != NULL) && (conns[i]->running != 0) && (conns[i]->connection_number != except_this_one) &&
         ((stream_category == unspecified_stream_category) ||
          (stream_category == conns[i]->airplay_stream_category))) {
-      debug(1, "Connection %d: stopped.", conns[i]->connection_number);
       pthread_cancel(conns[i]->thread);
+      debug(1, "Connection %d: cancelled.", conns[i]->connection_number);
     }
   }
   for (i = 0; i < nconns; i++) {
     if ((conns[i] != NULL) && (conns[i]->running != 0) && (conns[i]->connection_number != except_this_one) &&
         ((stream_category == unspecified_stream_category) ||
          (stream_category == conns[i]->airplay_stream_category))) {
-      debug(1, "Connection %d: deleted.", conns[i]->connection_number);
       pthread_join(conns[i]->thread, NULL);
+      debug(1, "Connection %d: joined.", conns[i]->connection_number);
       free(conns[i]);
       conns[i] = NULL;
     }
@@ -2305,6 +2305,47 @@ void handle_options(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *
                  "OPTIONS, POST, GET, PUT");
 }
 
+void teardown_phase_one(rtsp_conn_info *conn) {
+  if (conn->player_thread) {
+    player_stop(conn);
+    activity_monitor_signify_activity(0); // inactive, and should be after command_stop()
+  }
+  if (conn->session_key) {
+    free(conn->session_key);
+    conn->session_key = NULL;
+  }
+}
+
+void teardown_phase_two(rtsp_conn_info *conn) {
+  // we are being asked to disconnect
+  debug(1, "Connection %d: TEARDOWN a %s connection.", conn->connection_number,
+        get_category_string(conn->airplay_stream_category));
+  debug(2, "Connection %d: TEARDOWN Delete Event Thread.", conn->connection_number);
+  pthread_cancel(conn->rtp_event_thread);
+  pthread_join(conn->rtp_event_thread, NULL);
+  debug(1, "Connection %d: TEARDOWN Close Event Socket.", conn->connection_number);
+  if (conn->event_socket) {
+    close(conn->event_socket);
+    conn->event_socket = 0;
+    debug(1, "Connection %d: closing TCP event port %u.", conn->connection_number, conn->local_event_port);
+  }
+
+  // if we are closing a PTP stream only, do this
+  if (conn->airplay_stream_category == ptp_stream) {
+    if (conn->airplay_gid != NULL) {
+      free(conn->airplay_gid);
+      conn->airplay_gid = NULL;
+    }
+    conn->groupContainsGroupLeader = 0;
+    config.airplay_statusflags &= (0xffffffff - (1 << 11)); // DeviceSupportsRelay
+    build_bonjour_strings(conn);
+    debug(1, "Connection %d: TEARDOWN mdns_update on %s.", conn->connection_number,
+          get_category_string(conn->airplay_stream_category));
+    mdns_update(NULL, secondary_txt_records);
+  }
+}
+
+
 void handle_teardown_2(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *req,
                        rtsp_message *resp) {
 
@@ -2322,38 +2363,11 @@ void handle_teardown_2(rtsp_conn_info *conn, __attribute__((unused)) rtsp_messag
       debug(1, "Connection %d: TEARDOWN a %s.", conn->connection_number,
             get_category_string(conn->airplay_stream_category));
       // we are being asked to close a stream
-      player_stop(conn);
-      activity_monitor_signify_activity(0); // inactive, and should be after command_stop()
-      if (conn->session_key) {
-        free(conn->session_key);
-        conn->session_key = NULL;
-      }
+      teardown_phase_one(conn);
       plist_free(streams);
       debug(2, "Connection %d: Stream TEARDOWN complete", conn->connection_number);
     } else {
-      // we are being asked to disconnect
-      debug(1, "Connection %d: TEARDOWN a %s connection.", conn->connection_number,
-            get_category_string(conn->airplay_stream_category));
-      debug(2, "Connection %d: TEARDOWN Delete Event Thread.", conn->connection_number);
-      pthread_cancel(conn->rtp_event_thread);
-      pthread_join(conn->rtp_event_thread, NULL);
-      debug(2, "Connection %d: TEARDOWN Close Event Socket.", conn->connection_number);
-      if (conn->event_socket)
-        close(conn->event_socket);
-
-      // if we are closing a PTP stream only, do this
-      if (conn->airplay_stream_category == ptp_stream) {
-        if (conn->airplay_gid != NULL) {
-          free(conn->airplay_gid);
-          conn->airplay_gid = NULL;
-        }
-        conn->groupContainsGroupLeader = 0;
-        config.airplay_statusflags &= (0xffffffff - (1 << 11)); // DeviceSupportsRelay
-        build_bonjour_strings(conn);
-        debug(1, "Connection %d: TEARDOWN mdns_update on %s.", conn->connection_number,
-              get_category_string(conn->airplay_stream_category));
-        mdns_update(NULL, secondary_txt_records);
-      }
+      teardown_phase_two(conn);
       debug(2, "Connection %d: non-stream TEARDOWN complete", conn->connection_number);
     }
     //} else {
@@ -2627,6 +2641,8 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
                   conn->connection_number, err);
             }
 
+            debug(1, "Connection %d: TCP PTP event port opened: %u.", conn->connection_number, conn->local_event_port);
+
             pthread_create(&conn->rtp_event_thread, NULL, &rtp_event_receiver, (void *)conn);
 
             plist_dict_set_item(setupResponsePlist, "eventPort",
@@ -2664,6 +2680,8 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
                 "port",
                 conn->connection_number, err);
           }
+          
+          debug(1, "Connection %d: TCP Remote Control event port opened: %u.", conn->connection_number, conn->local_event_port);
 
           pthread_create(&conn->rtp_event_thread, NULL, &rtp_event_receiver, (void *)conn);
 
@@ -2711,6 +2729,7 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
       if (err) {
         die("Error %d: could not find a UDP port to use as an ap2_control port", err);
       }
+      debug(1, "Connection %d: UDP control port opened: %u.", conn->connection_number, conn->local_ap2_control_port);
 
       pthread_create(&conn->rtp_ap2_control_thread, NULL, &rtp_ap2_control_receiver, (void *)conn);
 
@@ -2780,6 +2799,7 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
         if (err) {
           die("Error %d: could not find a UDP port to use as a realtime_audio port", err);
         }
+        debug(1, "Connection %d: UDP realtime audio port opened: %u.", conn->connection_number, conn->local_realtime_audio_port);
 
         pthread_create(&conn->rtp_realtime_audio_thread, NULL, &rtp_realtime_audio_receiver,
                        (void *)conn);
@@ -2842,6 +2862,8 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
               conn->connection_number, err);
         }
 
+        debug(1, "Connection %d: TCP Buffered Audio port opened: %u.", conn->connection_number, conn->local_buffered_audio_port);
+
         // hack.
         conn->max_frames_per_packet = 352; // number of audio frames per packet.
         conn->input_rate = 44100;          // we are stuck with this for the moment.
@@ -4448,26 +4470,36 @@ void rtsp_conversation_thread_cleanup_function(void *arg) {
   int oldState;
   pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
 
-  debug(3, "Connection %d: rtsp_conversation_thread_func_cleanup_function called.",
+  debug(1, "Connection %d: rtsp_conversation_thread_func_cleanup_function called.",
         conn->connection_number);
-  if (conn->player_thread) {
-    player_stop(conn);
-    activity_monitor_signify_activity(0); // inactive, and should be after command_stop()
-  }
+  teardown_phase_one(conn);
+  teardown_phase_two(conn);
 
   debug(3, "Connection %d terminating:Closing timing, control and audio sockets...",
         conn->connection_number);
-  if (conn->control_socket)
+  if (conn->control_socket) {
     close(conn->control_socket);
-  if (conn->timing_socket)
+    debug(1, "Connection %d: closing control port %u", conn->local_ap2_control_port);
+  }
+  if (conn->timing_socket) {
     close(conn->timing_socket);
-  if (conn->audio_socket)
+    debug(1, "Connection %d: closing timing port %u", conn->local_ap2_control_port);
+  }
+  if (conn->audio_socket) {
     close(conn->audio_socket);
+    debug(1, "Connection %d: closing audio port %u", conn->local_ap2_control_port);
+  }
+  
+  
 
   if (conn->fd > 0) {
     debug(3, "Connection %d terminating: closing fd %d.", conn->connection_number, conn->fd);
     close(conn->fd);
     debug(3, "Connection %d terminating: closed fd %d.", conn->connection_number, conn->fd);
+
+    debug(1, "Connection %d: terminating connection from %s:%u to self at %s:%u.",
+          conn->connection_number, conn->client_ip_string, conn->client_rtsp_port,
+          conn->self_ip_string, conn->self_rtsp_port);
   }
   if (conn->auth_nonce) {
     free(conn->auth_nonce);
@@ -4958,7 +4990,7 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
           inet_ntop(conn->connection_ip_family, self_addr, conn->self_ip_string,
                     sizeof(conn->self_ip_string));
 
-          debug(2, "Connection %d: new connection from %s:%u to self at %s:%u.",
+          debug(1, "Connection %d: new connection from %s:%u to self at %s:%u.",
                 conn->connection_number, conn->client_ip_string, conn->client_rtsp_port,
                 conn->self_ip_string, conn->self_rtsp_port);
         } else {