rtsp-client: free transport on no_stream in SETUP handler
[platform/upstream/gstreamer.git] / gst / rtsp-server / rtsp-client.c
index 757f08f..0c63108 100644 (file)
 #include "rtsp-sdp.h"
 #include "rtsp-params.h"
 
-/* temporary multicast address until it's configurable somewhere */
-#define MCAST_ADDRESS "224.2.0.1"
-
-static GMutex *tunnels_lock;
+static GMutex tunnels_lock;
 static GHashTable *tunnels;
 
 enum
@@ -50,9 +47,17 @@ enum
   PROP_LAST
 };
 
+enum
+{
+  SIGNAL_CLOSED,
+  SIGNAL_LAST
+};
+
 GST_DEBUG_CATEGORY_STATIC (rtsp_client_debug);
 #define GST_CAT_DEFAULT rtsp_client_debug
 
+static guint gst_rtsp_client_signals[SIGNAL_LAST] = { 0 };
+
 static void gst_rtsp_client_get_property (GObject * object, guint propid,
     GValue * value, GParamSpec * pspec);
 static void gst_rtsp_client_set_property (GObject * object, guint propid,
@@ -89,9 +94,14 @@ gst_rtsp_client_class_init (GstRTSPClientClass * klass)
           GST_TYPE_RTSP_MEDIA_MAPPING,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_rtsp_client_signals[SIGNAL_CLOSED] =
+      g_signal_new ("closed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
+      G_STRUCT_OFFSET (GstRTSPClientClass, closed), NULL, NULL,
+      g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE);
+
   tunnels =
       g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
-  tunnels_lock = g_mutex_new ();
+  g_mutex_init (&tunnels_lock);
 
   GST_DEBUG_CATEGORY_INIT (rtsp_client_debug, "rtspclient", 0, "GstRTSPClient");
 }
@@ -104,12 +114,14 @@ gst_rtsp_client_init (GstRTSPClient * client)
 static void
 client_unlink_session (GstRTSPClient * client, GstRTSPSession * session)
 {
-  GList *medias;
-
   /* unlink all media managed in this session */
-  for (medias = session->medias; medias; medias = g_list_next (medias)) {
-    unlink_session_streams (client, session,
-        (GstRTSPSessionMedia *) medias->data);
+  while (g_list_length (session->medias) > 0) {
+    GstRTSPSessionMedia *media = g_list_first (session->medias)->data;
+
+    gst_rtsp_session_media_set_state (media, GST_STATE_NULL);
+    unlink_session_streams (client, session, media);
+    /* unmanage the media in the session. this will modify session->medias */
+    gst_rtsp_session_release_media (session, media);
   }
 }
 
@@ -144,6 +156,8 @@ gst_rtsp_client_finalize (GObject * obj)
     g_object_unref (client->session_pool);
   if (client->media_mapping)
     g_object_unref (client->media_mapping);
+  if (client->auth)
+    g_object_unref (client->auth);
 
   if (client->uri)
     gst_rtsp_url_free (client->uri);
@@ -242,32 +256,27 @@ send_response (GstRTSPClient * client, GstRTSPSession * session,
 
 static void
 send_generic_response (GstRTSPClient * client, GstRTSPStatusCode code,
-    GstRTSPMessage * request)
+    GstRTSPClientState * state)
 {
-  GstRTSPMessage response = { 0 };
+  gst_rtsp_message_init_response (state->response, code,
+      gst_rtsp_status_as_text (code), state->request);
 
-  gst_rtsp_message_init_response (&response, code,
-      gst_rtsp_status_as_text (code), request);
-
-  send_response (client, NULL, &response);
+  send_response (client, NULL, state->response);
 }
 
 static void
-handle_unauthorized_request (GstRTSPClient * client, GstRTSPUrl * uri,
-    GstRTSPSession * session, GstRTSPMessage * request)
+handle_unauthorized_request (GstRTSPClient * client, GstRTSPAuth * auth,
+    GstRTSPClientState * state)
 {
-  GstRTSPMessage response = { 0 };
+  gst_rtsp_message_init_response (state->response, GST_RTSP_STS_UNAUTHORIZED,
+      gst_rtsp_status_as_text (GST_RTSP_STS_UNAUTHORIZED), state->request);
 
-  gst_rtsp_message_init_response (&response, GST_RTSP_STS_UNAUTHORIZED,
-      gst_rtsp_status_as_text (GST_RTSP_STS_UNAUTHORIZED), request);
-
-  if (client->auth) {
+  if (auth) {
     /* and let the authentication manager setup the auth tokens */
-    gst_rtsp_auth_setup_auth (client->auth, client, uri, session, request,
-        &response);
+    gst_rtsp_auth_setup_auth (auth, client, 0, state);
   }
 
-  send_response (client, session, &response);
+  send_response (client, state->session, state->response);
 }
 
 
@@ -287,12 +296,13 @@ compare_uri (const GstRTSPUrl * uri1, const GstRTSPUrl * uri2)
  * but is cached for when the same client (without breaking the connection) is
  * doing a setup for the exact same url. */
 static GstRTSPMedia *
-find_media (GstRTSPClient * client, GstRTSPUrl * uri, GstRTSPMessage * request)
+find_media (GstRTSPClient * client, GstRTSPClientState * state)
 {
   GstRTSPMediaFactory *factory;
   GstRTSPMedia *media;
+  GstRTSPAuth *auth;
 
-  if (!compare_uri (client->uri, uri)) {
+  if (!compare_uri (client->uri, state->uri)) {
     /* remove any previously cached values before we try to construct a new
      * media for uri */
     if (client->uri)
@@ -307,26 +317,43 @@ find_media (GstRTSPClient * client, GstRTSPUrl * uri, GstRTSPMessage * request)
 
     /* find the factory for the uri first */
     if (!(factory =
-            gst_rtsp_media_mapping_find_factory (client->media_mapping, uri)))
+            gst_rtsp_media_mapping_find_factory (client->media_mapping,
+                state->uri)))
       goto no_factory;
 
+    state->factory = factory;
+
+    /* check if we have access to the factory */
+    if ((auth = gst_rtsp_media_factory_get_auth (factory))) {
+      if (!gst_rtsp_auth_check (auth, client, 0, state))
+        goto not_allowed;
+
+      g_object_unref (auth);
+    }
+
     /* prepare the media and add it to the pipeline */
-    if (!(media = gst_rtsp_media_factory_construct (factory, uri)))
+    if (!(media = gst_rtsp_media_factory_construct (factory, state->uri)))
       goto no_media;
 
+    g_object_unref (factory);
+    factory = NULL;
+    state->factory = NULL;
+
     /* set ipv6 on the media before preparing */
     media->is_ipv6 = client->is_ipv6;
+    state->media = media;
 
     /* prepare the media */
     if (!(gst_rtsp_media_prepare (media)))
       goto no_prepare;
 
     /* now keep track of the uri and the media */
-    client->uri = gst_rtsp_url_copy (uri);
+    client->uri = gst_rtsp_url_copy (state->uri);
     client->media = media;
   } else {
     /* we have seen this uri before, used cached media */
     media = client->media;
+    state->media = media;
     GST_INFO ("reusing cached media %p", media);
   }
 
@@ -338,25 +365,31 @@ find_media (GstRTSPClient * client, GstRTSPUrl * uri, GstRTSPMessage * request)
   /* ERRORS */
 no_mapping:
   {
-    send_generic_response (client, GST_RTSP_STS_NOT_FOUND, request);
+    send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
     return NULL;
   }
 no_factory:
   {
-    send_generic_response (client, GST_RTSP_STS_NOT_FOUND, request);
+    send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
+    return NULL;
+  }
+not_allowed:
+  {
+    handle_unauthorized_request (client, auth, state);
+    g_object_unref (factory);
+    g_object_unref (auth);
     return NULL;
   }
 no_media:
   {
-    send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, request);
+    send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
     g_object_unref (factory);
     return NULL;
   }
 no_prepare:
   {
-    send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, request);
+    send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
     g_object_unref (media);
-    g_object_unref (factory);
     return NULL;
   }
 }
