Fix: relayd: send_viewer_streams sends stack data in padding
[lttng-tools.git] / src / bin / lttng-relayd / live.c
index 6c1dbcd36763f5c7309ab4e5b08d12c1fd528860..75c0227079d714f0230016af4e3c1cd72c240f17 100644 (file)
@@ -200,7 +200,6 @@ ssize_t send_viewer_streams(struct lttcomm_sock *sock,
                uint64_t session_id, unsigned int ignore_sent_flag)
 {
        ssize_t ret;
-       struct lttng_viewer_stream send_stream;
        struct lttng_ht_iter iter;
        struct relay_viewer_stream *vstream;
 
@@ -209,6 +208,7 @@ ssize_t send_viewer_streams(struct lttcomm_sock *sock,
        cds_lfht_for_each_entry(viewer_streams_ht->ht, &iter.iter, vstream,
                        stream_n.node) {
                struct ctf_trace *ctf_trace;
+               struct lttng_viewer_stream send_stream = {};
 
                health_code_update();
 
@@ -338,7 +338,8 @@ static int make_viewer_streams(struct relay_session *session,
                 */
                if (!trace_has_metadata_stream &&
                                !ctf_trace->metadata_stream_sent_to_viewer) {
-                       break;
+                       ctf_trace_put(ctf_trace);
+                       continue;
                }
 
                cds_list_for_each_entry_rcu(stream, &ctf_trace->stream_list, stream_node) {
@@ -1723,7 +1724,23 @@ int viewer_get_metadata(struct relay_connection *conn)
 
        len = vstream->stream->metadata_received - vstream->metadata_sent;
        if (len == 0) {
+               /*
+                * The live viewers expect to receive a NO_NEW_METADATA
+                * status before a stream disappears, otherwise they abort the
+                * entire live connection when receiving an error status.
+                */
                reply.status = htobe32(LTTNG_VIEWER_NO_NEW_METADATA);
+               /*
+                * The live viewer considers a closed 0 byte metadata stream as
+                * an error.
+                */
+               if (vstream->metadata_sent > 0) {
+                       vstream->stream->no_new_metadata_notified = true;
+                       if (vstream->stream->closed) {
+                               /* Release ownership for the viewer metadata stream. */
+                               viewer_stream_put(vstream);
+                       }
+               }
                goto send_reply;
        }
 
@@ -1771,12 +1788,6 @@ int viewer_get_metadata(struct relay_connection *conn)
                goto error;
        }
        vstream->metadata_sent += read_len;
-       if (vstream->metadata_sent == vstream->stream->metadata_received
-                       && vstream->stream->closed) {
-               /* Release ownership for the viewer metadata stream. */
-               viewer_stream_put(vstream);
-       }
-
        reply.status = htobe32(LTTNG_VIEWER_METADATA_OK);
 
        goto send_reply;
This page took 0.024738 seconds and 4 git commands to generate.