Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SrsRtcTcpConn::read_packet should use read_fully instead of read #3842

Closed
sandro-qiang opened this issue Oct 18, 2023 · 5 comments · Fixed by #3847
Closed

SrsRtcTcpConn::read_packet should use read_fully instead of read #3842

sandro-qiang opened this issue Oct 18, 2023 · 5 comments · Fixed by #3847
Labels
EnglishNative This issue is conveyed exclusively in English. good first issue Easy to fix issues, good for newcomers help wanted Extra attention is needed

Comments

@sandro-qiang
Copy link

Describe the bug
read_packet use skt_->read to read packet length, not skt_->read_fully. for client not using tcp_no_delay option, this may lead to read wrong packet length.

Version
5 and 6

@winlinvip winlinvip added the EnglishNative This issue is conveyed exclusively in English. label Oct 18, 2023
@winlinvip
Copy link
Member

winlinvip commented Oct 18, 2023

This is indeed an error. Can you submit a PR (Pull Request)?

TRANS_BY_GPT4

@sandro-qiang
Copy link
Author

I'm a bit busy now, can you just fix this? only a single line.

@winlinvip winlinvip added good first issue Easy to fix issues, good for newcomers help wanted Extra attention is needed labels Oct 19, 2023
@winlinvip winlinvip changed the title bug in SrsRtcTcpConn::read_packet SrsRtcTcpConn::read_packet should use read_fully instead of read Oct 19, 2023
@chundonglinlin
Copy link
Member

chundonglinlin commented Oct 19, 2023

I've made some changes, please review, @sandro-qiang. Could you explain how to test the client (can you provide a client demo that does not use the tcp_no_delay option for streaming webrtc over tcp)? I've only done a simple test on the web player.

srs_error_t SrsRtcTcpConn::read_packet(char* pkt, int* nb_pkt)
{
    srs_error_t err = srs_success;

    // Read length in 2 bytes @doc: https://www.rfc-editor.org/rfc/rfc4571#section-2
    ssize_t nread = 0; uint8_t b[2];
    if((err = skt_->read((char*)b, sizeof(b), &nread)) != srs_success) {
        return srs_error_wrap(err, "rtc tcp conn read len");
    }

    uint16_t npkt = uint16_t(b[0])<<8 | uint16_t(b[1]);
    if (npkt > *nb_pkt) {
        return srs_error_new(ERROR_RTC_TCP_SIZE, "invalid size=%u exceed %d", npkt, *nb_pkt);
    }

    // Read a RTC pkt such as STUN, DTLS or RTP/RTCP
    if((err = skt_->read(pkt, npkt, &nread)) != srs_success) {
        return srs_error_wrap(err, "rtc tcp conn read body");
    }

    *nb_pkt = npkt;

    return err;
}

TRANS_BY_GPT4

@winlinvip
Copy link
Member

winlinvip commented Oct 19, 2023

Please submit a PR (Pull Request) directly, and let's discuss it on the PR.

TRANS_BY_GPT4

@sandro-qiang
Copy link
Author

sandro-qiang commented Oct 19, 2023

I've made some changes, please review, @sandro-qiang. Could you explain how to test the client (can you provide a client demo that does not use the tcp_no_delay option for streaming webrtc over tcp)? I've only done a simple test on the web player.

srs_error_t SrsRtcTcpConn::read_packet(char* pkt, int* nb_pkt)
{
    srs_error_t err = srs_success;

    // Read length in 2 bytes @doc: https://www.rfc-editor.org/rfc/rfc4571#section-2
    ssize_t nread = 0; uint8_t b[2];
    if((err = skt_->read((char*)b, sizeof(b), &nread)) != srs_success) {
        return srs_error_wrap(err, "rtc tcp conn read len");
    }

    uint16_t npkt = uint16_t(b[0])<<8 | uint16_t(b[1]);
    if (npkt > *nb_pkt) {
        return srs_error_new(ERROR_RTC_TCP_SIZE, "invalid size=%u exceed %d", npkt, *nb_pkt);
    }

    // Read a RTC pkt such as STUN, DTLS or RTP/RTCP
    if((err = skt_->read(pkt, npkt, &nread)) != srs_success) {
        return srs_error_wrap(err, "rtc tcp conn read body");
    }

    *nb_pkt = npkt;

    return err;
}

TRANS_BY_GPT4

Full demo involve a lot of logic, connect -> stun binding -> dtls handshake -> rtp/rtcp. Base on srs source code, the simplest demo I can see is make a client program only do connect -> stun, but make sure stun is not a binding request, so srs will ignore this packet. Make the dummy stun packet size vary(body has random chunks). The default create_socket function has no tcp_no_delay option on, so any tcp connect code can use(I found this bug using boost::asio, the boost::asio::async_connect function).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
EnglishNative This issue is conveyed exclusively in English. good first issue Easy to fix issues, good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants