[Home]BoostSocket/AddressConcept

BOOST WIKI | BoostSocket | RecentChanges | Preferences | Page List | Links List

Address concept

The Address concept represents a communication end point. As far as the socket library is concerned, the follow are the three functions required.

Too enable the user to use the address in containers, etc, the following are requirements

All name lookup and resolution (gethostbyname, inet_addr, et al) is address family specific.

It would be worth specifiying an IpAddress? concept to get interoperability between Ip4 and Ip6. This would specify port, hostname conversions, etc

Comment

I don't think such APIs like gethostbyname are good enough to use widely, especially in a mutithreaded environment. I suggest an addressinfo class, which provide a thin wrap to the addrinfo struct.

class addressinfo { public:

	addressinfo()
	: m_addrinfo(NULL), m_begin(NULL), m_engaged(false)
	{
	}

	~addressinfo()
	{
		if (m_engaged)
			::freeaddrinfo(m_begin);
	}

	/*
	* flags  	AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST
	* family	PF_UNSPEC, PF_INET, PF_INET6
	* socktype	SOCK_STREAM, SOCK_DGRAM, 0
	* protocol	IPPROTO_IP, IPPROTO_IPV6, IPPROTO_TCP, IPPROTO_UDP, 0
	*/
	void getaddrinfo(
			 const char* service, 
			 const char* name,
			 const int   flags    = 0,
			 const int   family   = PF_UNSPEC, 
			 const int   socktype = 0,
			 const int   protocol = 0 )
	{
		int result;
		if(m_engaged)
		{
			m_engaged = false;
			::freeaddrinfo(m_begin);
		}
		::addrinfo hint;
		memset(&hint, 0, sizeof(hint));
		hint.ai_flags = flags;
		hint.ai_family = family;
		hint.ai_socktype = socktype;
		hint.ai_protocol = protocol;
		m_engaged = true;
		result = ::getaddrinfo(name, service, &hint, &m_begin);
		if (result != 0)
		{
                        //throw exception
		}
		rewind();
		return;
	}

	const int ai_flags()
	{
		return m_addrinfo->ai_flags;
	}
	const int ai_family()
	{
		return m_addrinfo->ai_family;
	}
	const int ai_socktype()
	{
		return m_addrinfo->ai_socktype;
	}
	const int ai_protocol()
	{
		return m_addrinfo->ai_protocol;
	}
	const ::sockaddr* ai_addr()
	{
		return m_addrinfo->ai_addr;
	}
	const size_t ai_addrlen()
	{
		return m_addrinfo->ai_addrlen;
	}

	bool next()
	{
		if (m_addrinfo->ai_next != NULL)
		{
			m_addrinfo = m_addrinfo->ai_next;
			return true;
		}
		else
		{
			rewind();
			return false;
		}
	}

private:

	void rewind()
	{
		m_addrinfo = m_begin;
	}

private:

	::addrinfo* m_addrinfo;
	::addrinfo* m_begin;
	bool m_engaged;
};

It can provide thread-safety, portablity and protocol-independence IMHO.

-- See BoostSocket/AddressInfoConcept -- Hugo

Comment on resolving and naming

I would propose that we separate name resolving from the actual address class. Actually i would like to propose these interfaces for address and resolving (wraps addrinfo if present on platform). The interface below is an general ip4 and ip6 structure. I think that we should strive to make ip4/ip6 work compiletime polymorph and diff ip4/ip6 as little as possible so transition and supporting both ip4 and ip6 can be smooth and made easily configurable without having to have double hierarchies of addresses, protocols if possible. And I would propose enabling and detecting ipv6 via a config define BOOST_HAS_IPV6??

    struct ip_address 
    {
    enum family_t
    {
        family_ipv4 = 1,
        family_ipv6 = 2
    };

    enum special_address_t
    {
        no_special_address,
        special_address_any,
        special_address_broadcast,
        special_address_loopback,
        special_address_none
    };

    /// construct an addres from a numeric string.  Eg dotted IPv4 or numeric IPv6.
    /// @throws boost::socket::error on failure eg bad string format
    ip_address(const std::string& numeric);

    /// construct an special address
    ip_address(special_address_t special, family_t family);

    /// Copy and assignment for value semantics
    ip_address(const ip_address& address);
    ip_address& operator=(const ip_address& address);

    /// Destructor
    ~ip_address();

    /// String representation of address.
    const std::string& to_str() const;

    /// octets of ip address.
    const std::vector<unsigned char> ip_address() const;

    /// Fully Qualified Domain Name (FQDN) for address, 
    /// if this represents a resolved addres empty if 
    /// address isn't an resolved.
    const std::string& host_name() const;

    family_t family() const;
    special_address_t special_address() const;

    /// implementation defined default sorting order
    bool operator<(const ip_address& other) const;
    /// equality
    bool operator==(const ip_address& other) const;
    /// inequality
    bool operator!=(const ip_address& other) const { return !operator==(other); }
    }

    struct ip_end_point 
    {
    enum special_port
    {
        special_port_any = 0
    };

    typedef unsigned short port_t;

    /// Copy constructor
    ip_end_point (const end_point& other);

    /// Constructs an end point from address and port
    ip_end_point (const address& address, port_t port);

    /// Constructs an end point from address string x.y.z.x:p
    ip_end_point (const std::string& address);

    /// port
    port_t port() const;
    /// address
    const ip_end_point& ip_address() const;

    family_t family() const;
    std::pair<void*,unsigned> representation(); // pointer to internal rep and size pointer
    // equality
    end_point& operator=(const  end_point& other);
    /// implementation defined default sorting order
    bool operator<(const end_point& other);
   };

   struct ip_resolver
   {
    /// 
    ip_resolver (const std::string& host);
    typedef impl_def_iterator const_iterator;

    /// do the actual resolving if not called
    /// throws on error.
    void resolve();

    /// will call resolve if not called
    const_iterator begin() const; /// iterator pointing to const ip_address&
    const_iterator end() const; /// iterator pointing to const ip_address&
    size_t size() const; 
    bool empty() const;
   };

I would propose a general definition of address concept like this:

constructors assignment:

Ordering and comparing


BOOST WIKI | BoostSocket | RecentChanges | Preferences | Page List | Links List
Edit text of this page | View other revisions
Last edited December 18, 2004 12:32 pm (diff)
Search:
Disclaimer: This site not officially maintained by Boost Developers