mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
RTC: Parse PT fast and refine udp handler. 4.0.69
This commit is contained in:
parent
668f8cbf6c
commit
d184b5662c
8 changed files with 62 additions and 35 deletions
|
@ -155,6 +155,7 @@ For previous versions, please read:
|
||||||
|
|
||||||
## V4 changes
|
## 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-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, 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
|
* v4.0, 2021-02-04, At least wait 1ms when <1ms, to avoid epoll_wait spin loop. 4.0.66
|
||||||
|
|
|
@ -41,6 +41,7 @@ using namespace std;
|
||||||
#include <srs_app_server.hpp>
|
#include <srs_app_server.hpp>
|
||||||
#include <srs_app_utility.hpp>
|
#include <srs_app_utility.hpp>
|
||||||
#include <srs_kernel_utility.hpp>
|
#include <srs_kernel_utility.hpp>
|
||||||
|
#include <srs_kernel_buffer.hpp>
|
||||||
|
|
||||||
// set the max packet size.
|
// set the max packet size.
|
||||||
#define SRS_UDP_MAX_PACKET_SIZE 65535
|
#define SRS_UDP_MAX_PACKET_SIZE 65535
|
||||||
|
@ -295,11 +296,13 @@ SrsUdpMuxSocket::SrsUdpMuxSocket(srs_netfd_t fd)
|
||||||
peer_port = 0;
|
peer_port = 0;
|
||||||
|
|
||||||
fast_id_ = 0;
|
fast_id_ = 0;
|
||||||
|
cache_buffer_ = new SrsBuffer(buf, nb_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsUdpMuxSocket::~SrsUdpMuxSocket()
|
SrsUdpMuxSocket::~SrsUdpMuxSocket()
|
||||||
{
|
{
|
||||||
srs_freepa(buf);
|
srs_freepa(buf);
|
||||||
|
srs_freep(cache_buffer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsUdpMuxSocket::recvfrom(srs_utime_t timeout)
|
int SrsUdpMuxSocket::recvfrom(srs_utime_t timeout)
|
||||||
|
@ -307,6 +310,10 @@ int SrsUdpMuxSocket::recvfrom(srs_utime_t timeout)
|
||||||
fromlen = sizeof(from);
|
fromlen = sizeof(from);
|
||||||
nread = srs_recvfrom(lfd, buf, nb_buf, (sockaddr*)&from, &fromlen, timeout);
|
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.
|
// Drop UDP health check packet of Aliyun SLB.
|
||||||
// Healthcheck udp check
|
// Healthcheck udp check
|
||||||
// @see https://help.aliyun.com/document_detail/27595.html
|
// @see https://help.aliyun.com/document_detail/27595.html
|
||||||
|
@ -420,6 +427,11 @@ uint64_t SrsUdpMuxSocket::fast_id()
|
||||||
return fast_id_;
|
return fast_id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsBuffer* SrsUdpMuxSocket::buffer()
|
||||||
|
{
|
||||||
|
return cache_buffer_;
|
||||||
|
}
|
||||||
|
|
||||||
SrsUdpMuxSocket* SrsUdpMuxSocket::copy_sendonly()
|
SrsUdpMuxSocket* SrsUdpMuxSocket::copy_sendonly()
|
||||||
{
|
{
|
||||||
SrsUdpMuxSocket* sendonly = new SrsUdpMuxSocket(lfd);
|
SrsUdpMuxSocket* sendonly = new SrsUdpMuxSocket(lfd);
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
struct sockaddr;
|
struct sockaddr;
|
||||||
|
|
||||||
|
class SrsBuffer;
|
||||||
class SrsUdpMuxSocket;
|
class SrsUdpMuxSocket;
|
||||||
|
|
||||||
// The udp packet handler.
|
// The udp packet handler.
|
||||||
|
@ -138,6 +139,7 @@ class SrsUdpMuxSocket
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::map<uint32_t, std::string> cache_;
|
std::map<uint32_t, std::string> cache_;
|
||||||
|
SrsBuffer* cache_buffer_;
|
||||||
private:
|
private:
|
||||||
char* buf;
|
char* buf;
|
||||||
int nb_buf;
|
int nb_buf;
|
||||||
|
@ -168,6 +170,7 @@ public:
|
||||||
int get_peer_port() const;
|
int get_peer_port() const;
|
||||||
std::string peer_id();
|
std::string peer_id();
|
||||||
uint64_t fast_id();
|
uint64_t fast_id();
|
||||||
|
SrsBuffer* buffer();
|
||||||
SrsUdpMuxSocket* copy_sendonly();
|
SrsUdpMuxSocket* copy_sendonly();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1122,8 +1122,16 @@ srs_error_t SrsRtcPublishStream::on_rtp(char* data, int nb_data)
|
||||||
return err;
|
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.
|
// Decode the header first.
|
||||||
if (pt_to_drop_ || twcc_id_) {
|
if (twcc_id_) {
|
||||||
SrsRtpHeader h;
|
SrsRtpHeader h;
|
||||||
SrsBuffer b(data, nb_data);
|
SrsBuffer b(data, nb_data);
|
||||||
h.ignore_padding(true); h.set_extensions(&extension_types_);
|
h.ignore_padding(true); h.set_extensions(&extension_types_);
|
||||||
|
@ -1135,7 +1143,6 @@ 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.
|
// 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.
|
// 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).
|
// so, we must parse the header before SRTP unprotect(which may fail and drop packet).
|
||||||
if (twcc_id_) {
|
|
||||||
uint16_t twcc_sn = 0;
|
uint16_t twcc_sn = 0;
|
||||||
if ((err = h.get_twcc_sequence_number(twcc_sn)) == srs_success) {
|
if ((err = h.get_twcc_sequence_number(twcc_sn)) == srs_success) {
|
||||||
if((err = on_twcc(twcc_sn)) != srs_success) {
|
if((err = on_twcc(twcc_sn)) != srs_success) {
|
||||||
|
@ -1146,12 +1153,6 @@ srs_error_t SrsRtcPublishStream::on_rtp(char* data, int nb_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If payload type is configed to drop, ignore this packet.
|
|
||||||
if (pt_to_drop_ && pt_to_drop_ == h.get_payload_type()) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decrypt the cipher to plaintext RTP data.
|
// Decrypt the cipher to plaintext RTP data.
|
||||||
int nb_unprotected_buf = nb_data;
|
int nb_unprotected_buf = nb_data;
|
||||||
char* unprotected_buf = new char[kRtpPacketSize];
|
char* unprotected_buf = new char[kRtpPacketSize];
|
||||||
|
|
|
@ -302,6 +302,8 @@ srs_error_t SrsRtcServer::on_udp_packet(SrsUdpMuxSocket* skt)
|
||||||
|
|
||||||
SrsRtcConnection* session = NULL;
|
SrsRtcConnection* session = NULL;
|
||||||
char* data = skt->data(); int size = skt->size();
|
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();
|
uint64_t fast_id = skt->fast_id();
|
||||||
// Try fast id first, if not found, search by long peer id.
|
// Try fast id first, if not found, search by long peer id.
|
||||||
|
@ -322,7 +324,7 @@ srs_error_t SrsRtcServer::on_udp_packet(SrsUdpMuxSocket* skt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify hijack to handle the UDP packet.
|
// Notify hijack to handle the UDP packet.
|
||||||
if (hijacker) {
|
if (hijacker && is_rtp_or_rtcp && is_rtcp) {
|
||||||
bool consumed = false;
|
bool consumed = false;
|
||||||
if ((err = hijacker->on_udp_packet(skt, session, &consumed)) != srs_success) {
|
if ((err = hijacker->on_udp_packet(skt, session, &consumed)) != srs_success) {
|
||||||
return srs_error_wrap(err, "hijack consumed=%u", consumed);
|
return srs_error_wrap(err, "hijack consumed=%u", consumed);
|
||||||
|
@ -334,7 +336,7 @@ srs_error_t SrsRtcServer::on_udp_packet(SrsUdpMuxSocket* skt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// For STUN, the peer address may change.
|
// 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();
|
string peer_id = skt->peer_id();
|
||||||
|
|
||||||
SrsStunPacket ping;
|
SrsStunPacket ping;
|
||||||
|
@ -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);
|
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)) {
|
if (is_rtp_or_rtcp) {
|
||||||
return session->on_dtls(data, size);
|
if (is_rtcp) {
|
||||||
} else if (srs_is_rtp_or_rtcp((uint8_t*)data, size)) {
|
|
||||||
if (srs_is_rtcp((uint8_t*)data, size)) {
|
|
||||||
return session->on_rtcp(data, size);
|
return session->on_rtcp(data, size);
|
||||||
}
|
}
|
||||||
return session->on_rtp(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");
|
return srs_error_new(ERROR_RTC_UDP, "unknown packet");
|
||||||
|
|
|
@ -24,6 +24,6 @@
|
||||||
#ifndef SRS_CORE_VERSION4_HPP
|
#ifndef SRS_CORE_VERSION4_HPP
|
||||||
#define SRS_CORE_VERSION4_HPP
|
#define SRS_CORE_VERSION4_HPP
|
||||||
|
|
||||||
#define SRS_VERSION4_REVISION 68
|
#define SRS_VERSION4_REVISION 69
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,9 +33,7 @@ using namespace std;
|
||||||
#include <srs_kernel_utility.hpp>
|
#include <srs_kernel_utility.hpp>
|
||||||
#include <srs_kernel_flv.hpp>
|
#include <srs_kernel_flv.hpp>
|
||||||
|
|
||||||
uint32_t srs_rtp_fast_parse_ssrc(char* buf, int size)
|
/* @see https://tools.ietf.org/html/rfc1889#section-5.1
|
||||||
{
|
|
||||||
/* @see https://tools.ietf.org/html/rfc1889#section-5.1
|
|
||||||
0 1 2 3
|
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
|
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
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
@ -48,7 +46,9 @@ uint32_t srs_rtp_fast_parse_ssrc(char* buf, int size)
|
||||||
| contributing source (CSRC) identifiers |
|
| contributing source (CSRC) identifiers |
|
||||||
| .... |
|
| .... |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
*/
|
*/
|
||||||
|
uint32_t srs_rtp_fast_parse_ssrc(char* buf, int size)
|
||||||
|
{
|
||||||
if (size < 12) {
|
if (size < 12) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,13 @@ uint32_t srs_rtp_fast_parse_ssrc(char* buf, int size)
|
||||||
pp[0] = *p++;
|
pp[0] = *p++;
|
||||||
return value;
|
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
|
// If value is newer than pre_value,return true; otherwise false
|
||||||
bool srs_seq_is_newer(uint16_t value, uint16_t pre_value)
|
bool srs_seq_is_newer(uint16_t value, uint16_t pre_value)
|
||||||
|
|
|
@ -60,6 +60,7 @@ class SrsSharedPtrMessage;
|
||||||
|
|
||||||
// Fast parse the SSRC from RTP packet. Return 0 if invalid.
|
// Fast parse the SSRC from RTP packet. Return 0 if invalid.
|
||||||
uint32_t srs_rtp_fast_parse_ssrc(char* buf, int size);
|
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:
|
// 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
|
// distance(prev_value=3, value=5) === (int16_t)(uint16_t)((uint16_t)3-(uint16_t)5) === -2
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue