Skip to content

Fix RTSP server crash on TCP transport connect#602

Open
Copilot wants to merge 4 commits intomainfrom
copilot/fix-rtsp-stream-crash-tcp
Open

Fix RTSP server crash on TCP transport connect#602
Copilot wants to merge 4 commits intomainfrom
copilot/fix-rtsp-stream-crash-tcp

Conversation

Copy link
Contributor

Copilot AI commented Feb 19, 2026

RTSP server becomes permanently unresponsive after a client connects requesting TCP interleaved transport (e.g., Home Assistant). No subsequent clients can connect until reboot.

Changes

  • Fix data race on sessions_ mapaccept_task_function was mutating sessions_ without holding session_mutex_, while session_task_function iterates/erases under that same mutex on a different thread. Added lock guard around the emplace.

  • Teardown session on failed SETUP — After rejecting TCP transport with 461, the session was left alive (closed_=false, session_active_=false) as a zombie. Now calls teardown() so session_task_function cleans it up on the next iteration.

  • Include CSeq in 461 response — The "Unsupported Transport" response was missing the CSeq header, violating RTSP protocol.

// rtsp_server.cpp — accept_task_function
{
  std::lock_guard<std::mutex> lk(session_mutex_);
  sessions_.emplace(session_id, std::move(session));
}

// rtsp_session.cpp — handle_rtsp_setup
if (!parse_rtsp_setup_request(request, rtsp_path, client_rtp_port, client_rtcp_port)) {
  teardown();
  return false;
}

// rtsp_session.cpp — parse_rtsp_setup_request (TCP rejection)
int sequence_number = 0;
parse_rtsp_command_sequence(request, sequence_number);
send_response(461, "Unsupported Transport", sequence_number);
Original prompt

This section details on the original issue you should resolve

<issue_title>RTSP stream crashes on TCP connect</issue_title>
<issue_description>### Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

What is the expected behavior?

v 1.0.34
I know TCP is not supported, but as soon as the client forces this anyway no other clients can connect until reboot.
tried to fix myself without any luck.
So if TCP is not supported at least it should not make the system unworkable.

What is the actual behavior?

That after 1 client uses tcp others are still able to connect.

Steps to reproduce.

use rtsp in a project

    espp::RtspServer::Config rtsp_cfg;
    rtsp_cfg.port = 8554;

    espp::RtspServer server{rtsp_cfg};
    vTaskDelay(1000 / portTICK_PERIOD_MS); // 1 second
    server.start();

and a simple for loop

 while (true)
    {
        camera_fb_t *fb = esp_camera_fb_get();
        if (!fb)
            continue;
       // --- RTSP send ---
        std::span<const uint8_t> jpeg_span(fb->buf, fb->len);
        server.send_frame(espp::JpegFrame(jpeg_span));
      esp_camera_fb_return(fb);
   }

connect with home assistant like this

type: custom:webrtc-camera
streams:
  - url: rtsp://192.168.170.31:8554/stream

Build or installation Logs.


More Information.

No response</issue_description>

<agent_instructions>Please look through the rtsp component code as well as the socket component code and make any additional bufixes necessary.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@finger563 @bkbartk thanks for reporting this! Can you please enable logging on the rtsp server and provide the logs so I can see what the server is doing in this state?

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 3 commits February 19, 2026 15:07
Three fixes:
1. Fix race condition on sessions_ map - accept_task_function now
   locks session_mutex_ when modifying sessions_, matching the
   locking in session_task_function that iterates/erases sessions.
2. Teardown session after failed SETUP - when TCP transport is
   rejected (or any SETUP parse failure), the session is properly
   torn down so it gets cleaned up instead of remaining as a zombie.
3. Include CSeq in 461 response - the "Unsupported Transport"
   response now includes the sequence number per RTSP protocol.

Co-authored-by: finger563 <213467+finger563@users.noreply.github.com>
Co-authored-by: finger563 <213467+finger563@users.noreply.github.com>
Co-authored-by: finger563 <213467+finger563@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix RTSP stream crash on TCP connection Fix RTSP server crash on TCP transport connect Feb 19, 2026
Copilot AI requested a review from finger563 February 19, 2026 15:10
@github-actions
Copy link

✅Static analysis result - no issues found! ✅

@finger563 finger563 marked this pull request as ready for review February 19, 2026 15:32
Copilot AI review requested due to automatic review settings February 19, 2026 15:32
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a critical crash in the RTSP server that occurs when clients request TCP transport (e.g., Home Assistant connections). The server was becoming permanently unresponsive due to a race condition and zombie sessions.

Changes:

  • Fixed data race on sessions_ map by adding mutex protection during session insertion
  • Added session teardown on failed SETUP requests to prevent zombie sessions
  • Fixed RTSP protocol violation by including CSeq header in 461 "Unsupported Transport" responses

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
components/rtsp/src/rtsp_server.cpp Added mutex lock guard around sessions_.emplace() to fix race condition between accept_task and session_task threads
components/rtsp/src/rtsp_session.cpp Added teardown() call on SETUP failure and included CSeq in TCP transport rejection response

Comment on lines +155 to +156
// the parse function will send the response, so we just need to
// teardown the session since setup failed and streaming cannot proceed
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment states "the parse function will send the response," but parse_rtsp_setup_request only sends a response for the TCP transport rejection case (line 385). Other parse failures (empty rtsp_path at line 361-362, missing/malformed Transport header at lines 367-377, or malformed client_port at lines 394-401) return false without sending any error response to the client, which violates RTSP protocol requirements. Consider sending an appropriate error response (e.g., 400 Bad Request with CSeq) for all parse failure cases before calling teardown(), or update the comment to clarify that only the TCP rejection sends a response.

Suggested change
// the parse function will send the response, so we just need to
// teardown the session since setup failed and streaming cannot proceed
// the request could not be parsed; send an error response and teardown
handle_rtsp_invalid_request(request);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RTSP stream crashes on TCP connect

2 participants

Comments