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:
parent
7a56208f2f
commit
fe086dfc31
143 changed files with 38185 additions and 15108 deletions
327
trunk/3rdparty/srt-1-fit/srtcore/netinet_any.h
vendored
327
trunk/3rdparty/srt-1-fit/srtcore/netinet_any.h
vendored
|
@ -13,10 +13,12 @@ written by
|
|||
Haivision Systems Inc.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef INC__NETINET_ANY_H
|
||||
#define INC__NETINET_ANY_H
|
||||
#ifndef INC_SRT_NETINET_ANY_H
|
||||
#define INC_SRT_NETINET_ANY_H
|
||||
|
||||
#include <cstring>
|
||||
#include <cstring> // memcmp
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include "platform_sys.h"
|
||||
|
||||
// This structure should replace every use of sockaddr and its currently
|
||||
|
@ -25,6 +27,9 @@ written by
|
|||
// You can use the instances of sockaddr_any in every place where sockaddr is
|
||||
// required.
|
||||
|
||||
namespace srt
|
||||
{
|
||||
|
||||
struct sockaddr_any
|
||||
{
|
||||
union
|
||||
|
@ -33,27 +38,234 @@ struct sockaddr_any
|
|||
sockaddr_in6 sin6;
|
||||
sockaddr sa;
|
||||
};
|
||||
socklen_t len;
|
||||
|
||||
sockaddr_any(int domain = AF_INET)
|
||||
// The type is intended to be the same as the length
|
||||
// parameter in ::accept, ::bind and ::connect functions.
|
||||
|
||||
// This is the type used by SRT.
|
||||
typedef int len_t;
|
||||
|
||||
// This is the type used by system functions
|
||||
#ifdef _WIN32
|
||||
typedef int syslen_t;
|
||||
#else
|
||||
typedef socklen_t syslen_t;
|
||||
#endif
|
||||
|
||||
// Note: by having `len_t` type here the usage in
|
||||
// API functions is here limited to SRT. For system
|
||||
// functions you can pass the address here as (socklen_t*)&sa.len,
|
||||
// but just do it on your own risk, as there's no guarantee
|
||||
// that sizes of `int` and `socklen_t` do not differ. The safest
|
||||
// way seems to be using an intermediate proxy to be written
|
||||
// back here from the value of `syslen_t`.
|
||||
len_t len;
|
||||
|
||||
struct SysLenWrapper
|
||||
{
|
||||
memset(this, 0, sizeof *this);
|
||||
sa.sa_family = domain;
|
||||
len = size();
|
||||
syslen_t syslen;
|
||||
len_t& backwriter;
|
||||
syslen_t* operator&() { return &syslen; }
|
||||
|
||||
SysLenWrapper(len_t& source): syslen(source), backwriter(source)
|
||||
{
|
||||
}
|
||||
|
||||
~SysLenWrapper()
|
||||
{
|
||||
backwriter = syslen;
|
||||
}
|
||||
};
|
||||
|
||||
// Usage:
|
||||
// ::accept(lsn_sock, sa.get(), &sa.syslen());
|
||||
SysLenWrapper syslen()
|
||||
{
|
||||
return SysLenWrapper(len);
|
||||
}
|
||||
|
||||
socklen_t size() const
|
||||
static size_t storage_size()
|
||||
{
|
||||
switch (sa.sa_family)
|
||||
typedef union
|
||||
{
|
||||
case AF_INET: return socklen_t(sizeof sin);
|
||||
case AF_INET6: return socklen_t(sizeof sin6);
|
||||
sockaddr_in sin;
|
||||
sockaddr_in6 sin6;
|
||||
sockaddr sa;
|
||||
} ucopy;
|
||||
return sizeof (ucopy);
|
||||
}
|
||||
|
||||
default: return 0; // fallback, impossible
|
||||
void reset()
|
||||
{
|
||||
// sin6 is the largest field
|
||||
memset((&sin6), 0, sizeof sin6);
|
||||
len = 0;
|
||||
}
|
||||
|
||||
// Default domain is unspecified, and
|
||||
// in this case the size is 0.
|
||||
// Note that AF_* (and alias PF_*) types have
|
||||
// many various values, of which only
|
||||
// AF_INET and AF_INET6 are handled here.
|
||||
// Others make the same effect as unspecified.
|
||||
explicit sockaddr_any(int domain = AF_UNSPEC)
|
||||
{
|
||||
// Default domain is "unspecified", 0
|
||||
reset();
|
||||
|
||||
// Overriding family as required in the parameters
|
||||
// and the size then accordingly.
|
||||
sa.sa_family = domain == AF_INET || domain == AF_INET6 ? domain : AF_UNSPEC;
|
||||
switch (domain)
|
||||
{
|
||||
case AF_INET:
|
||||
len = len_t(sizeof (sockaddr_in));
|
||||
break;
|
||||
|
||||
// Use size of sin6 as the default size
|
||||
// len must be properly set so that the
|
||||
// family-less sockaddr is passed to bind/accept
|
||||
default:
|
||||
len = len_t(sizeof (sockaddr_in6));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sockaddr_any(const sockaddr_storage& stor)
|
||||
{
|
||||
// Here the length isn't passed, so just rely on family.
|
||||
set((const sockaddr*)&stor);
|
||||
}
|
||||
|
||||
sockaddr_any(const sockaddr* source, len_t namelen = 0)
|
||||
{
|
||||
if (namelen == 0)
|
||||
set(source);
|
||||
else
|
||||
set(source, namelen);
|
||||
}
|
||||
|
||||
void set(const sockaddr* source)
|
||||
{
|
||||
// Less safe version, simply trust the caller that the
|
||||
// memory at 'source' is also large enough to contain
|
||||
// all data required for particular family.
|
||||
if (source->sa_family == AF_INET)
|
||||
{
|
||||
memcpy((&sin), source, sizeof sin);
|
||||
len = sizeof sin;
|
||||
}
|
||||
else if (source->sa_family == AF_INET6)
|
||||
{
|
||||
memcpy((&sin6), source, sizeof sin6);
|
||||
len = sizeof sin6;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Error fallback: no other families than IP are regarded.
|
||||
// Note: socket set up this way isn't intended to be used
|
||||
// for bind/accept.
|
||||
sa.sa_family = AF_UNSPEC;
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void set(const sockaddr* source, syslen_t namelen)
|
||||
{
|
||||
// It's not safe to copy it directly, so check.
|
||||
if (source->sa_family == AF_INET && namelen >= syslen_t(sizeof sin))
|
||||
{
|
||||
memcpy((&sin), source, sizeof sin);
|
||||
len = sizeof sin;
|
||||
}
|
||||
else if (source->sa_family == AF_INET6 && namelen >= syslen_t(sizeof sin6))
|
||||
{
|
||||
// Note: this isn't too safe, may crash for stupid values
|
||||
// of source->sa_family or any other data
|
||||
// in the source structure, so make sure it's correct first.
|
||||
memcpy((&sin6), source, sizeof sin6);
|
||||
len = sizeof sin6;
|
||||
}
|
||||
else
|
||||
{
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
void set(const sockaddr_in& in4)
|
||||
{
|
||||
memcpy((&sin), &in4, sizeof in4);
|
||||
len = sizeof in4;
|
||||
}
|
||||
|
||||
void set(const sockaddr_in6& in6)
|
||||
{
|
||||
memcpy((&sin6), &in6, sizeof in6);
|
||||
len = sizeof in6;
|
||||
}
|
||||
|
||||
sockaddr_any(const in_addr& i4_adr, uint16_t port)
|
||||
{
|
||||
// Some cases require separately IPv4 address passed as in_addr,
|
||||
// so port is given separately.
|
||||
sa.sa_family = AF_INET;
|
||||
sin.sin_addr = i4_adr;
|
||||
sin.sin_port = htons(port);
|
||||
len = sizeof sin;
|
||||
}
|
||||
|
||||
sockaddr_any(const in6_addr& i6_adr, uint16_t port)
|
||||
{
|
||||
sa.sa_family = AF_INET6;
|
||||
sin6.sin6_addr = i6_adr;
|
||||
sin6.sin6_port = htons(port);
|
||||
len = sizeof sin6;
|
||||
}
|
||||
|
||||
static len_t size(int family)
|
||||
{
|
||||
switch (family)
|
||||
{
|
||||
case AF_INET:
|
||||
return len_t(sizeof (sockaddr_in));
|
||||
|
||||
case AF_INET6:
|
||||
return len_t(sizeof (sockaddr_in6));
|
||||
|
||||
default:
|
||||
return 0; // fallback
|
||||
}
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
bool isempty = true; // unspec-family address is always empty
|
||||
|
||||
if (sa.sa_family == AF_INET)
|
||||
{
|
||||
isempty = (sin.sin_port == 0
|
||||
&& sin.sin_addr.s_addr == 0);
|
||||
}
|
||||
else if (sa.sa_family == AF_INET6)
|
||||
{
|
||||
isempty = (sin6.sin6_port == 0
|
||||
&& memcmp(&sin6.sin6_addr, &in6addr_any, sizeof in6addr_any) == 0);
|
||||
}
|
||||
// otherwise isempty stays with default false
|
||||
return isempty;
|
||||
}
|
||||
|
||||
len_t size() const
|
||||
{
|
||||
return size(sa.sa_family);
|
||||
}
|
||||
|
||||
int family() const { return sa.sa_family; }
|
||||
void family(int val)
|
||||
{
|
||||
sa.sa_family = val;
|
||||
len = size();
|
||||
}
|
||||
|
||||
// port is in exactly the same location in both sin and sin6
|
||||
// and has the same size. This is actually yet another common
|
||||
|
@ -71,10 +283,26 @@ struct sockaddr_any
|
|||
}
|
||||
|
||||
sockaddr* get() { return &sa; }
|
||||
sockaddr* operator&() { return &sa; }
|
||||
|
||||
const sockaddr* get() const { return &sa; }
|
||||
const sockaddr* operator&() const { return &sa; }
|
||||
|
||||
// Sometimes you need to get the address
|
||||
// the way suitable for e.g. inet_ntop.
|
||||
const void* get_addr() const
|
||||
{
|
||||
if (sa.sa_family == AF_INET)
|
||||
return &sin.sin_addr.s_addr;
|
||||
|
||||
if (sa.sa_family == AF_INET6)
|
||||
return &sin6.sin6_addr;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* get_addr()
|
||||
{
|
||||
const sockaddr_any* that = this;
|
||||
return (void*)that->get_addr();
|
||||
}
|
||||
|
||||
template <int> struct TypeMap;
|
||||
|
||||
|
@ -85,7 +313,26 @@ struct sockaddr_any
|
|||
{
|
||||
bool operator()(const sockaddr_any& c1, const sockaddr_any& c2)
|
||||
{
|
||||
return memcmp(&c1, &c2, sizeof(c1)) == 0;
|
||||
if (c1.family() != c2.family())
|
||||
return false;
|
||||
|
||||
// Cannot use memcmp due to having in some systems
|
||||
// another field like sockaddr_in::sin_len. This exists
|
||||
// in some BSD-derived systems, but is not required by POSIX.
|
||||
// Therefore sockaddr_any class cannot operate with it,
|
||||
// as in this situation it would be safest to state that
|
||||
// particular implementations may have additional fields
|
||||
// of different purpose beside those required by POSIX.
|
||||
//
|
||||
// The only reliable way to compare two underlying sockaddr
|
||||
// object is then to compare the port value and the address
|
||||
// value.
|
||||
//
|
||||
// Fortunately the port is 16-bit and located at the same
|
||||
// offset in both sockaddr_in and sockaddr_in6.
|
||||
|
||||
return c1.sin.sin_port == c2.sin.sin_port
|
||||
&& c1.equal_address(c2);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -120,6 +367,50 @@ struct sockaddr_any
|
|||
return memcmp(&c1, &c2, sizeof(c1)) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Tests if the current address is the "any" wildcard.
|
||||
bool isany() const
|
||||
{
|
||||
if (sa.sa_family == AF_INET)
|
||||
return sin.sin_addr.s_addr == INADDR_ANY;
|
||||
|
||||
if (sa.sa_family == AF_INET6)
|
||||
return memcmp(&sin6.sin6_addr, &in6addr_any, sizeof in6addr_any) == 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Debug support
|
||||
std::string str() const
|
||||
{
|
||||
if (family() != AF_INET && family() != AF_INET6)
|
||||
return "unknown:0";
|
||||
|
||||
std::ostringstream output;
|
||||
char hostbuf[1024];
|
||||
int flags;
|
||||
|
||||
#if ENABLE_GETNAMEINFO
|
||||
flags = NI_NAMEREQD;
|
||||
#else
|
||||
flags = NI_NUMERICHOST | NI_NUMERICSERV;
|
||||
#endif
|
||||
|
||||
if (!getnameinfo(get(), size(), hostbuf, 1024, NULL, 0, flags))
|
||||
{
|
||||
output << hostbuf;
|
||||
}
|
||||
|
||||
output << ":" << hport();
|
||||
return output.str();
|
||||
}
|
||||
|
||||
bool operator==(const sockaddr_any& other) const
|
||||
{
|
||||
return Equal()(*this, other);
|
||||
}
|
||||
|
||||
bool operator!=(const sockaddr_any& other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
template<> struct sockaddr_any::TypeMap<AF_INET> { typedef sockaddr_in type; };
|
||||
|
@ -130,4 +421,6 @@ inline sockaddr_any::TypeMap<AF_INET>::type& sockaddr_any::get<AF_INET>() { retu
|
|||
template <>
|
||||
inline sockaddr_any::TypeMap<AF_INET6>::type& sockaddr_any::get<AF_INET6>() { return sin6; }
|
||||
|
||||
} // namespace srt
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue