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

Upgrade libsrt to v1.5.3. v5.0.183 (#3808)

This commit is contained in:
winlin 2023-09-21 22:31:38 +08:00
parent 389a62ee3a
commit 632d457194
154 changed files with 39813 additions and 17038 deletions

View file

@ -1,11 +1,11 @@
/*
* 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,138 +50,249 @@ modified by
Haivision Systems Inc.
*****************************************************************************/
#ifndef __UDT_CHANNEL_H__
#define __UDT_CHANNEL_H__
#ifndef INC_SRT_CHANNEL_H
#define INC_SRT_CHANNEL_H
#include "platform_sys.h"
#include "udt.h"
#include "packet.h"
#include "socketconfig.h"
#include "netinet_any.h"
namespace srt
{
class CChannel
{
void createSocket(int family);
public:
// XXX There's currently no way to access the socket ID set for
// whatever the channel is currently working for. Required to find
// some way to do this, possibly by having a "reverse pointer".
// Currently just "unimplemented".
std::string CONID() const { return ""; }
// XXX There's currently no way to access the socket ID set for
// whatever the channel is currently working for. Required to find
// some way to do this, possibly by having a "reverse pointer".
// Currently just "unimplemented".
std::string CONID() const { return ""; }
CChannel();
~CChannel();
CChannel();
CChannel(int version);
~CChannel();
/// Open a UDP channel.
/// @param [in] addr The local address that UDP will use.
/// Open a UDP channel.
/// @param [in] addr The local address that UDP will use.
void open(const sockaddr_any& addr);
void open(const sockaddr* addr = NULL);
void open(int family);
/// Open a UDP channel based on an existing UDP socket.
/// @param [in] udpsock UDP socket descriptor.
/// Open a UDP channel based on an existing UDP socket.
/// @param [in] udpsock UDP socket descriptor.
void attach(UDPSOCKET udpsock);
void attach(UDPSOCKET udpsock, const sockaddr_any& adr);
/// Disconnect and close the UDP entity.
/// Disconnect and close the UDP entity.
void close() const;
void close() const;
/// Get the UDP sending buffer size.
/// @return Current UDP sending buffer size.
/// Get the UDP sending buffer size.
/// @return Current UDP sending buffer size.
int getSndBufSize();
int getSndBufSize();
/// Get the UDP receiving buffer size.
/// @return Current UDP receiving buffer size.
/// Get the UDP receiving buffer size.
/// @return Current UDP receiving buffer size.
int getRcvBufSize();
int getRcvBufSize();
/// Set the UDP sending buffer size.
/// @param [in] size expected UDP sending buffer size.
/// Query the socket address that the channel is using.
/// @param [out] addr pointer to store the returned socket address.
void setSndBufSize(int size);
void getSockAddr(sockaddr_any& addr) const;
/// Set the UDP receiving buffer size.
/// @param [in] size expected UDP receiving buffer size.
/// Query the peer side socket address that the channel is connect to.
/// @param [out] addr pointer to store the returned socket address.
void setRcvBufSize(int size);
void getPeerAddr(sockaddr_any& addr) const;
/// Set the IPV6ONLY option.
/// @param [in] IPV6ONLY value.
/// Send a packet to the given address.
/// @param [in] addr pointer to the destination address.
/// @param [in] packet reference to a CPacket entity.
/// @param [in] src source address to sent on an outgoing packet (if not ANY)
/// @return Actual size of data sent.
void setIpV6Only(int ipV6Only);
int sendto(const sockaddr_any& addr, srt::CPacket& packet, const sockaddr_any& src) const;
/// Query the socket address that the channel is using.
/// @param [out] addr pointer to store the returned socket address.
/// Receive a packet from the channel and record the source address.
/// @param [in] addr pointer to the source address.
/// @param [in] packet reference to a CPacket entity.
/// @return Actual size of data received.
void getSockAddr(sockaddr* addr) const;
EReadStatus recvfrom(sockaddr_any& addr, srt::CPacket& packet) const;
/// Query the peer side socket address that the channel is connect to.
/// @param [out] addr pointer to store the returned socket address.
void setConfig(const CSrtMuxerConfig& config);
void getPeerAddr(sockaddr* addr) const;
void getSocketOption(int level, int sockoptname, char* pw_dataptr, socklen_t& w_len, int& w_status);
/// Send a packet to the given address.
/// @param [in] addr pointer to the destination address.
/// @param [in] packet reference to a CPacket entity.
/// @return Actual size of data sent.
template<class Type>
Type sockopt(int level, int sockoptname, Type deflt)
{
Type retval;
socklen_t socklen = sizeof retval;
int status;
getSocketOption(level, sockoptname, ((char*)&retval), (socklen), (status));
if (status == -1)
return deflt;
int sendto(const sockaddr* addr, CPacket& packet) const;
return retval;
}
/// Receive a packet from the channel and record the source address.
/// @param [in] addr pointer to the source address.
/// @param [in] packet reference to a CPacket entity.
/// @return Actual size of data received.
/// Get the IP TTL.
/// @param [in] ttl IP Time To Live.
/// @return TTL.
EReadStatus recvfrom(sockaddr* addr, CPacket& packet) const;
int getIpTTL() const;
#ifdef SRT_ENABLE_IPOPTS
/// Set the IP TTL.
/// @param [in] ttl IP Time To Live.
/// @return none.
/// Get the IP Type of Service.
/// @return ToS.
void setIpTTL(int ttl);
int getIpToS() const;
/// Set the IP Type of Service.
/// @param [in] tos IP Type of Service.
void setIpToS(int tos);
/// Get the IP TTL.
/// @param [in] ttl IP Time To Live.
/// @return TTL.
int getIpTTL() const;
/// Get the IP Type of Service.
/// @return ToS.
int getIpToS() const;
#ifdef SRT_ENABLE_BINDTODEVICE
bool getBind(char* dst, size_t len);
#endif
int ioctlQuery(int type) const;
int sockoptQuery(int level, int option) const;
int ioctlQuery(int type) const;
int sockoptQuery(int level, int option) const;
const sockaddr* bindAddress() { return &m_BindAddr; }
const sockaddr_any& bindAddressAny() { return m_BindAddr; }
const sockaddr* bindAddress() { return m_BindAddr.get(); }
const sockaddr_any& bindAddressAny() { return m_BindAddr; }
private:
void setUDPSockOpt();
void setUDPSockOpt();
private:
const int m_iIPversion; // IP version
int m_iSockAddrSize; // socket address structure size (pre-defined to avoid run-time test)
UDPSOCKET m_iSocket; // socket descriptor
// Mutable because when querying original settings
// this comprises the cache for extracted values,
// although the object itself isn't considered modified.
mutable CSrtMuxerConfig m_mcfg; // Note: ReuseAddr is unused and ineffective.
sockaddr_any m_BindAddr;
// This feature is not enabled on Windows, for now.
// This is also turned off in case of MinGW
#ifdef SRT_ENABLE_PKTINFO
bool m_bBindMasked; // True if m_BindAddr is INADDR_ANY. Need for quick check.
// Calculating the required space is extremely tricky, and whereas on most
// platforms it's possible to define it this way:
//
// size_t s = max( CMSG_SPACE(sizeof(in_pktinfo)), CMSG_SPACE(sizeof(in6_pktinfo)) )
//
// ...on some platforms however CMSG_SPACE macro can't be resolved as constexpr.
//
// This structure is exclusively used to determine the required size for
// CMSG buffer so that it can be allocated in a solid block with CChannel.
// NOT TO BE USED to access any data inside the CMSG message.
struct CMSGNodeIPv4
{
in_pktinfo in4;
size_t extrafill;
cmsghdr hdr;
};
struct CMSGNodeIPv6
{
in6_pktinfo in6;
size_t extrafill;
cmsghdr hdr;
};
// This is 'mutable' because it's a utility buffer defined here
// to avoid unnecessary re-allocations.
mutable char m_acCmsgRecvBuffer [sizeof (CMSGNodeIPv4) + sizeof (CMSGNodeIPv6)]; // Reserved space for ancillary data with pktinfo
mutable char m_acCmsgSendBuffer [sizeof (CMSGNodeIPv4) + sizeof (CMSGNodeIPv6)]; // Reserved space for ancillary data with pktinfo
// IMPORTANT!!! This function shall be called EXCLUSIVELY just after
// calling ::recvmsg function. It uses a static buffer to supply data
// for the call, and it's stated that only one thread is trying to
// use a CChannel object in receiving mode.
sockaddr_any getTargetAddress(const msghdr& msg) const
{
// Loop through IP header messages
cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
for (cmsg = CMSG_FIRSTHDR(&msg);
cmsg != NULL;
cmsg = CMSG_NXTHDR(((msghdr*)&msg), cmsg))
{
// This should be safe - this packet contains always either
// IPv4 headers or IPv6 headers.
if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO)
{
in_pktinfo *dest_ip_ptr = (in_pktinfo*)CMSG_DATA(cmsg);
return sockaddr_any(dest_ip_ptr->ipi_addr, 0);
}
if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO)
{
in6_pktinfo* dest_ip_ptr = (in6_pktinfo*)CMSG_DATA(cmsg);
return sockaddr_any(dest_ip_ptr->ipi6_addr, 0);
}
}
// Fallback for an error
return sockaddr_any(m_BindAddr.family());
}
// IMPORTANT!!! This function shall be called EXCLUSIVELY just before
// calling ::sendmsg function. It uses a static buffer to supply data
// for the call, and it's stated that only one thread is trying to
// use a CChannel object in sending mode.
bool setSourceAddress(msghdr& mh, const sockaddr_any& adr) const
{
// In contrast to an advice followed on the net, there's no case of putting
// both IPv4 and IPv6 ancillary data, case we could have them. Only one
// IP version is used and it's the version as found in @a adr, which should
// be the version used for binding.
if (adr.family() == AF_INET)
{
mh.msg_control = m_acCmsgSendBuffer;
mh.msg_controllen = CMSG_SPACE(sizeof(in_pktinfo));
cmsghdr* cmsg_send = CMSG_FIRSTHDR(&mh);
// after initializing msghdr & control data to CMSG_SPACE(sizeof(struct in_pktinfo))
cmsg_send->cmsg_level = IPPROTO_IP;
cmsg_send->cmsg_type = IP_PKTINFO;
cmsg_send->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
in_pktinfo* pktinfo = (in_pktinfo*) CMSG_DATA(cmsg_send);
pktinfo->ipi_ifindex = 0;
pktinfo->ipi_spec_dst = adr.sin.sin_addr;
return true;
}
if (adr.family() == AF_INET6)
{
mh.msg_control = m_acCmsgSendBuffer;
mh.msg_controllen = CMSG_SPACE(sizeof(in6_pktinfo));
cmsghdr* cmsg_send = CMSG_FIRSTHDR(&mh);
cmsg_send->cmsg_level = IPPROTO_IPV6;
cmsg_send->cmsg_type = IPV6_PKTINFO;
cmsg_send->cmsg_len = CMSG_LEN(sizeof(in6_pktinfo));
in6_pktinfo* pktinfo = (in6_pktinfo*) CMSG_DATA(cmsg_send);
pktinfo->ipi6_ifindex = 0;
pktinfo->ipi6_addr = adr.sin6.sin6_addr;
return true;
}
return false;
}
#endif // SRT_ENABLE_PKTINFO
UDPSOCKET m_iSocket; // socket descriptor
#ifdef SRT_ENABLE_IPOPTS
int m_iIpTTL;
int m_iIpToS;
#endif
int m_iSndBufSize; // UDP sending buffer size
int m_iRcvBufSize; // UDP receiving buffer size
int m_iIpV6Only; // IPV6_V6ONLY option (-1 if not set)
sockaddr_any m_BindAddr;
};
} // namespace srt
#endif