@@ -365,41 +398,25 @@ static gboolean
 do_send_data (GstBuffer * buffer, guint8 channel, GstRTSPClient * client)
 {
   GstRTSPMessage message = { 0 };
+  GstMapInfo map_info;
   guint8 *data;
-  guint size;
+  guint usize;
 
   gst_rtsp_message_init_data (&message, channel);
 
-  data = GST_BUFFER_DATA (buffer);
-  size = GST_BUFFER_SIZE (buffer);
-  gst_rtsp_message_take_body (&message, data, size);
+  if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ))
+    return FALSE;
+
+  gst_rtsp_message_take_body (&message, map_info.data, map_info.size);
 
   /* FIXME, client->watch could have been finalized here, we need to keep an
    * extra refcount to the watch.  */
   gst_rtsp_watch_send_message (client->watch, &message, NULL);
 
-  gst_rtsp_message_steal_body (&message, &data, &size);
-  gst_rtsp_message_unset (&message);
+  gst_rtsp_message_steal_body (&message, &data, &usize);
+  gst_buffer_unmap (buffer, &map_info);
 
-  return TRUE;
-}
-
-static gboolean
-do_send_data_list (GstBufferList * blist, guint8 channel,
-    GstRTSPClient * client)
-{
-  GstBufferListIterator *it;
-
-  it = gst_buffer_list_iterate (blist);
-  while (gst_buffer_list_iterator_next_group (it)) {
-    GstBuffer *group = gst_buffer_list_iterator_merge_group (it);
-
-    if (group == NULL)
-      continue;
-
-    do_send_data (group, channel, client);
-  }
-  gst_buffer_list_iterator_free (it);
+  gst_rtsp_message_unset (&message);
 
   return TRUE;
 }
@@ -410,8 +427,7 @@ link_stream (GstRTSPClient * client, GstRTSPSession * session,
 {
   GST_DEBUG ("client %p: linking stream %p", client, stream);
   gst_rtsp_session_stream_set_callbacks (stream, (GstRTSPSendFunc) do_send_data,
-      (GstRTSPSendFunc) do_send_data, (GstRTSPSendListFunc) do_send_data_list,
-      (GstRTSPSendListFunc) do_send_data_list, client, NULL);
+      (GstRTSPSendFunc) do_send_data, client, NULL);
   client->streams = g_list_prepend (client->streams, stream);
   /* make sure our session can't expire */
   gst_rtsp_session_prevent_expire (session);
@@ -422,8 +438,7 @@ unlink_stream (GstRTSPClient * client, GstRTSPSession * session,
     GstRTSPSessionStream * stream)
 {
   GST_DEBUG ("client %p: unlinking stream %p", client, stream);
-  gst_rtsp_session_stream_set_callbacks (stream, NULL, NULL, NULL, NULL, NULL,
-      NULL);
+  gst_rtsp_session_stream_set_callbacks (stream, NULL, NULL, NULL, NULL);
   client->streams = g_list_remove (client->streams, stream);
   /* our session can now expire */
   gst_rtsp_session_allow_expire (session);
@@ -461,10 +476,10 @@ close_connection (GstRTSPClient * client)
   GST_DEBUG ("client %p: closing connection", client);
 
   if ((tunnelid = gst_rtsp_connection_get_tunnelid (client->connection))) {
-    g_mutex_lock (tunnels_lock);
+    g_mutex_lock (&tunnels_lock);
     /* remove from tunnelids */
     g_hash_table_remove (tunnels, tunnelid);
-    g_mutex_unlock (tunnels_lock);
+    g_mutex_unlock (&tunnels_lock);
   }
 
   gst_rtsp_connection_close (client->connection);
@@ -476,21 +491,24 @@ close_connection (GstRTSPClient * client)
 }
 
 static gboolean
-handle_teardown_request (GstRTSPClient * client, GstRTSPUrl * uri,
-    GstRTSPSession * session, GstRTSPMessage * request)
+handle_teardown_request (GstRTSPClient * client, GstRTSPClientState * state)
 {
+  GstRTSPSession *session;
   GstRTSPSessionMedia *media;
-  GstRTSPMessage response = { 0 };
   GstRTSPStatusCode code;
 
-  if (!session)
+  if (!state->session)
     goto no_session;
 
+  session = state->session;
+
   /* get a handle to the configuration of the media in the session */
-  media = gst_rtsp_session_get_media (session, uri);
+  media = gst_rtsp_session_get_media (session, state->uri);
   if (!media)
     goto not_found;
 
+  state->sessmedia = media;
+
   /* unlink the all TCP callbacks */
   unlink_session_streams (client, session, media);
 
@@ -509,12 +527,13 @@ handle_teardown_request (GstRTSPClient * client, GstRTSPUrl * uri,
   }
   /* construct the response now */
   code = GST_RTSP_STS_OK;
-  gst_rtsp_message_init_response (&response, code,
-      gst_rtsp_status_as_text (code), request);
+  gst_rtsp_message_init_response (state->response, code,
+      gst_rtsp_status_as_text (code), state->request);
 
-  gst_rtsp_message_add_header (&response, GST_RTSP_HDR_CONNECTION, "close");
+  gst_rtsp_message_add_header (state->response, GST_RTSP_HDR_CONNECTION,
+      "close");
 
-  send_response (client, session, &response);
+  send_response (client, session, state->response);
 
   close_connection (client);
 
@@ -523,103 +542,97 @@ handle_teardown_request (GstRTSPClient * client, GstRTSPUrl * uri,
   /* ERRORS */
 no_session:
   {
-    send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, request);
+    send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, state);
     return FALSE;
   }
 not_found:
   {
-    send_generic_response (client, GST_RTSP_STS_NOT_FOUND, request);
+    send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
     return FALSE;
   }
 }
 
 static gboolean
-handle_get_param_request (GstRTSPClient * client, GstRTSPUrl * uri,
-    GstRTSPSession * session, GstRTSPMessage * request)
+handle_get_param_request (GstRTSPClient * client, GstRTSPClientState * state)
 {
   GstRTSPResult res;
   guint8 *data;
   guint size;
 
-  res = gst_rtsp_message_get_body (request, &data, &size);
+  res = gst_rtsp_message_get_body (state->request, &data, &size);
   if (res != GST_RTSP_OK)
     goto bad_request;
 
   if (size == 0) {
     /* no body, keep-alive request */
-    send_generic_response (client, GST_RTSP_STS_OK, request);
+    send_generic_response (client, GST_RTSP_STS_OK, state);
   } else {
-    /* there is a body */
-    GstRTSPMessage response = { 0 };
-
     /* there is a body, handle the params */
-    res = gst_rtsp_params_get (client, uri, session, request, &response);
+    res = gst_rtsp_params_get (client, state);
     if (res != GST_RTSP_OK)
       goto bad_request;
 
-    send_response (client, session, &response);
+    send_response (client, state->session, state->response);
   }
   return TRUE;
 
   /* ERRORS */
 bad_request:
   {
-    send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, request);
+    send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, state);
     return FALSE;
   }
 }
 
 static gboolean
-handle_set_param_request (GstRTSPClient * client, GstRTSPUrl * uri,
-    GstRTSPSession * session, GstRTSPMessage * request)
+handle_set_param_request (GstRTSPClient * client, GstRTSPClientState * state)
 {
   GstRTSPResult res;
   guint8 *data;
   guint size;
 
-  res = gst_rtsp_message_get_body (request, &data, &size);
+  res = gst_rtsp_message_get_body (state->request, &data, &size);
   if (res != GST_RTSP_OK)
     goto bad_request;
 
   if (size == 0) {
     /* no body, keep-alive request */
-    send_generic_response (client, GST_RTSP_STS_OK, request);
+    send_generic_response (client, GST_RTSP_STS_OK, state);
   } else {
-    GstRTSPMessage response = { 0 };
-
     /* there is a body, handle the params */
-    res = gst_rtsp_params_set (client, uri, session, request, &response);
+    res = gst_rtsp_params_set (client, state);
     if (res != GST_RTSP_OK)
       goto bad_request;
 
-    send_response (client, session, &response);
+    send_response (client, state->session, state->response);
   }
   return TRUE;
 
   /* ERRORS */
 bad_request:
   {
-    send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, request);
+    send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, state);
     return FALSE;
   }
 }
 
 static gboolean
-handle_pause_request (GstRTSPClient * client, GstRTSPUrl * uri,
-    GstRTSPSession * session, GstRTSPMessage * request)
+handle_pause_request (GstRTSPClient * client, GstRTSPClientState * state)
 {
+  GstRTSPSession *session;
   GstRTSPSessionMedia *media;
-  GstRTSPMessage response = { 0 };
   GstRTSPStatusCode code;
 
-  if (!session)
+  if (!(session = state->session))
     goto no_session;
 
   /* get a handle to the configuration of the media in the session */
-  media = gst_rtsp_session_get_media (session, uri);
+  media = gst_rtsp_session_get_media (session, state->uri);
   if (!media)
     goto not_found;
 
+  state->sessmedia = media;
+
   /* the session state must be playing or recording */
   if (media->state != GST_RTSP_STATE_PLAYING &&
       media->state != GST_RTSP_STATE_RECORDING)
@@ -633,10 +646,10 @@ handle_pause_request (GstRTSPClient * client, GstRTSPUrl * uri,
 
   /* construct the response now */
   code = GST_RTSP_STS_OK;
-  gst_rtsp_message_init_response (&response, code,
-      gst_rtsp_status_as_text (code), request);
+  gst_rtsp_message_init_response (state->response, code,
+      gst_rtsp_status_as_text (code), state->request);
 
-  send_response (client, session, &response);
+  send_response (client, session, state->response);
 
   /* the state is now READY */
   media->state = GST_RTSP_STATE_READY;
@@ -646,28 +659,27 @@ handle_pause_request (GstRTSPClient * client, GstRTSPUrl * uri,
   /* ERRORS */
 no_session:
   {
-    send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, request);
+    send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, state);
     return FALSE;
   }
 not_found:
   {
-    send_generic_response (client, GST_RTSP_STS_NOT_FOUND, request);
+    send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
     return FALSE;
   }
 invalid_state:
   {
     send_generic_response (client, GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE,
-        request);
+        state);
     return FALSE;
   }
 }
 
 static gboolean
-handle_play_request (GstRTSPClient * client, GstRTSPUrl * uri,
-    GstRTSPSession * session, GstRTSPMessage * request)
+handle_play_request (GstRTSPClient * client, GstRTSPClientState * state)
 {
+  GstRTSPSession *session;
   GstRTSPSessionMedia *media;
-  GstRTSPMessage response = { 0 };
   GstRTSPStatusCode code;
   GString *rtpinfo;
   guint n_streams, i, infocount;
@@ -676,21 +688,24 @@ handle_play_request (GstRTSPClient * client, GstRTSPUrl * uri,
   GstRTSPTimeRange *range;
   GstRTSPResult res;
 
-  if (!session)
+  if (!(session = state->session))
     goto no_session;
 
   /* get a handle to the configuration of the media in the session */
-  media = gst_rtsp_session_get_media (session, uri);
+  media = gst_rtsp_session_get_media (session, state->uri);
   if (!media)
     goto not_found;
 
+  state->sessmedia = media;
+
   /* the session state must be playing or ready */
   if (media->state != GST_RTSP_STATE_PLAYING &&
       media->state != GST_RTSP_STATE_READY)
     goto invalid_state;
 
   /* parse the range header if we have one */
-  res = gst_rtsp_message_get_header (request, GST_RTSP_HDR_RANGE, &str, 0);
+  res =
+      gst_rtsp_message_get_header (state->request, GST_RTSP_HDR_RANGE, &str, 0);
   if (res == GST_RTSP_OK) {
     if (gst_rtsp_range_parse (str, &range) == GST_RTSP_OK) {
       /* we have a range, seek to the position */
@@ -739,7 +754,7 @@ handle_play_request (GstRTSPClient * client, GstRTSPUrl * uri,
       if (infocount > 0)
         g_string_append (rtpinfo, ", ");
 
-      uristr = gst_rtsp_url_get_request_uri (uri);
+      uristr = gst_rtsp_url_get_request_uri (state->uri);
       g_string_append_printf (rtpinfo, "url=%s/stream=%d;seq=%u;rtptime=%u",
           uristr, i, seqnum, timestamp);
       g_free (uristr);
@@ -752,22 +767,22 @@ handle_play_request (GstRTSPClient * client, GstRTSPUrl * uri,
 
   /* construct the response now */
   code = GST_RTSP_STS_OK;
-  gst_rtsp_message_init_response (&response, code,
-      gst_rtsp_status_as_text (code), request);
+  gst_rtsp_message_init_response (state->response, code,
+      gst_rtsp_status_as_text (code), state->request);
 
   /* add the RTP-Info header */
   if (infocount > 0) {
     str = g_string_free (rtpinfo, FALSE);
-    gst_rtsp_message_take_header (&response, GST_RTSP_HDR_RTP_INFO, str);
+    gst_rtsp_message_take_header (state->response, GST_RTSP_HDR_RTP_INFO, str);
   } else {
     g_string_free (rtpinfo, TRUE);
   }
 
   /* add the range */
   str = gst_rtsp_media_get_range_string (media->media, TRUE);
-  gst_rtsp_message_take_header (&response, GST_RTSP_HDR_RANGE, str);
+  gst_rtsp_message_take_header (state->response, GST_RTSP_HDR_RANGE, str);
 
-  send_response (client, session, &response);
+  send_response (client, session, state->response);
 
   /* start playing after sending the request */
   gst_rtsp_session_media_set_state (media, GST_STATE_PLAYING);
@@ -779,18 +794,18 @@ handle_play_request (GstRTSPClient * client, GstRTSPUrl * uri,
   /* ERRORS */
 no_session:
   {
-    send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, request);
+    send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, state);
     return FALSE;
   }
 not_found:
   {
-    send_generic_response (client, GST_RTSP_STS_NOT_FOUND, request);
+    send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
     return FALSE;
   }
 invalid_state:
   {
     send_generic_response (client, GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE,
-        request);
+        state);
     return FALSE;
   }
 }
@@ -803,23 +818,24 @@ do_keepalive (GstRTSPSession * session)
 }
 
 static gboolean
-handle_setup_request (GstRTSPClient * client, GstRTSPUrl * uri,
-    GstRTSPSession * session, GstRTSPMessage * request)
+handle_setup_request (GstRTSPClient * client, GstRTSPClientState * state)
 {
   GstRTSPResult res;
+  GstRTSPUrl *uri;
   gchar *transport;
   gchar **transports;
   gboolean have_transport;
   GstRTSPTransport *ct, *st;
   gint i;
   GstRTSPLowerTrans supported;
-  GstRTSPMessage response = { 0 };
   GstRTSPStatusCode code;
+  GstRTSPSession *session;
   GstRTSPSessionStream *stream;
   gchar *trans_str, *pos;
   guint streamid;
   GstRTSPSessionMedia *media;
-  GstRTSPUrl *url;
+
+  uri = state->uri;
 
   /* the uri contains the stream number we added in the SDP config, which is
    * always /stream=%d so we need to strip that off 
@@ -839,8 +855,8 @@ handle_setup_request (GstRTSPClient * client, GstRTSPUrl * uri,
 
   /* parse the transport */
   res =
-      gst_rtsp_message_get_header (request, GST_RTSP_HDR_TRANSPORT, &transport,
-      0);
+      gst_rtsp_message_get_header (state->request, GST_RTSP_HDR_TRANSPORT,
+      &transport, 0);
   if (res != GST_RTSP_OK)
     goto no_transport;
 
@@ -892,14 +908,7 @@ handle_setup_request (GstRTSPClient * client, GstRTSPUrl * uri,
   if (client->session_pool == NULL)
     goto no_pool;
 
-  /* we have a valid transport now, set the destination of the client. */
-  g_free (ct->destination);
-  if (ct->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) {
-    ct->destination = g_strdup (MCAST_ADDRESS);
-  } else {
-    url = gst_rtsp_connection_get_url (client->connection);
-    ct->destination = g_strdup (url->host);
-  }
+  session = state->session;
 
   if (session) {
     g_object_ref (session);
@@ -912,6 +921,8 @@ handle_setup_request (GstRTSPClient * client, GstRTSPUrl * uri,
     if (!(session = gst_rtsp_session_pool_create (client->session_pool)))
       goto service_unavailable;
 
+    state->session = session;
+
     /* we need a new media configuration in this session */
     media = NULL;
   }
@@ -921,7 +932,7 @@ handle_setup_request (GstRTSPClient * client, GstRTSPUrl * uri,
     GstRTSPMedia *m;
 
     /* get a handle to the configuration of the media in the session */
-    if ((m = find_media (client, uri, request))) {
+    if ((m = find_media (client, state))) {
       /* manage the media in our session now */
       media = gst_rtsp_session_manage_media (session, uri, m);
     }
@@ -931,11 +942,23 @@ handle_setup_request (GstRTSPClient * client, GstRTSPUrl * uri,
   if (media == NULL)
     goto not_found;
 
-  /* fix the transports */
-  if (ct->lower_transport & GST_RTSP_LOWER_TRANS_TCP) {
-    /* check if the client selected channels for TCP */
-    if (ct->interleaved.min == -1 || ct->interleaved.max == -1) {
-      gst_rtsp_session_media_alloc_channels (media, &ct->interleaved);
+  state->sessmedia = media;
+
+  /* we have a valid transport now, set the destination of the client. */
+  g_free (ct->destination);
+  if (ct->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) {
+    ct->destination = gst_rtsp_media_get_multicast_group (media->media);
+  } else {
+    GstRTSPUrl *url;
+
+    url = gst_rtsp_connection_get_url (client->connection);
+    ct->destination = g_strdup (url->host);
+
+    if (ct->lower_transport & GST_RTSP_LOWER_TRANS_TCP) {
+      /* check if the client selected channels for TCP */
+      if (ct->interleaved.min == -1 || ct->interleaved.max == -1) {
+        gst_rtsp_session_media_alloc_channels (media, &ct->interleaved);
+      }
     }
   }
 
@@ -955,13 +978,14 @@ handle_setup_request (GstRTSPClient * client, GstRTSPUrl * uri,
 
   /* construct the response now */
   code = GST_RTSP_STS_OK;
-  gst_rtsp_message_init_response (&response, code,
-      gst_rtsp_status_as_text (code), request);
+  gst_rtsp_message_init_response (state->response, code,
+      gst_rtsp_status_as_text (code), state->request);
 
-  gst_rtsp_message_add_header (&response, GST_RTSP_HDR_TRANSPORT, trans_str);
+  gst_rtsp_message_add_header (state->response, GST_RTSP_HDR_TRANSPORT,
+      trans_str);
   g_free (trans_str);
 
-  send_response (client, session, &response);
+  send_response (client, session, state->response);
 
   /* update the state */
   switch (media->state) {
@@ -981,41 +1005,41 @@ handle_setup_request (GstRTSPClient * client, GstRTSPUrl * uri,
   /* ERRORS */
 bad_request:
   {
-    send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, request);
+    send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, state);
     return FALSE;
   }
 not_found:
   {
-    send_generic_response (client, GST_RTSP_STS_NOT_FOUND, request);
+    send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
     g_object_unref (session);
     return FALSE;
   }
 no_stream:
   {
-    send_generic_response (client, GST_RTSP_STS_NOT_FOUND, request);
-    g_object_unref (media);
+    send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
     g_object_unref (session);
+    gst_rtsp_transport_free (ct);
     return FALSE;
   }
 no_transport:
   {
-    send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, request);
+    send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, state);
     return FALSE;
   }
 unsupported_transports:
   {
-    send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, request);
+    send_generic_response (client, GST_RTSP_STS_UNSUPPORTED_TRANSPORT, state);
     gst_rtsp_transport_free (ct);
     return FALSE;
   }
 no_pool:
   {
-    send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, request);
+    send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
     return FALSE;
   }
 service_unavailable:
   {
-    send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, request);
+    send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
     return FALSE;
   }
 }
@@ -1026,6 +1050,7 @@ create_sdp (GstRTSPClient * client, GstRTSPMedia * media)
   GstSDPMessage *sdp;
   GstSDPInfo info;
   const gchar *proto;
+  GstRTSPLowerTrans protocols;
 
   gst_sdp_message_new (&sdp);
 
@@ -1048,20 +1073,24 @@ create_sdp (GstRTSPClient * client, GstRTSPMedia * media)
   gst_sdp_message_add_attribute (sdp, "control", "*");
 
   info.server_proto = proto;
-  if (media->protocols & GST_RTSP_LOWER_TRANS_UDP_MCAST)
-    info.server_ip = MCAST_ADDRESS;
+  protocols = gst_rtsp_media_get_protocols (media);
+  if (protocols & GST_RTSP_LOWER_TRANS_UDP_MCAST)
+    info.server_ip = gst_rtsp_media_get_multicast_group (media);
   else
-    info.server_ip = client->server_ip;
+    info.server_ip = g_strdup (client->server_ip);
 
   /* create an SDP for the media object */
   if (!gst_rtsp_sdp_from_media (sdp, &info, media))
     goto no_sdp;
 
+  g_free (info.server_ip);
+
   return sdp;
 
   /* ERRORS */
 no_sdp:
   {
+    g_free (info.server_ip);
     gst_sdp_message_free (sdp);
     return NULL;
   }
@@ -1069,10 +1098,8 @@ no_sdp:
 
 /* for the describe we must generate an SDP */
 static gboolean
-handle_describe_request (GstRTSPClient * client, GstRTSPUrl * uri,
-    GstRTSPSession * session, GstRTSPMessage * request)
+handle_describe_request (GstRTSPClient * client, GstRTSPClientState * state)
 {
-  GstRTSPMessage response = { 0 };
   GstRTSPResult res;
   GstSDPMessage *sdp;
   guint i, str_len;
@@ -1085,7 +1112,8 @@ handle_describe_request (GstRTSPClient * client, GstRTSPUrl * uri,
     gchar *accept;
 
     res =
-        gst_rtsp_message_get_header (request, GST_RTSP_HDR_ACCEPT, &accept, i);
+        gst_rtsp_message_get_header (state->request, GST_RTSP_HDR_ACCEPT,
+        &accept, i);
     if (res == GST_RTSP_ENOTIMPL)
       break;
 
@@ -1094,7 +1122,7 @@ handle_describe_request (GstRTSPClient * client, GstRTSPUrl * uri,
   }
 
   /* find the media object for the uri */
-  if (!(media = find_media (client, uri, request)))
+  if (!(media = find_media (client, state)))
     goto no_media;
 
   /* create an SDP for the media object on this client */
@@ -1103,14 +1131,14 @@ handle_describe_request (GstRTSPClient * client, GstRTSPUrl * uri,
 
   g_object_unref (media);
 
-  gst_rtsp_message_init_response (&response, GST_RTSP_STS_OK,
-      gst_rtsp_status_as_text (GST_RTSP_STS_OK), request);
+  gst_rtsp_message_init_response (state->response, GST_RTSP_STS_OK,
+      gst_rtsp_status_as_text (GST_RTSP_STS_OK), state->request);
 
-  gst_rtsp_message_add_header (&response, GST_RTSP_HDR_CONTENT_TYPE,
+  gst_rtsp_message_add_header (state->response, GST_RTSP_HDR_CONTENT_TYPE,
       "application/sdp");
 
   /* content base for some clients that might screw up creating the setup uri */
-  str = gst_rtsp_url_get_request_uri (uri);
+  str = gst_rtsp_url_get_request_uri (state->uri);
   str_len = strlen (str);
 
   /* check for trailing '/' and append one */
@@ -1126,16 +1154,16 @@ handle_describe_request (GstRTSPClient * client, GstRTSPUrl * uri,
 
   GST_INFO ("adding content-base: %s", content_base);
 
-  gst_rtsp_message_add_header (&response, GST_RTSP_HDR_CONTENT_BASE,
+  gst_rtsp_message_add_header (state->response, GST_RTSP_HDR_CONTENT_BASE,
       content_base);
   g_free (content_base);
 
   /* add SDP to the response body */
   str = gst_sdp_message_as_text (sdp);
-  gst_rtsp_message_take_body (&response, (guint8 *) str, strlen (str));
+  gst_rtsp_message_take_body (state->response, (guint8 *) str, strlen (str));
   gst_sdp_message_free (sdp);
 
-  send_response (client, session, &response);
+  send_response (client, state->session, state->response);
 
   return TRUE;
 
@@ -1147,17 +1175,15 @@ no_media:
   }
 no_sdp:
   {
-    send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, request);
+    send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
     g_object_unref (media);
     return FALSE;
   }
 }
 
 static gboolean
-handle_options_request (GstRTSPClient * client, GstRTSPUrl * uri,
-    GstRTSPSession * session, GstRTSPMessage * request)
+handle_options_request (GstRTSPClient * client, GstRTSPClientState * state)
 {
-  GstRTSPMessage response = { 0 };
   GstRTSPMethod options;
   gchar *str;
 
@@ -1170,13 +1196,13 @@ handle_options_request (GstRTSPClient * client, GstRTSPUrl * uri,
 
   str = gst_rtsp_options_as_text (options);
 
-  gst_rtsp_message_init_response (&response, GST_RTSP_STS_OK,
-      gst_rtsp_status_as_text (GST_RTSP_STS_OK), request);
+  gst_rtsp_message_init_response (state->response, GST_RTSP_STS_OK,
+      gst_rtsp_status_as_text (GST_RTSP_STS_OK), state->request);
 
-  gst_rtsp_message_add_header (&response, GST_RTSP_HDR_PUBLIC, str);
+  gst_rtsp_message_add_header (state->response, GST_RTSP_HDR_PUBLIC, str);
   g_free (str);
 
-  send_response (client, session, &response);
+  send_response (client, state->session, state->response);
 
   return TRUE;
 }
@@ -1253,8 +1279,13 @@ handle_request (GstRTSPClient * client, GstRTSPMessage * request)
   GstRTSPVersion version;
   GstRTSPResult res;
   GstRTSPSession *session;
+  GstRTSPClientState state = { NULL };
+  GstRTSPMessage response = { 0 };
   gchar *sessid;
 
+  state.request = request;
+  state.response = &response;
+
   if (gst_debug_category_get_threshold (rtsp_client_debug) >= GST_LEVEL_LOG) {
     gst_rtsp_message_dump (request);
   }
@@ -1266,18 +1297,20 @@ handle_request (GstRTSPClient * client, GstRTSPMessage * request)
   if (version != GST_RTSP_VERSION_1_0) {
     /* we can only handle 1.0 requests */
     send_generic_response (client, GST_RTSP_STS_RTSP_VERSION_NOT_SUPPORTED,
-        request);
+        &state);
     return;
   }
+  state.method = method;
 
   /* we always try to parse the url first */
   if (gst_rtsp_url_parse (uristr, &uri) != GST_RTSP_OK) {
-    send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, request);
+    send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, &state);
     return;
   }
 
   /* sanitize the uri */
   sanitize_uri (uri);
+  state.uri = uri;
 
   /* get the session if there is any */
   res = gst_rtsp_message_get_header (request, GST_RTSP_HDR_SESSION, &sessid, 0);
@@ -1296,46 +1329,47 @@ handle_request (GstRTSPClient * client, GstRTSPMessage * request)
   } else
     session = NULL;
 
+  state.session = session;
+
   if (client->auth) {
-    if (!gst_rtsp_auth_check_method (client->auth, method, client, uri, session,
-            request))
+    if (!gst_rtsp_auth_check (client->auth, client, 0, &state))
       goto not_authorized;
   }
 
   /* now see what is asked and dispatch to a dedicated handler */
   switch (method) {
     case GST_RTSP_OPTIONS:
-      handle_options_request (client, uri, session, request);
+      handle_options_request (client, &state);
       break;
     case GST_RTSP_DESCRIBE:
-      handle_describe_request (client, uri, session, request);
+      handle_describe_request (client, &state);
       break;
     case GST_RTSP_SETUP:
-      handle_setup_request (client, uri, session, request);
+      handle_setup_request (client, &state);
       break;
     case GST_RTSP_PLAY:
-      handle_play_request (client, uri, session, request);
+      handle_play_request (client, &state);
       break;
     case GST_RTSP_PAUSE:
-      handle_pause_request (client, uri, session, request);
+      handle_pause_request (client, &state);
       break;
     case GST_RTSP_TEARDOWN:
-      handle_teardown_request (client, uri, session, request);
+      handle_teardown_request (client, &state);
       break;
     case GST_RTSP_SET_PARAMETER:
-      handle_set_param_request (client, uri, session, request);
+      handle_set_param_request (client, &state);
       break;
     case GST_RTSP_GET_PARAMETER:
-      handle_get_param_request (client, uri, session, request);
+      handle_get_param_request (client, &state);
       break;
     case GST_RTSP_ANNOUNCE:
     case GST_RTSP_RECORD:
     case GST_RTSP_REDIRECT:
-      send_generic_response (client, GST_RTSP_STS_NOT_IMPLEMENTED, request);
+      send_generic_response (client, GST_RTSP_STS_NOT_IMPLEMENTED, &state);
       break;
     case GST_RTSP_INVALID:
     default:
-      send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, request);
+      send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, &state);
       break;
   }
   if (session)
@@ -1347,17 +1381,17 @@ handle_request (GstRTSPClient * client, GstRTSPMessage * request)
   /* ERRORS */
 no_pool:
   {
-    send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, request);
+    send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, &state);
     return;
   }
 session_not_found:
   {
-    send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, request);
+    send_generic_response (client, GST_RTSP_STS_SESSION_NOT_FOUND, &state);
     return;
   }
 not_authorized:
   {
-    handle_unauthorized_request (client, uri, session, request);
+    handle_unauthorized_request (client, client->auth, &state);
     return;
   }
 }
@@ -1380,10 +1414,7 @@ handle_data (GstRTSPClient * client, GstRTSPMessage * message)
 
   gst_rtsp_message_steal_body (message, &data, &size);
 
-  buffer = gst_buffer_new ();
-  GST_BUFFER_DATA (buffer) = data;
-  GST_BUFFER_MALLOCDATA (buffer) = data;
-  GST_BUFFER_SIZE (buffer) = size;
+  buffer = gst_buffer_new_wrapped (data, size);
 
   handled = FALSE;
   for (walk = client->streams; walk; walk = g_list_next (walk)) {
@@ -1462,6 +1493,47 @@ gst_rtsp_client_get_session_pool (GstRTSPClient * client)
 }
 
 /**
+ * gst_rtsp_client_set_server:
+ * @client: a #GstRTSPClient
+ * @server: a #GstRTSPServer
+ *
+ * Set @server as the server that created @client.
+ */
+void
+gst_rtsp_client_set_server (GstRTSPClient * client, GstRTSPServer * server)
+{
+  GstRTSPServer *old;
+
+  old = client->server;
+  if (old != server) {
+    if (server)
+      g_object_ref (server);
+    client->server = server;
+    if (old)
+      g_object_unref (old);
+  }
+}
+
+/**
+ * gst_rtsp_client_get_server:
+ * @client: a #GstRTSPClient
+ *
+ * Get the #GstRTSPServer object that @client was created from.
+ *
+ * Returns: a #GstRTSPServer, unref after usage.
+ */
+GstRTSPServer *
+gst_rtsp_client_get_server (GstRTSPClient * client)
+{
+  GstRTSPServer *result;
+
+  if ((result = client->server))
+    g_object_ref (result);
+
+  return result;
+}
+
+/**
  * gst_rtsp_client_set_media_mapping:
  * @client: a #GstRTSPClient
  * @mapping: a #GstRTSPMediaMapping
@@ -1578,9 +1650,9 @@ message_received (GstRTSPWatch * watch, GstRTSPMessage * message,
 static GstRTSPResult
 message_sent (GstRTSPWatch * watch, guint cseq, gpointer user_data)
 {
-  GstRTSPClient *client;
+  /* GstRTSPClient *client; */
 
