Skip to content
Snippets Groups Projects
Commit fc9df7ba authored by g0dil's avatar g0dil
Browse files

Socket/Protocols/INet: Add optional resolve-type argument to INet6 adressing...

Socket/Protocols/INet: Add optional resolve-type argument to INet6 adressing classes to support IpV4 mapped addresses
Socket/Protocols/INet: removed obsolte INet6SocketAddress constructor
parent 1b7e0eac
No related branches found
No related tags found
No related merge requests found
...@@ -38,7 +38,8 @@ ...@@ -38,7 +38,8 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// senf::INet6Address // senf::INet6Address
prefix_ senf::INet6Address senf::INet6Address::from_string(std::string const & s) prefix_ senf::INet6Address senf::INet6Address::from_string(std::string const & s,
Resolve_t resolve)
{ {
struct in6_addr ina; struct in6_addr ina;
if (::inet_pton(AF_INET6,s.c_str(),&ina) > 0) if (::inet_pton(AF_INET6,s.c_str(),&ina) > 0)
...@@ -66,15 +67,21 @@ prefix_ senf::INet6Address senf::INet6Address::from_string(std::string const & s ...@@ -66,15 +67,21 @@ prefix_ senf::INet6Address senf::INet6Address::from_string(std::string const & s
# endif // __GLIBC__ # endif // __GLIBC__
if (!ent) if (ent && ent->h_addrtype == AF_INET6)
///\fixme Need to give better exception here // We are only interested in the first address ...
throw SyntaxException(); return senf::INet6Address::from_data(
if (ent->h_addrtype != AF_INET6) &reinterpret_cast<in6_addr*>(*(ent->h_addr_list))->s6_addr[0]);
throw SyntaxException();
///\todo Throw better exceptions here ?
// We are only interested in the first address ...
return senf::INet6Address::from_data( if (resolve == ResolveINet4)
&reinterpret_cast<in6_addr*>(*(ent->h_addr_list))->s6_addr[0]); try {
return from_inet4address(INet4Address::from_string(s));
} catch (INet4Address::SyntaxException const & ex) {
throw SyntaxException();
}
else
throw SyntaxException();
} }
prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6Address const & addr) prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6Address const & addr)
......
...@@ -99,6 +99,7 @@ namespace senf { ...@@ -99,6 +99,7 @@ namespace senf {
static INet6Address const AllRouters; ///< The 'all routers' link-local multicast address static INet6Address const AllRouters; ///< The 'all routers' link-local multicast address
enum NoInit_t { noinit }; enum NoInit_t { noinit };
enum Resolve_t { ResolveINet6, ResolveINet4 };
/** \brief Possible scope values /** \brief Possible scope values
...@@ -128,7 +129,7 @@ namespace senf { ...@@ -128,7 +129,7 @@ namespace senf {
boost::uint16_t a6=0u, boost::uint16_t a7=0u); boost::uint16_t a6=0u, boost::uint16_t a7=0u);
///< Construct an address constant ///< Construct an address constant
static INet6Address from_string(std::string const & s); static INet6Address from_string(std::string const & s, Resolve_t resolve = ResolveINet6);
///< Convert string to address ///< Convert string to address
/**< This member will try to convert the given string into /**< This member will try to convert the given string into
an IP address. from_string() supports all standard IP an IP address. from_string() supports all standard IP
...@@ -138,9 +139,15 @@ namespace senf { ...@@ -138,9 +139,15 @@ namespace senf {
protocol like DNS or NIS protocol like DNS or NIS
\throws SyntaxException if the address cannot be \throws SyntaxException if the address cannot be
converted for some reason converted for some reason
\param[in] s Address literal or hostname */ \param[in] s Address literal or hostname
\param[in] resolve If this is set to \c ResolveINet4,
static void from_string(std::string const & s, Callback const & cb); the call will additionally try to interpret \a s as
an IpV4 address if no valid IpV6 address is
found. The address will be returned as mapped IpV6
address. */
static void from_string(std::string const & s, Callback const & cb,
Resolve_t resolve = ResolveINet6);
///< Convert string to address (async/non-blocking) ///< Convert string to address (async/non-blocking)
/**< This member works like /**< This member works like
from_string(std::string const &). However unlike from_string(std::string const &). However unlike
...@@ -152,6 +159,11 @@ namespace senf { ...@@ -152,6 +159,11 @@ namespace senf {
On error, the address passed to \a cb will be empty. On error, the address passed to \a cb will be empty.
\param[in] s Address literal or hostname \param[in] s Address literal or hostname
\param[in] cb Callback to pass the address to \param[in] cb Callback to pass the address to
\param[in] resolve If this is set to \c ResolveINet4,
the call will additionally try to interpret \a s as
an IpV4 address if no valid IpV6 address is
found. The address will be returned as mapped IpV6
address.
\fixme Implement */ \fixme Implement */
template <class InputIterator> template <class InputIterator>
......
...@@ -74,6 +74,10 @@ BOOST_AUTO_UNIT_TEST(inet6Address) ...@@ -74,6 +74,10 @@ BOOST_AUTO_UNIT_TEST(inet6Address)
BOOST_CHECK_EQUAL( addr3, INet6Address::from_string("1200::21") ); BOOST_CHECK_EQUAL( addr3, INet6Address::from_string("1200::21") );
BOOST_CHECK_EQUAL( INet6Address::from_inet4address(INet4Address(0x01020304)), BOOST_CHECK_EQUAL( INet6Address::from_inet4address(INet4Address(0x01020304)),
INet6Address::from_string("::ffff:1.2.3.4") ); INet6Address::from_string("::ffff:1.2.3.4") );
BOOST_CHECK_THROW( INet6Address::from_string("1.2.3.4"), INet6Address::SyntaxException );
BOOST_CHECK_EQUAL( INet6Address::from_string("1.2.3.4", INet6Address::ResolveINet4),
INet6Address::from_string("::ffff:1.2.3.4") );
} }
{ {
......
...@@ -73,6 +73,36 @@ prefix_ void senf::INet4SocketAddress::clear() ...@@ -73,6 +73,36 @@ prefix_ void senf::INet4SocketAddress::clear()
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// senf::INet6SocketAddress // senf::INet6SocketAddress
prefix_ senf::INet6SocketAddress::INet6SocketAddress(std::string const & addr,
INet6Address::Resolve_t resolve)
{
clear();
// Format of addr: "[" address [ "%" interface ] "]" ":" port
// or: host ":" port
static boost::regex const addressRx ("(?:\\[([a-f0-9A-F:]+)(?:%(.+))?\\]|(.+)):([0-9]+)");
// Subexpression numbers:
enum { NumericAddr = 1,
ZoneId = 2,
Hostname = 3,
Port = 4 };
boost::smatch match;
if (! regex_match(addr, match, addressRx))
throw SyntaxException();
INet6Address a (INet6Address::from_string(
match[NumericAddr].matched ? match[NumericAddr] : match[Hostname],
resolve));
std::copy(a.begin(), a.end(), &sockaddr_.sin6_addr.s6_addr[0]);
if (match[ZoneId].matched)
assignIface(match[ZoneId]);
sockaddr_.sin6_port = htons(boost::lexical_cast<boost::uint16_t>(match[Port]));
}
prefix_ bool senf::INet6SocketAddress::operator==(INet6SocketAddress const & other) prefix_ bool senf::INet6SocketAddress::operator==(INet6SocketAddress const & other)
const const
{ {
...@@ -103,32 +133,6 @@ prefix_ std::string senf::INet6SocketAddress::iface() ...@@ -103,32 +133,6 @@ prefix_ std::string senf::INet6SocketAddress::iface()
return std::string(buffer); return std::string(buffer);
} }
prefix_ void senf::INet6SocketAddress::assignAddr(std::string const & addr)
{
// Format of addr: "[" address [ "%" interface ] "]" ":" port
// or: host ":" port
static boost::regex const addressRx ("(?:\\[([a-f0-9A-F:]+)(?:%(.+))?\\]|(.+)):([0-9]+)");
// Subexpression numbers:
enum { NumericAddr = 1,
ZoneId = 2,
Hostname = 3,
Port = 4 };
boost::smatch match;
if (! regex_match(addr, match, addressRx))
throw SyntaxException();
INet6Address a (INet6Address::from_string(
match[NumericAddr].matched ? match[NumericAddr] : match[Hostname]));
std::copy(a.begin(), a.end(), &sockaddr_.sin6_addr.s6_addr[0]);
if (match[ZoneId].matched)
assignIface(match[ZoneId]);
sockaddr_.sin6_port = htons(boost::lexical_cast<boost::uint16_t>(match[Port]));
}
prefix_ void senf::INet6SocketAddress::assignIface(std::string const & iface) prefix_ void senf::INet6SocketAddress::assignIface(std::string const & iface)
{ {
if (iface.empty()) if (iface.empty())
......
...@@ -104,12 +104,6 @@ prefix_ senf::INet6SocketAddress::INet6SocketAddress() ...@@ -104,12 +104,6 @@ prefix_ senf::INet6SocketAddress::INet6SocketAddress()
clear(); clear();
} }
prefix_ senf::INet6SocketAddress::INet6SocketAddress(std::string const & addr)
{
clear();
assignAddr(addr);
}
prefix_ senf::INet6SocketAddress::INet6SocketAddress(INet6Address const & addr, unsigned port) prefix_ senf::INet6SocketAddress::INet6SocketAddress(INet6Address const & addr, unsigned port)
{ {
clear(); clear();
...@@ -126,14 +120,6 @@ prefix_ senf::INet6SocketAddress::INet6SocketAddress(INet6Address const & addr, ...@@ -126,14 +120,6 @@ prefix_ senf::INet6SocketAddress::INet6SocketAddress(INet6Address const & addr,
assignIface(iface); assignIface(iface);
} }
prefix_ senf::INet6SocketAddress::INet6SocketAddress(std::string const & addr,
std::string const & iface)
{
clear();
assignAddr(addr);
assignIface(iface);
}
prefix_ senf::INet6Address senf::INet6SocketAddress::address() prefix_ senf::INet6Address senf::INet6SocketAddress::address()
const const
{ {
......
...@@ -154,14 +154,17 @@ namespace senf { ...@@ -154,14 +154,17 @@ namespace senf {
///@{ ///@{
INet6SocketAddress(); ///< Create empty instance INet6SocketAddress(); ///< Create empty instance
explicit INet6SocketAddress(std::string const & addr); explicit INet6SocketAddress(std::string const & addr,
INet6Address::Resolve_t resolve = INet6Address::ResolveINet6);
///< Initialize/convert from string representation ///< Initialize/convert from string representation
/**< \param[in] addr Address to parse
\param[in] resolve If this is
INet6Address::ResolveINet4, support also IpV4
addresses. See INet6Address. */
INet6SocketAddress(INet6Address const & addr, unsigned port); INet6SocketAddress(INet6Address const & addr, unsigned port);
///< Initialize from address and port ///< Initialize from address and port
INet6SocketAddress(INet6Address const & addr, unsigned port, std::string const & iface); INet6SocketAddress(INet6Address const & addr, unsigned port, std::string const & iface);
///< Initialize explicitly from given parameters ///< Initialize explicitly from given parameters
INet6SocketAddress(std::string const & addr, std::string const & iface);
///< Initialize from URL representation and explit interface
///@} ///@}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
...@@ -197,7 +200,6 @@ namespace senf { ...@@ -197,7 +200,6 @@ namespace senf {
protected: protected:
private: private:
void assignAddr(std::string const & addr);
void assignIface(std::string const & iface); void assignIface(std::string const & iface);
struct sockaddr_in6 sockaddr_; struct sockaddr_in6 sockaddr_;
......
...@@ -94,6 +94,9 @@ BOOST_AUTO_UNIT_TEST(inet6SocketAddress) ...@@ -94,6 +94,9 @@ BOOST_AUTO_UNIT_TEST(inet6SocketAddress)
BOOST_CHECK_EQUAL( addr.iface(), "" ); BOOST_CHECK_EQUAL( addr.iface(), "" );
BOOST_CHECK_EQUAL( addr, INet6SocketAddress("[12::21]:12345") ); BOOST_CHECK_EQUAL( addr, INet6SocketAddress("[12::21]:12345") );
BOOST_CHECK_NO_THROW( INet6SocketAddress("www.6bone.net:80") ); BOOST_CHECK_NO_THROW( INet6SocketAddress("www.6bone.net:80") );
addr = senf::INet6SocketAddress("1.2.3.4:12345", INet6Address::ResolveINet4);
BOOST_CHECK_EQUAL( addr.address(), INet6Address::from_string("::ffff:1.2.3.4") );
BOOST_CHECK_EQUAL( addr.port(), 12345u );
} }
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment