1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-13 20:01:56 +00:00
srs/trunk/3rdparty/srt-1-fit/srtcore/netinet_any.h
2021-05-16 08:23:26 +08:00

133 lines
3.6 KiB
C++

/*
* 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/.
*
*/
/*****************************************************************************
written by
Haivision Systems Inc.
*****************************************************************************/
#ifndef INC__NETINET_ANY_H
#define INC__NETINET_ANY_H
#include <cstring>
#include "platform_sys.h"
// This structure should replace every use of sockaddr and its currently
// used specializations, sockaddr_in and sockaddr_in6. This is to simplify
// the use of the original BSD API that relies on type-violating type casts.
// You can use the instances of sockaddr_any in every place where sockaddr is
// required.
struct sockaddr_any
{
union
{
sockaddr_in sin;
sockaddr_in6 sin6;
sockaddr sa;
};
socklen_t len;
sockaddr_any(int domain = AF_INET)
{
memset(this, 0, sizeof *this);
sa.sa_family = domain;
len = size();
}
socklen_t size() const
{
switch (sa.sa_family)
{
case AF_INET: return socklen_t(sizeof sin);
case AF_INET6: return socklen_t(sizeof sin6);
default: return 0; // fallback, impossible
}
}
int family() const { return sa.sa_family; }
// port is in exactly the same location in both sin and sin6
// and has the same size. This is actually yet another common
// field, just not mentioned in the sockaddr structure.
uint16_t& r_port() { return sin.sin_port; }
uint16_t r_port() const { return sin.sin_port; }
int hport() const { return ntohs(sin.sin_port); }
void hport(int value)
{
// Port is fortunately located at the same position
// in both sockaddr_in and sockaddr_in6 and has the
// same size.
sin.sin_port = htons(value);
}
sockaddr* get() { return &sa; }
sockaddr* operator&() { return &sa; }
const sockaddr* get() const { return &sa; }
const sockaddr* operator&() const { return &sa; }
template <int> struct TypeMap;
template <int af_domain>
typename TypeMap<af_domain>::type& get();
struct Equal
{
bool operator()(const sockaddr_any& c1, const sockaddr_any& c2)
{
return memcmp(&c1, &c2, sizeof(c1)) == 0;
}
};
struct EqualAddress
{
bool operator()(const sockaddr_any& c1, const sockaddr_any& c2)
{
if ( c1.sa.sa_family == AF_INET )
{
return c1.sin.sin_addr.s_addr == c2.sin.sin_addr.s_addr;
}
if ( c1.sa.sa_family == AF_INET6 )
{
return memcmp(&c1.sin6.sin6_addr, &c2.sin6.sin6_addr, sizeof (in6_addr)) == 0;
}
return false;
}
};
bool equal_address(const sockaddr_any& rhs) const
{
return EqualAddress()(*this, rhs);
}
struct Less
{
bool operator()(const sockaddr_any& c1, const sockaddr_any& c2)
{
return memcmp(&c1, &c2, sizeof(c1)) < 0;
}
};
};
template<> struct sockaddr_any::TypeMap<AF_INET> { typedef sockaddr_in type; };
template<> struct sockaddr_any::TypeMap<AF_INET6> { typedef sockaddr_in6 type; };
template <>
inline sockaddr_any::TypeMap<AF_INET>::type& sockaddr_any::get<AF_INET>() { return sin; }
template <>
inline sockaddr_any::TypeMap<AF_INET6>::type& sockaddr_any::get<AF_INET6>() { return sin6; }
#endif