-  client = GST_RTSP_CLIENT (user_data);
+  /* client = GST_RTSP_CLIENT (user_data); */
 
   /* GST_INFO ("client %p: sent a message with cseq %d", client, cseq); */
 
@@ -1596,10 +1668,10 @@ closed (GstRTSPWatch * watch, gpointer user_data)
   GST_INFO ("client %p: connection closed", client);
 
   if ((tunnelid = gst_rtsp_connection_get_tunnelid (client->connection))) {
-    g_mutex_lock (tunnels_lock);
+    g_mutex_lock (&tunnels_lock);
     /* remove from tunnelids */
     g_hash_table_remove (tunnels, tunnelid);
-    g_mutex_unlock (tunnels_lock);
+    g_mutex_unlock (&tunnels_lock);
   }
 
   return GST_RTSP_OK;
@@ -1647,12 +1719,12 @@ remember_tunnel (GstRTSPClient * client)
   GST_INFO ("client %p: inserting tunnel session %s", client, tunnelid);
 
   /* we can't have two clients connecting with the same tunnelid */
-  g_mutex_lock (tunnels_lock);
+  g_mutex_lock (&tunnels_lock);
   if (g_hash_table_lookup (tunnels, tunnelid))
     goto tunnel_existed;
 
   g_hash_table_insert (tunnels, g_strdup (tunnelid), g_object_ref (client));
-  g_mutex_unlock (tunnels_lock);
+  g_mutex_unlock (&tunnels_lock);
 
   return TRUE;
 
@@ -1664,7 +1736,7 @@ no_tunnelid:
   }
 tunnel_existed:
   {
-    g_mutex_unlock (tunnels_lock);
+    g_mutex_unlock (&tunnels_lock);
     GST_ERROR ("client %p: tunnel session %s already existed", client,
         tunnelid);
     return FALSE;
@@ -1724,7 +1796,7 @@ tunnel_complete (GstRTSPWatch * watch, gpointer user_data)
   if (tunnelid == NULL)
     goto no_tunnelid;
 
-  g_mutex_lock (tunnels_lock);
+  g_mutex_lock (&tunnels_lock);
   if (!(oclient = g_hash_table_lookup (tunnels, tunnelid)))
     goto no_tunnel;
 
@@ -1735,7 +1807,7 @@ tunnel_complete (GstRTSPWatch * watch, gpointer user_data)
 
   if (oclient->watch == NULL)
     goto tunnel_closed;
-  g_mutex_unlock (tunnels_lock);
+  g_mutex_unlock (&tunnels_lock);
 
   GST_INFO ("client %p: found tunnel %p (old %p, new %p)", client, oclient,
       oclient->connection, client->connection);
@@ -1756,20 +1828,20 @@ tunnel_complete (GstRTSPWatch * watch, gpointer user_data)
 no_tunnelid:
   {
     GST_INFO ("client %p: no tunnelid provided", client);
-    return GST_RTSP_STS_SERVICE_UNAVAILABLE;
+    return GST_RTSP_ERROR;
   }
 no_tunnel:
   {
-    g_mutex_unlock (tunnels_lock);
+    g_mutex_unlock (&tunnels_lock);
     GST_INFO ("client %p: tunnel session %s not found", client, tunnelid);
-    return GST_RTSP_STS_SERVICE_UNAVAILABLE;
+    return GST_RTSP_ERROR;
   }
 tunnel_closed:
   {
-    g_mutex_unlock (tunnels_lock);
+    g_mutex_unlock (&tunnels_lock);
     GST_INFO ("client %p: tunnel session %s was closed", client, tunnelid);
     g_object_unref (oclient);
-    return GST_RTSP_STS_SERVICE_UNAVAILABLE;
+    return GST_RTSP_ERROR;
   }
 }
 
