mirror of
https://github.com/ossrs/srs.git
synced 2025-02-13 20:01:56 +00:00
133 lines
3.6 KiB
C++
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
|