mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +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
 |