@@ -1790,15 +1862,18 @@ client_watch_notify (GstRTSPClient * client)
   GST_INFO ("client %p: watch destroyed", client);
   client->watchid = 0;
   client->watch = NULL;
+  g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_CLOSED], 0, NULL);
   g_object_unref (client);
 }
 
 /**
  * gst_rtsp_client_attach:
  * @client: a #GstRTSPClient
- * @channel: a #GIOChannel
+ * @socket: a #GSocket
+ * @cancellable: a #GCancellable
+ * @error: a #GError
  *
- * Accept a new connection for @client on the socket in @channel. 
+ * Accept a new connection for @client on @socket.
  *
  * This function should be called when the client properties and urls are fully
  * configured and the client is ready to start.
@@ -1806,11 +1881,13 @@ client_watch_notify (GstRTSPClient * client)
  * Returns: %TRUE if the client could be accepted.
  */
 gboolean
-gst_rtsp_client_accept (GstRTSPClient * client, GIOChannel * channel)
+gst_rtsp_client_accept (GstRTSPClient * client, GSocket * socket,
+    GCancellable * cancellable, GError ** error)
 {
-  int sock, fd;
   GstRTSPConnection *conn;
   GstRTSPResult res;
+  GSocket *read_socket;
+  GSocketAddress *addres;
   GSource *source;
   GMainContext *context;
   GstRTSPUrl *url;
@@ -1819,17 +1896,19 @@ gst_rtsp_client_accept (GstRTSPClient * client, GIOChannel * channel)
   gchar ip[INET6_ADDRSTRLEN];
 
   /* a new client connected. */
-  sock = g_io_channel_unix_get_fd (channel);
+  GST_RTSP_CHECK (gst_rtsp_connection_accept (socket, &conn, cancellable),
+      accept_failed);
 
-  GST_RTSP_CHECK (gst_rtsp_connection_accept (sock, &conn), accept_failed);
+  read_socket = gst_rtsp_connection_get_read_socket (conn);
+  client->is_ipv6 = g_socket_get_family (socket) == G_SOCKET_FAMILY_IPV6;
 
-  fd = gst_rtsp_connection_get_readfd (conn);
+  if (!(addres = g_socket_get_remote_address (read_socket, error)))
+    goto no_address;
 
   addrlen = sizeof (addr);
-  if (getsockname (fd, (struct sockaddr *) &addr, &addrlen) < 0)
-    goto getpeername_failed;
-
-  client->is_ipv6 = addr.ss_family == AF_INET6;
+  if (!g_socket_address_to_native (addres, &addr, addrlen, error))
+    goto native_failed;
+  g_object_unref (addres);
 
   if (getnameinfo ((struct sockaddr *) &addr, addrlen, ip, sizeof (ip), NULL, 0,
           NI_NUMERICHOST) != 0)
@@ -1869,13 +1948,19 @@ accept_failed:
   {
     gchar *str = gst_rtsp_strresult (res);
 
-    GST_ERROR ("Could not accept client on server socket %d: %s", sock, str);
+    GST_ERROR ("Could not accept client on server socket %p: %s", socket, str);
     g_free (str);
     return FALSE;
   }
-getpeername_failed:
+no_address:
+  {
+    GST_ERROR ("could not get remote address %s", (*error)->message);
+    return FALSE;
+  }
+native_failed:
   {
-    GST_ERROR ("getpeername failed: %s", g_strerror (errno));
+    g_object_unref (addres);
+    GST_ERROR ("could not get native address %s", (*error)->message);
     return FALSE;
   }
 getnameinfo_failed: