mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
rtsp-client: make sure sessmedia will not get freed while used
handle_*_request() functions were all retrieving the session media from the session by calling gst_rtsp_session_get_media () which is a transfer-none call. If a session timeout happens at that time, the session media may get freed making the pointer invalid.. Fixes #757 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1053>
This commit is contained in:
parent
ce76a286ed
commit
7ba665995f
3 changed files with 72 additions and 17 deletions
|
@ -1447,7 +1447,7 @@ handle_teardown_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
||||||
path = klass->make_path_from_uri (client, ctx->uri);
|
path = klass->make_path_from_uri (client, ctx->uri);
|
||||||
|
|
||||||
/* get a handle to the configuration of the media in the session */
|
/* get a handle to the configuration of the media in the session */
|
||||||
sessmedia = gst_rtsp_session_get_media (session, path, &matched);
|
sessmedia = gst_rtsp_session_dup_media (session, path, &matched);
|
||||||
if (!sessmedia)
|
if (!sessmedia)
|
||||||
goto not_found;
|
goto not_found;
|
||||||
|
|
||||||
|
@ -1482,6 +1482,7 @@ handle_teardown_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
||||||
/* unmanage the media in the session, returns false if all media session
|
/* unmanage the media in the session, returns false if all media session
|
||||||
* are torn down. */
|
* are torn down. */
|
||||||
keep_session = gst_rtsp_session_release_media (session, sessmedia);
|
keep_session = gst_rtsp_session_release_media (session, sessmedia);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
|
|
||||||
/* construct the response now */
|
/* construct the response now */
|
||||||
code = GST_RTSP_STS_OK;
|
code = GST_RTSP_STS_OK;
|
||||||
|
@ -1532,6 +1533,7 @@ no_aggregate:
|
||||||
send_generic_response (client,
|
send_generic_response (client,
|
||||||
GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, ctx);
|
GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, ctx);
|
||||||
g_free (path);
|
g_free (path);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
sig_failed:
|
sig_failed:
|
||||||
|
@ -1541,6 +1543,7 @@ sig_failed:
|
||||||
send_generic_response (client, sig_result, ctx);
|
send_generic_response (client, sig_result, ctx);
|
||||||
gst_rtsp_media_unlock (media);
|
gst_rtsp_media_unlock (media);
|
||||||
g_object_unref (media);
|
g_object_unref (media);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1699,7 +1702,7 @@ handle_pause_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
||||||
path = klass->make_path_from_uri (client, ctx->uri);
|
path = klass->make_path_from_uri (client, ctx->uri);
|
||||||
|
|
||||||
/* get a handle to the configuration of the media in the session */
|
/* get a handle to the configuration of the media in the session */
|
||||||
sessmedia = gst_rtsp_session_get_media (session, path, &matched);
|
sessmedia = gst_rtsp_session_dup_media (session, path, &matched);
|
||||||
if (!sessmedia)
|
if (!sessmedia)
|
||||||
goto not_found;
|
goto not_found;
|
||||||
|
|
||||||
|
@ -1746,6 +1749,7 @@ handle_pause_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
||||||
|
|
||||||
/* the state is now READY */
|
/* the state is now READY */
|
||||||
gst_rtsp_session_media_set_rtsp_state (sessmedia, GST_RTSP_STATE_READY);
|
gst_rtsp_session_media_set_rtsp_state (sessmedia, GST_RTSP_STATE_READY);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
|
|
||||||
g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PAUSE_REQUEST], 0, ctx);
|
g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PAUSE_REQUEST], 0, ctx);
|
||||||
|
|
||||||
|
@ -1779,6 +1783,7 @@ no_aggregate:
|
||||||
GST_ERROR ("client %p: no aggregate path %s", client, path);
|
GST_ERROR ("client %p: no aggregate path %s", client, path);
|
||||||
send_generic_response (client,
|
send_generic_response (client,
|
||||||
GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, ctx);
|
GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, ctx);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
g_free (path);
|
g_free (path);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1788,6 +1793,7 @@ sig_failed:
|
||||||
gst_rtsp_status_as_text (sig_result));
|
gst_rtsp_status_as_text (sig_result));
|
||||||
send_generic_response (client, sig_result, ctx);
|
send_generic_response (client, sig_result, ctx);
|
||||||
gst_rtsp_media_unlock (media);
|
gst_rtsp_media_unlock (media);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
g_object_unref (media);
|
g_object_unref (media);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1797,6 +1803,7 @@ invalid_state:
|
||||||
send_generic_response (client, GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE,
|
send_generic_response (client, GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE,
|
||||||
ctx);
|
ctx);
|
||||||
gst_rtsp_media_unlock (media);
|
gst_rtsp_media_unlock (media);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
g_object_unref (media);
|
g_object_unref (media);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1805,6 +1812,7 @@ not_supported:
|
||||||
GST_ERROR ("client %p: pausing not supported", client);
|
GST_ERROR ("client %p: pausing not supported", client);
|
||||||
send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx);
|
send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, ctx);
|
||||||
gst_rtsp_media_unlock (media);
|
gst_rtsp_media_unlock (media);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
g_object_unref (media);
|
g_object_unref (media);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -2068,7 +2076,7 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
||||||
path = klass->make_path_from_uri (client, uri);
|
path = klass->make_path_from_uri (client, uri);
|
||||||
|
|
||||||
/* get a handle to the configuration of the media in the session */
|
/* get a handle to the configuration of the media in the session */
|
||||||
sessmedia = gst_rtsp_session_get_media (session, path, &matched);
|
sessmedia = gst_rtsp_session_dup_media (session, path, &matched);
|
||||||
if (!sessmedia)
|
if (!sessmedia)
|
||||||
goto not_found;
|
goto not_found;
|
||||||
|
|
||||||
|
@ -2163,6 +2171,7 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
||||||
gst_rtsp_session_media_set_state (sessmedia, GST_STATE_PLAYING);
|
gst_rtsp_session_media_set_state (sessmedia, GST_STATE_PLAYING);
|
||||||
|
|
||||||
gst_rtsp_session_media_set_rtsp_state (sessmedia, GST_RTSP_STATE_PLAYING);
|
gst_rtsp_session_media_set_rtsp_state (sessmedia, GST_RTSP_STATE_PLAYING);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
|
|
||||||
g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PLAY_REQUEST], 0, ctx);
|
g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_PLAY_REQUEST], 0, ctx);
|
||||||
|
|
||||||
|
@ -2195,6 +2204,7 @@ no_aggregate:
|
||||||
GST_ERROR ("client %p: no aggregate path %s", client, path);
|
GST_ERROR ("client %p: no aggregate path %s", client, path);
|
||||||
send_generic_response (client,
|
send_generic_response (client,
|
||||||
GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, ctx);
|
GST_RTSP_STS_ONLY_AGGREGATE_OPERATION_ALLOWED, ctx);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
g_free (path);
|
g_free (path);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -2205,6 +2215,7 @@ sig_failed:
|
||||||
send_generic_response (client, sig_result, ctx);
|
send_generic_response (client, sig_result, ctx);
|
||||||
gst_rtsp_media_unlock (media);
|
gst_rtsp_media_unlock (media);
|
||||||
g_object_unref (media);
|
g_object_unref (media);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
invalid_state:
|
invalid_state:
|
||||||
|
@ -2214,6 +2225,7 @@ invalid_state:
|
||||||
ctx);
|
ctx);
|
||||||
gst_rtsp_media_unlock (media);
|
gst_rtsp_media_unlock (media);
|
||||||
g_object_unref (media);
|
g_object_unref (media);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
pipeline_error:
|
pipeline_error:
|
||||||
|
@ -2223,6 +2235,7 @@ pipeline_error:
|
||||||
ctx);
|
ctx);
|
||||||
gst_rtsp_media_unlock (media);
|
gst_rtsp_media_unlock (media);
|
||||||
g_object_unref (media);
|
g_object_unref (media);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
unsuspend_failed:
|
unsuspend_failed:
|
||||||
|
@ -2231,6 +2244,7 @@ unsuspend_failed:
|
||||||
send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx);
|
send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx);
|
||||||
gst_rtsp_media_unlock (media);
|
gst_rtsp_media_unlock (media);
|
||||||
g_object_unref (media);
|
g_object_unref (media);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
invalid_mode:
|
invalid_mode:
|
||||||
|
@ -2239,6 +2253,7 @@ invalid_mode:
|
||||||
send_generic_response (client, code, ctx);
|
send_generic_response (client, code, ctx);
|
||||||
gst_rtsp_media_unlock (media);
|
gst_rtsp_media_unlock (media);
|
||||||
g_object_unref (media);
|
g_object_unref (media);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
unsupported_mode:
|
unsupported_mode:
|
||||||
|
@ -2247,6 +2262,7 @@ unsupported_mode:
|
||||||
send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx);
|
send_generic_response (client, GST_RTSP_STS_METHOD_NOT_ALLOWED, ctx);
|
||||||
gst_rtsp_media_unlock (media);
|
gst_rtsp_media_unlock (media);
|
||||||
g_object_unref (media);
|
g_object_unref (media);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
get_rates_error:
|
get_rates_error:
|
||||||
|
@ -2255,6 +2271,7 @@ get_rates_error:
|
||||||
send_generic_response (client, GST_RTSP_STS_INTERNAL_SERVER_ERROR, ctx);
|
send_generic_response (client, GST_RTSP_STS_INTERNAL_SERVER_ERROR, ctx);
|
||||||
gst_rtsp_media_unlock (media);
|
gst_rtsp_media_unlock (media);
|
||||||
g_object_unref (media);
|
g_object_unref (media);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
adjust_play_response_failed:
|
adjust_play_response_failed:
|
||||||
|
@ -2263,6 +2280,7 @@ adjust_play_response_failed:
|
||||||
send_generic_response (client, code, ctx);
|
send_generic_response (client, code, ctx);
|
||||||
gst_rtsp_media_unlock (media);
|
gst_rtsp_media_unlock (media);
|
||||||
g_object_unref (media);
|
g_object_unref (media);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
rtp_info_error:
|
rtp_info_error:
|
||||||
|
@ -2271,6 +2289,7 @@ rtp_info_error:
|
||||||
send_generic_response (client, GST_RTSP_STS_INTERNAL_SERVER_ERROR, ctx);
|
send_generic_response (client, GST_RTSP_STS_INTERNAL_SERVER_ERROR, ctx);
|
||||||
gst_rtsp_media_unlock (media);
|
gst_rtsp_media_unlock (media);
|
||||||
g_object_unref (media);
|
g_object_unref (media);
|
||||||
|
g_object_unref (sessmedia);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -343,20 +343,9 @@ gst_rtsp_session_release_media (GstRTSPSession * sess,
|
||||||
return more;
|
return more;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static GstRTSPSessionMedia *
|
||||||
* gst_rtsp_session_get_media:
|
_gst_rtsp_session_get_media (GstRTSPSession * sess, const gchar * path,
|
||||||
* @sess: a #GstRTSPSession
|
gint * matched, gboolean dup)
|
||||||
* @path: the path for the media
|
|
||||||
* @matched: (out): the amount of matched characters
|
|
||||||
*
|
|
||||||
* Get the session media for @path. @matched will contain the number of matched
|
|
||||||
* characters of @path.
|
|
||||||
*
|
|
||||||
* Returns: (transfer none) (nullable): the configuration for @path in @sess.
|
|
||||||
*/
|
|
||||||
GstRTSPSessionMedia *
|
|
||||||
gst_rtsp_session_get_media (GstRTSPSession * sess, const gchar * path,
|
|
||||||
gint * matched)
|
|
||||||
{
|
{
|
||||||
GstRTSPSessionPrivate *priv;
|
GstRTSPSessionPrivate *priv;
|
||||||
GstRTSPSessionMedia *result;
|
GstRTSPSessionMedia *result;
|
||||||
|
@ -384,6 +373,9 @@ gst_rtsp_session_get_media (GstRTSPSession * sess, const gchar * path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result && dup)
|
||||||
|
result = g_object_ref (result);
|
||||||
g_mutex_unlock (&priv->lock);
|
g_mutex_unlock (&priv->lock);
|
||||||
|
|
||||||
*matched = best;
|
*matched = best;
|
||||||
|
@ -391,6 +383,45 @@ gst_rtsp_session_get_media (GstRTSPSession * sess, const gchar * path,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_session_get_media:
|
||||||
|
* @sess: a #GstRTSPSession
|
||||||
|
* @path: the path for the media
|
||||||
|
* @matched: (out): the amount of matched characters
|
||||||
|
*
|
||||||
|
* Gets the session media for @path. @matched will contain the number of matched
|
||||||
|
* characters of @path.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none) (nullable): the configuration for @path in @sess.
|
||||||
|
*/
|
||||||
|
GstRTSPSessionMedia *
|
||||||
|
gst_rtsp_session_get_media (GstRTSPSession * sess, const gchar * path,
|
||||||
|
gint * matched)
|
||||||
|
{
|
||||||
|
return _gst_rtsp_session_get_media (sess, path, matched, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_session_dup_media:
|
||||||
|
* @sess: a #GstRTSPSession
|
||||||
|
* @path: the path for the media
|
||||||
|
* @matched: (out): the amount of matched characters
|
||||||
|
*
|
||||||
|
* Gets the session media for @path, increasing its reference count. @matched
|
||||||
|
* will contain the number of matched characters of @path.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full) (nullable): the configuration for @path in @sess,
|
||||||
|
* should be unreferenced when no longer needed.
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
GstRTSPSessionMedia *
|
||||||
|
gst_rtsp_session_dup_media (GstRTSPSession * sess, const gchar * path,
|
||||||
|
gint * matched)
|
||||||
|
{
|
||||||
|
return _gst_rtsp_session_get_media (sess, path, matched, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_rtsp_session_filter:
|
* gst_rtsp_session_filter:
|
||||||
* @sess: a #GstRTSPSession
|
* @sess: a #GstRTSPSession
|
||||||
|
|
|
@ -141,7 +141,12 @@ GST_RTSP_SERVER_API
|
||||||
GstRTSPSessionMedia * gst_rtsp_session_get_media (GstRTSPSession *sess,
|
GstRTSPSessionMedia * gst_rtsp_session_get_media (GstRTSPSession *sess,
|
||||||
const gchar *path,
|
const gchar *path,
|
||||||
gint * matched);
|
gint * matched);
|
||||||
|
/* get media in a session, increasing its reference count */
|
||||||
|
|
||||||
|
GST_RTSP_SERVER_API
|
||||||
|
GstRTSPSessionMedia * gst_rtsp_session_dup_media (GstRTSPSession *sess,
|
||||||
|
const gchar *path,
|
||||||
|
gint * matched);
|
||||||
/**
|
/**
|
||||||
* GstRTSPSessionFilterFunc:
|
* GstRTSPSessionFilterFunc:
|
||||||
* @sess: a #GstRTSPSession object
|
* @sess: a #GstRTSPSession object
|
||||||
|
|
Loading…
Reference in a new issue