Skip to content

Commit

Permalink
RTC: Parse PT fast and refine udp handler. 4.0.69
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Feb 10, 2021
1 parent 826546d commit 79a6907
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 35 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ For previous versions, please read:

## V4 changes

* v4.0, 2021-02-07, RTC: Parse PT fast and refine udp handler. 4.0.69
* v4.0, 2021-02-05, RTC: Refine UDP packet peer fast id. 4.0.68
* v4.0, 2021-02-04, RTC: Reuse UDP socket to receive packet. 4.0.67
* v4.0, 2021-02-04, At least wait 1ms when <1ms, to avoid epoll_wait spin loop. 4.0.66
Expand Down
12 changes: 12 additions & 0 deletions trunk/src/app/srs_app_listener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ using namespace std;
#include <srs_app_server.hpp>
#include <srs_app_utility.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_kernel_buffer.hpp>

// set the max packet size.
#define SRS_UDP_MAX_PACKET_SIZE 65535
Expand Down Expand Up @@ -295,18 +296,24 @@ SrsUdpMuxSocket::SrsUdpMuxSocket(srs_netfd_t fd)
peer_port = 0;

fast_id_ = 0;
cache_buffer_ = new SrsBuffer(buf, nb_buf);
}

SrsUdpMuxSocket::~SrsUdpMuxSocket()
{
srs_freepa(buf);
srs_freep(cache_buffer_);
}

int SrsUdpMuxSocket::recvfrom(srs_utime_t timeout)
{
fromlen = sizeof(from);
nread = srs_recvfrom(lfd, buf, nb_buf, (sockaddr*)&from, &fromlen, timeout);

// Reset the fast cache buffer size.
cache_buffer_->set_size(nread);
cache_buffer_->skip(-1 * cache_buffer_->pos());

// Drop UDP health check packet of Aliyun SLB.
// Healthcheck udp check
// @see https://help.aliyun.com/document_detail/27595.html
Expand Down Expand Up @@ -420,6 +427,11 @@ uint64_t SrsUdpMuxSocket::fast_id()
return fast_id_;
}

SrsBuffer* SrsUdpMuxSocket::buffer()
{
return cache_buffer_;
}

SrsUdpMuxSocket* SrsUdpMuxSocket::copy_sendonly()
{
SrsUdpMuxSocket* sendonly = new SrsUdpMuxSocket(lfd);
Expand Down
3 changes: 3 additions & 0 deletions trunk/src/app/srs_app_listener.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

struct sockaddr;

class SrsBuffer;
class SrsUdpMuxSocket;

// The udp packet handler.
Expand Down Expand Up @@ -138,6 +139,7 @@ class SrsUdpMuxSocket
{
private:
std::map<uint32_t, std::string> cache_;
SrsBuffer* cache_buffer_;
private:
char* buf;
int nb_buf;
Expand Down Expand Up @@ -168,6 +170,7 @@ class SrsUdpMuxSocket
int get_peer_port() const;
std::string peer_id();
uint64_t fast_id();
SrsBuffer* buffer();
SrsUdpMuxSocket* copy_sendonly();
};

Expand Down
29 changes: 15 additions & 14 deletions trunk/src/app/srs_app_rtc_conn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1122,8 +1122,16 @@ srs_error_t SrsRtcPublishStream::on_rtp(char* data, int nb_data)
return err;
}

// If payload type is configed to drop, ignore this packet.
if (pt_to_drop_) {
uint8_t pt = srs_rtp_fast_parse_pt(data, nb_data);
if (pt_to_drop_ == pt) {
return err;
}
}

// Decode the header first.
if (pt_to_drop_ || twcc_id_) {
if (twcc_id_) {
SrsRtpHeader h;
SrsBuffer b(data, nb_data);
h.ignore_padding(true); h.set_extensions(&extension_types_);
Expand All @@ -1135,20 +1143,13 @@ srs_error_t SrsRtcPublishStream::on_rtp(char* data, int nb_data)
// 1. Client may send some padding packets with invalid SequenceNumber, which causes the SRTP fail.
// 2. Server may send multiple duplicated NACK to client, and got more than one ARQ packet, which also fail SRTP.
// so, we must parse the header before SRTP unprotect(which may fail and drop packet).
if (twcc_id_) {
uint16_t twcc_sn = 0;
if ((err = h.get_twcc_sequence_number(twcc_sn)) == srs_success) {
if((err = on_twcc(twcc_sn)) != srs_success) {
return srs_error_wrap(err, "on twcc");
}
} else {
srs_error_reset(err);
uint16_t twcc_sn = 0;
if ((err = h.get_twcc_sequence_number(twcc_sn)) == srs_success) {
if((err = on_twcc(twcc_sn)) != srs_success) {
return srs_error_wrap(err, "on twcc");
}
}

// If payload type is configed to drop, ignore this packet.
if (pt_to_drop_ && pt_to_drop_ == h.get_payload_type()) {
return err;
} else {
srs_error_reset(err);
}
}

Expand Down
14 changes: 8 additions & 6 deletions trunk/src/app/srs_app_rtc_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,8 @@ srs_error_t SrsRtcServer::on_udp_packet(SrsUdpMuxSocket* skt)

SrsRtcConnection* session = NULL;
char* data = skt->data(); int size = skt->size();
bool is_rtp_or_rtcp = srs_is_rtp_or_rtcp((uint8_t*)data, size);
bool is_rtcp = srs_is_rtcp((uint8_t*)data, size);

uint64_t fast_id = skt->fast_id();
// Try fast id first, if not found, search by long peer id.
Expand All @@ -322,7 +324,7 @@ srs_error_t SrsRtcServer::on_udp_packet(SrsUdpMuxSocket* skt)
}

// Notify hijack to handle the UDP packet.
if (hijacker) {
if (hijacker && is_rtp_or_rtcp && is_rtcp) {
bool consumed = false;
if ((err = hijacker->on_udp_packet(skt, session, &consumed)) != srs_success) {
return srs_error_wrap(err, "hijack consumed=%u", consumed);
Expand All @@ -334,7 +336,7 @@ srs_error_t SrsRtcServer::on_udp_packet(SrsUdpMuxSocket* skt)
}

// For STUN, the peer address may change.
if (srs_is_stun((uint8_t*)data, size)) {
if (!is_rtp_or_rtcp && srs_is_stun((uint8_t*)data, size)) {
string peer_id = skt->peer_id();

SrsStunPacket ping;
Expand Down Expand Up @@ -368,13 +370,13 @@ srs_error_t SrsRtcServer::on_udp_packet(SrsUdpMuxSocket* skt)
return srs_error_new(ERROR_RTC_STUN, "no session, peer_id=%s, fast=%" PRId64, peer_id.c_str(), fast_id);
}

if (srs_is_dtls((uint8_t*)data, size)) {
return session->on_dtls(data, size);
} else if (srs_is_rtp_or_rtcp((uint8_t*)data, size)) {
if (srs_is_rtcp((uint8_t*)data, size)) {
if (is_rtp_or_rtcp) {
if (is_rtcp) {
return session->on_rtcp(data, size);
}
return session->on_rtp(data, size);
} else if (srs_is_dtls((uint8_t*)data, size)) {
return session->on_dtls(data, size);
}

return srs_error_new(ERROR_RTC_UDP, "unknown packet");
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/core/srs_core_version4.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@
#ifndef SRS_CORE_VERSION4_HPP
#define SRS_CORE_VERSION4_HPP

#define SRS_VERSION4_REVISION 68
#define SRS_VERSION4_REVISION 69

#endif
35 changes: 21 additions & 14 deletions trunk/src/kernel/srs_kernel_rtc_rtp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,22 @@ using namespace std;
#include <srs_kernel_utility.hpp>
#include <srs_kernel_flv.hpp>

/* @see https://tools.ietf.org/html/rfc1889#section-5.1
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| contributing source (CSRC) identifiers |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
uint32_t srs_rtp_fast_parse_ssrc(char* buf, int size)
{
/* @see https://tools.ietf.org/html/rfc1889#section-5.1
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| contributing source (CSRC) identifiers |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
if (size < 12) {
return 0;
}
Expand All @@ -63,6 +63,13 @@ uint32_t srs_rtp_fast_parse_ssrc(char* buf, int size)
pp[0] = *p++;
return value;
}
uint8_t srs_rtp_fast_parse_pt(char* buf, int size)
{
if (size < 12) {
return 0;
}
return buf[1] & 0x7f;
}

// If value is newer than pre_value,return true; otherwise false
bool srs_seq_is_newer(uint16_t value, uint16_t pre_value)
Expand Down
1 change: 1 addition & 0 deletions trunk/src/kernel/srs_kernel_rtc_rtp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class SrsSharedPtrMessage;

// Fast parse the SSRC from RTP packet. Return 0 if invalid.
uint32_t srs_rtp_fast_parse_ssrc(char* buf, int size);
uint8_t srs_rtp_fast_parse_pt(char* buf, int size);

// The "distance" between two uint16 number, for example:
// distance(prev_value=3, value=5) === (int16_t)(uint16_t)((uint16_t)3-(uint16_t)5) === -2
Expand Down

0 comments on commit 79a6907

Please sign in to comment.