]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Fix deadlocks in RTSP code 72/head
authorJoseph C. Lehner <joseph.c.lehner@gmail.com>
Thu, 16 Apr 2015 09:53:39 +0000 (11:53 +0200)
committerJoseph C. Lehner <joseph.c.lehner@gmail.com>
Thu, 16 Apr 2015 09:53:39 +0000 (11:53 +0200)
If the ANNOUNCE and/or SETUP method fails, the play_lock mutex
is never unlocked, thus blocking other clients from connecting.

This patch unlocks play_lock if an error occurs in either ANNOUNCE
or SETUP.

rtsp.c

diff --git a/rtsp.c b/rtsp.c
index 91e0728e24574d4ba6ec1148b8a954a51c5f4ce1..4d4c4811e00fd17a11f288b0c34708e8a0a476da 100644 (file)
--- a/rtsp.c
+++ b/rtsp.c
@@ -681,25 +681,25 @@ static void handle_setup(rtsp_conn_info *conn,
     }
     char *hdr = msg_get_header(req, "Transport");
     if (!hdr)
-        return;
+        goto error;
 
     char *p;
     p = strstr(hdr, "control_port=");
     if (!p)
-        return;
+        goto error;
     p = strchr(p, '=') + 1;
     cport = atoi(p);
 
     p = strstr(hdr, "timing_port=");
     if (!p)
-        return;
+        goto error;
     p = strchr(p, '=') + 1;
     tport = atoi(p);
 
     rtsp_take_player();
     rtp_setup(&conn->remote, cport, tport, active_remote, &lsport,&lcport,&ltport);
     if (!lsport)
-        return;
+        goto error;
     char *q;
     p = strstr(hdr,"control_port=");
     if (p) {
@@ -727,6 +727,12 @@ static void handle_setup(rtsp_conn_info *conn,
     msg_add_header(resp, "Session", "1");
 
     resp->respcode = 200;
+    return;
+
+error:
+    warn("Error in setup request.");
+    pthread_mutex_unlock(&play_lock);
+    resp->respcode = 451; // invalid arguments
 }
 
 static void handle_ignore(rtsp_conn_info *conn,
@@ -1124,7 +1130,7 @@ static void handle_announce(rtsp_conn_info *conn,
 
     if (!paesiv || !prsaaeskey || !pfmtp) {
       warn("required params missing from announce");
-      return;
+      goto out;
     }
 
     int len, keylen;
@@ -1132,7 +1138,7 @@ static void handle_announce(rtsp_conn_info *conn,
     if (len != 16) {
       warn("client announced aeskey of %d bytes, wanted 16", len);
       free(aesiv);
-      return;
+      goto out;
     }
     memcpy(conn->stream.aesiv, aesiv, 16);
     free(aesiv);
@@ -1143,7 +1149,7 @@ static void handle_announce(rtsp_conn_info *conn,
     if (keylen != 16) {
       warn("client announced rsaaeskey of %d bytes, wanted 16", keylen);
       free(aeskey);
-      return;
+      goto out;
     }
     memcpy(conn->stream.aeskey, aeskey, 16);
     free(aeskey);
@@ -1169,6 +1175,11 @@ static void handle_announce(rtsp_conn_info *conn,
     resp->respcode = 453;
     debug(1,"Already playing.");
   }
+
+out:
+  if (resp->respcode != 200 && resp->respcode != 453) {
+    pthread_mutex_unlock(&play_lock);
+  }
 }