1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

SRT: Upgrade libsrt from 1.4.1 to 1.5.1. v6.0.12 (#3362)

Co-authored-by: winlin <winlin@vip.126.com>
This commit is contained in:
john 2023-01-04 19:56:33 +08:00 committed by GitHub
parent 7a56208f2f
commit fe086dfc31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
143 changed files with 38185 additions and 15108 deletions

View file

@ -1,11 +1,11 @@
/*
* SRT - Secure, Reliable, Transport
* SRT - Secure Reliable Transport
* Copyright (c) 2018 Haivision Systems Inc.
*
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*
*/
/*****************************************************************************
@ -50,86 +50,85 @@ modified by
Haivision Systems Inc.
*****************************************************************************/
#ifndef __UDT_PACKET_H__
#define __UDT_PACKET_H__
#ifndef INC_SRT_PACKET_H
#define INC_SRT_PACKET_H
#include "udt.h"
#include "common.h"
#include "utilities.h"
#include "netinet_any.h"
#include "packetfilter_api.h"
namespace srt
{
//////////////////////////////////////////////////////////////////////////////
// The purpose of the IOVector class is to proide a platform-independet interface
// to the WSABUF on Windows and iovec on Linux, that can be easilly converted
// to the native structure for use in WSARecvFrom() and recvmsg(...) functions
// to the native structure for use in WSARecvFrom() and recvmsg(...) functions
class IOVector
#ifdef _WIN32
: public WSABUF
: public WSABUF
#else
: public iovec
: public iovec
#endif
{
public:
inline void set(void *buffer, size_t length)
{
inline void set(void* buffer, size_t length)
{
#ifdef _WIN32
len = (ULONG)length;
buf = (CHAR*)buffer;
len = (ULONG)length;
buf = (CHAR*)buffer;
#else
iov_base = (void*)buffer;
iov_len = length;
iov_base = (void*)buffer;
iov_len = length;
#endif
}
}
inline char*& dataRef()
{
inline char*& dataRef()
{
#ifdef _WIN32
return buf;
return buf;
#else
return (char*&) iov_base;
return (char*&)iov_base;
#endif
}
}
inline char* data()
{
inline char* data()
{
#ifdef _WIN32
return buf;
return buf;
#else
return (char*)iov_base;
return (char*)iov_base;
#endif
}
}
inline size_t size() const
{
inline size_t size() const
{
#ifdef _WIN32
return (size_t) len;
return (size_t)len;
#else
return iov_len;
return iov_len;
#endif
}
}
inline void setLength(size_t length)
{
inline void setLength(size_t length)
{
#ifdef _WIN32
len = length;
len = (ULONG)length;
#else
iov_len = length;
iov_len = length;
#endif
}
}
};
/// To define packets in order in the buffer. This is public due to being used in buffer.
enum PacketBoundary
{
PB_SUBSEQUENT = 0, // 00
/// 01: last packet of a message
PB_LAST = 1, // 01
/// 10: first packet of a message
PB_FIRST = 2, // 10
/// 11: solo message packet
PB_SOLO = 3, // 11
PB_SUBSEQUENT = 0, // 00: a packet in the middle of a message, neither the first, not the last.
PB_LAST = 1, // 01: last packet of a message
PB_FIRST = 2, // 10: first packet of a message
PB_SOLO = 3, // 11: solo message packet
};
// Breakdown of the PM_SEQNO field in the header:
@ -137,7 +136,7 @@ enum PacketBoundary
typedef Bits<31> SEQNO_CONTROL;
// 1|T T T T T T T T T T T T T T T|E E...E
typedef Bits<30, 16> SEQNO_MSGTYPE;
typedef Bits<15, 0> SEQNO_EXTTYPE;
typedef Bits<15, 0> SEQNO_EXTTYPE;
// 0|S S ... S
typedef Bits<30, 0> SEQNO_VALUE;
@ -161,11 +160,11 @@ inline int32_t CreateControlExtSeqNo(int exttype)
// MSGNO breakdown: B B|O|K K|R|M M M M M M M M M M...M
typedef Bits<31, 30> MSGNO_PACKET_BOUNDARY;
typedef Bits<29> MSGNO_PACKET_INORDER;
typedef Bits<29> MSGNO_PACKET_INORDER;
typedef Bits<28, 27> MSGNO_ENCKEYSPEC;
#if 1 // can block rexmit flag
// New bit breakdown - rexmit flag supported.
typedef Bits<26> MSGNO_REXMIT;
typedef Bits<26> MSGNO_REXMIT;
typedef Bits<25, 0> MSGNO_SEQ;
// Old bit breakdown - no rexmit flag
typedef Bits<26, 0> MSGNO_SEQ_OLD;
@ -173,32 +172,36 @@ typedef Bits<26, 0> MSGNO_SEQ_OLD;
// The message should be extracted as PMASK_MSGNO_SEQ, if REXMIT is supported, and PMASK_MSGNO_SEQ_OLD otherwise.
const uint32_t PACKET_SND_NORMAL = 0, PACKET_SND_REXMIT = MSGNO_REXMIT::mask;
const int MSGNO_SEQ_MAX = MSGNO_SEQ::mask;
#else
// Old bit breakdown - no rexmit flag
typedef Bits<26, 0> MSGNO_SEQ;
#endif
typedef RollNumber<MSGNO_SEQ::size - 1, 1> MsgNo;
// constexpr in C++11 !
inline int32_t PacketBoundaryBits(PacketBoundary o) { return MSGNO_PACKET_BOUNDARY::wrap(int32_t(o)); }
inline int32_t PacketBoundaryBits(PacketBoundary o)
{
return MSGNO_PACKET_BOUNDARY::wrap(int32_t(o));
}
enum EncryptionKeySpec
{
EK_NOENC = 0,
EK_EVEN = 1,
EK_ODD = 2
EK_EVEN = 1,
EK_ODD = 2
};
enum EncryptionStatus
{
ENCS_CLEAR = 0,
ENCS_CLEAR = 0,
ENCS_FAILED = -1,
ENCS_NOTSUP = -2
};
const int32_t PMASK_MSGNO_ENCKEYSPEC = MSGNO_ENCKEYSPEC::mask;
const int32_t PMASK_MSGNO_ENCKEYSPEC = MSGNO_ENCKEYSPEC::mask;
inline int32_t EncryptionKeyBits(EncryptionKeySpec f)
{
return MSGNO_ENCKEYSPEC::wrap(int32_t(f));
@ -212,210 +215,170 @@ const int32_t PUMASK_SEQNO_PROBE = 0xF;
std::string PacketMessageFlagStr(uint32_t msgno_field);
class CChannel;
class CPacket
{
friend class CChannel;
friend class CSndQueue;
friend class CRcvQueue;
friend class CChannel;
friend class CSndQueue;
friend class CRcvQueue;
public:
CPacket();
~CPacket();
CPacket();
~CPacket();
void allocate(size_t size);
void deallocate();
void allocate(size_t size);
void deallocate();
/// Get the payload or the control information field length.
/// @return the payload or the control information field length.
/// Get the payload or the control information field length.
/// @return the payload or the control information field length.
size_t getLength() const;
size_t getLength() const;
/// Set the payload or the control information field length.
/// @param len [in] the payload or the control information field length.
void setLength(size_t len);
/// Set the payload or the control information field length.
/// @param len [in] the payload or the control information field length.
/// Pack a Control packet.
/// @param pkttype [in] packet type filed.
/// @param lparam [in] pointer to the first data structure, explained by the packet type.
/// @param rparam [in] pointer to the second data structure, explained by the packet type.
/// @param size [in] size of rparam, in number of bytes;
void pack(UDTMessageType pkttype, const int32_t* lparam = NULL, void* rparam = NULL, size_t size = 0);
void setLength(size_t len);
/// Read the packet vector.
/// @return Pointer to the packet vector.
IOVector* getPacketVector();
/// Pack a Control packet.
/// @param pkttype [in] packet type filed.
/// @param lparam [in] pointer to the first data structure, explained by the packet type.
/// @param rparam [in] pointer to the second data structure, explained by the packet type.
/// @param size [in] size of rparam, in number of bytes;
uint32_t* getHeader() { return m_nHeader; }
void pack(UDTMessageType pkttype, const void* lparam = NULL, void* rparam = NULL, int size = 0);
/// Read the packet type.
/// @return packet type filed (000 ~ 111).
UDTMessageType getType() const;
/// Read the packet vector.
/// @return Pointer to the packet vector.
bool isControl(UDTMessageType type) const { return isControl() && type == getType(); }
IOVector* getPacketVector();
bool isControl() const { return 0 != SEQNO_CONTROL::unwrap(m_nHeader[SRT_PH_SEQNO]); }
uint32_t* getHeader() { return m_nHeader; }
void setControl(UDTMessageType type) { m_nHeader[SRT_PH_SEQNO] = SEQNO_CONTROL::mask | SEQNO_MSGTYPE::wrap(type); }
/// Read the packet flag.
/// @return packet flag (0 or 1).
/// Read the extended packet type.
/// @return extended packet type filed (0x000 ~ 0xFFF).
int getExtendedType() const;
// XXX DEPRECATED. Use isControl() instead
ATR_DEPRECATED
int getFlag() const
{
return isControl() ? 1 : 0;
}
/// Read the ACK-2 seq. no.
/// @return packet header field (bit 16~31).
int32_t getAckSeqNo() const;
/// Read the packet type.
/// @return packet type filed (000 ~ 111).
uint16_t getControlFlags() const;
UDTMessageType getType() const;
// Note: this will return a "singular" value, if the packet
// contains the control message
int32_t getSeqNo() const { return m_nHeader[SRT_PH_SEQNO]; }
bool isControl(UDTMessageType type) const
{
return isControl() && type == getType();
}
/// Read the message boundary flag bit.
/// @return packet header field [1] (bit 0~1).
PacketBoundary getMsgBoundary() const;
bool isControl() const
{
// read bit 0
return 0!= SEQNO_CONTROL::unwrap(m_nHeader[SRT_PH_SEQNO]);
}
/// Read the message inorder delivery flag bit.
/// @return packet header field [1] (bit 2).
bool getMsgOrderFlag() const;
void setControl(UDTMessageType type)
{
m_nHeader[SRT_PH_SEQNO] = SEQNO_CONTROL::mask | SEQNO_MSGTYPE::wrap(type);
}
/// Read the rexmit flag (true if the packet was sent due to retransmission).
/// If the peer does not support retransmission flag, the current agent cannot use it as well
/// (because the peer will understand this bit as a part of MSGNO field).
bool getRexmitFlag() const;
/// Read the extended packet type.
/// @return extended packet type filed (0x000 ~ 0xFFF).
/// Read the message sequence number.
/// @return packet header field [1]
int32_t getMsgSeq(bool has_rexmit = true) const;
int getExtendedType() const;
/// Read the message crypto key bits.
/// @return packet header field [1] (bit 3~4).
EncryptionKeySpec getMsgCryptoFlags() const;
/// Read the ACK-2 seq. no.
/// @return packet header field (bit 16~31).
void setMsgCryptoFlags(EncryptionKeySpec spec);
int32_t getAckSeqNo() const;
uint16_t getControlFlags() const;
/// Read the message time stamp.
/// @return packet header field [2] (bit 0~31, bit 0-26 if SRT_DEBUG_TSBPD_WRAP).
uint32_t getMsgTimeStamp() const;
// Note: this will return a "singular" value, if the packet
// contains the control message
int32_t getSeqNo() const
{
return m_nHeader[SRT_PH_SEQNO];
}
/// Read the message boundary flag bit.
/// @return packet header field [1] (bit 0~1).
PacketBoundary getMsgBoundary() const;
/// Read the message inorder delivery flag bit.
/// @return packet header field [1] (bit 2).
bool getMsgOrderFlag() const;
/// Read the rexmit flag (true if the packet was sent due to retransmission).
/// If the peer does not support retransmission flag, the current agent cannot use it as well
/// (because the peer will understand this bit as a part of MSGNO field).
bool getRexmitFlag() const;
/// Read the message sequence number.
/// @return packet header field [1]
int32_t getMsgSeq(bool has_rexmit = true) const;
/// Read the message crypto key bits.
/// @return packet header field [1] (bit 3~4).
EncryptionKeySpec getMsgCryptoFlags() const;
void setMsgCryptoFlags(EncryptionKeySpec spec);
/// Read the message time stamp.
/// @return packet header field [2] (bit 0~31, bit 0-26 if SRT_DEBUG_TSBPD_WRAP).
uint32_t getMsgTimeStamp() const;
#ifdef SRT_DEBUG_TSBPD_WRAP //Receiver
static const uint32_t MAX_TIMESTAMP = 0x07FFFFFF; //27 bit fast wraparound for tests (~2m15s)
#ifdef SRT_DEBUG_TSBPD_WRAP // Receiver
static const uint32_t MAX_TIMESTAMP = 0x07FFFFFF; // 27 bit fast wraparound for tests (~2m15s)
#else
static const uint32_t MAX_TIMESTAMP = 0xFFFFFFFF; //Full 32 bit (01h11m35s)
static const uint32_t MAX_TIMESTAMP = 0xFFFFFFFF; // Full 32 bit (01h11m35s)
#endif
protected:
static const uint32_t TIMESTAMP_MASK = MAX_TIMESTAMP; // this value to be also used as a mask
static const uint32_t TIMESTAMP_MASK = MAX_TIMESTAMP; // this value to be also used as a mask
public:
/// Clone this packet.
/// @return Pointer to the new packet.
CPacket* clone() const;
/// Clone this packet.
/// @return Pointer to the new packet.
enum PacketVectorFields
{
PV_HEADER = 0,
PV_DATA = 1,
CPacket* clone() const;
enum PacketVectorFields
{
PV_HEADER = 0,
PV_DATA = 1,
PV_SIZE = 2
};
protected:
// Length in bytes
// DynamicStruct is the same as array of given type and size, just it
// enforces that you index it using a symbol from symbolic enum type, not by a bare integer.
typedef DynamicStruct<uint32_t, SRT_PH__SIZE, SrtPktHeaderFields> HEADER_TYPE;
HEADER_TYPE m_nHeader; //< The 128-bit header field
// XXX NOTE: iovec here is not portable. On Windows there's a different
// (although similar) structure defined, which means that this way the
// Windows function that is an equivalent of `recvmsg` cannot be used.
// For example, something like that:
// class IoVector: public iovec { public: size_t size() { return iov_len; } char* data() { return iov_base; } };
// class IoVector: public WSAMSG { public: size_t size() { return len; } char* data() { return buf; } };
IOVector m_PacketVector[PV_SIZE]; //< The 2-demension vector of UDT packet [header, data]
int32_t __pad;
bool m_data_owned;
protected:
CPacket& operator=(const CPacket&);
CPacket (const CPacket&);
PV_SIZE = 2
};
public:
void toNL();
void toHL();
int32_t& m_iSeqNo; // alias: sequence number
int32_t& m_iMsgNo; // alias: message number
int32_t& m_iTimeStamp; // alias: timestamp
int32_t& m_iID; // alias: socket ID
char*& m_pcData; // alias: data/control information
protected:
// DynamicStruct is the same as array of given type and size, just it
// enforces that you index it using a symbol from symbolic enum type, not by a bare integer.
typedef DynamicStruct<uint32_t, SRT_PH_E_SIZE, SrtPktHeaderFields> HEADER_TYPE;
HEADER_TYPE m_nHeader; //< The 128-bit header field
//static const int m_iPktHdrSize; // packet header size
static const size_t HDR_SIZE = sizeof(HEADER_TYPE); // packet header size = SRT_PH__SIZE * sizeof(uint32_t)
IOVector m_PacketVector[PV_SIZE]; //< The two-dimensional vector of an SRT packet [header, data]
// Used in many computations
// Actually this can be also calculated as: sizeof(struct ether_header) + sizeof(struct ip) + sizeof(struct udphdr).
static const size_t UDP_HDR_SIZE = 28; // 20 bytes IPv4 + 8 bytes of UDP { u16 sport, dport, len, csum }.
int32_t m_extra_pad;
bool m_data_owned;
static const size_t SRT_DATA_HDR_SIZE = UDP_HDR_SIZE + HDR_SIZE;
protected:
CPacket& operator=(const CPacket&);
CPacket(const CPacket&);
// Some well known data
static const size_t ETH_MAX_MTU_SIZE = 1500;
public:
int32_t& m_iSeqNo; // alias: sequence number
int32_t& m_iMsgNo; // alias: message number
int32_t& m_iTimeStamp; // alias: timestamp
int32_t& m_iID; // alias: destination SRT socket ID
char*& m_pcData; // alias: payload (data packet) / control information fields (control packet)
// And derived
static const size_t SRT_MAX_PAYLOAD_SIZE = ETH_MAX_MTU_SIZE - SRT_DATA_HDR_SIZE;
// Experimental: sometimes these references don't work!
char* getData();
char* release();
// Packet interface
char* data() { return m_pcData; }
const char* data() const { return m_pcData; }
size_t size() const { return getLength(); }
uint32_t header(SrtPktHeaderFields field) const { return m_nHeader[field]; }
static const size_t HDR_SIZE = sizeof(HEADER_TYPE); // packet header size = SRT_PH_E_SIZE * sizeof(uint32_t)
// Can also be calculated as: sizeof(struct ether_header) + sizeof(struct ip) + sizeof(struct udphdr).
static const size_t UDP_HDR_SIZE = 28; // 20 bytes IPv4 + 8 bytes of UDP { u16 sport, dport, len, csum }.
static const size_t SRT_DATA_HDR_SIZE = UDP_HDR_SIZE + HDR_SIZE;
// Maximum transmission unit size. 1500 in case of Ethernet II (RFC 1191).
static const size_t ETH_MAX_MTU_SIZE = 1500;
// Maximum payload size of an SRT packet.
static const size_t SRT_MAX_PAYLOAD_SIZE = ETH_MAX_MTU_SIZE - SRT_DATA_HDR_SIZE;
// Packet interface
char* data() { return m_pcData; }
const char* data() const { return m_pcData; }
size_t size() const { return getLength(); }
uint32_t header(SrtPktHeaderFields field) const { return m_nHeader[field]; }
std::string MessageFlagStr()
#if ENABLE_LOGGING
{ return PacketMessageFlagStr(m_nHeader[SRT_PH_MSGNO]); }
std::string MessageFlagStr() { return PacketMessageFlagStr(m_nHeader[SRT_PH_MSGNO]); }
std::string Info();
#else
{ return ""; }
std::string MessageFlagStr() { return std::string(); }
std::string Info() { return std::string(); }
#endif
};
} // namespace srt
#endif