Socket/Protocols/INet: Add optional resolve-type argument to INet6 adressing classes...
g0dil [Tue, 31 Jul 2007 12:26:16 +0000 (12:26 +0000)]
Socket/Protocols/INet: removed obsolte INet6SocketAddress constructor

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@366 270642c3-0616-0410-b53a-bc976706d245

Socket/Protocols/INet/INet6Address.cc
Socket/Protocols/INet/INet6Address.hh
Socket/Protocols/INet/INet6Address.test.cc
Socket/Protocols/INet/INetAddressing.cc
Socket/Protocols/INet/INetAddressing.cci
Socket/Protocols/INet/INetAddressing.hh
Socket/Protocols/INet/INetAddressing.test.cc

index 0def041..03f8944 100644 (file)
@@ -38,7 +38,8 @@
 ///////////////////////////////////////////////////////////////////////////
 // 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;
     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
 
 #   endif // __GLIBC__
 
-    if (!ent)
-        ///\fixme Need to give better exception here
-        throw SyntaxException(); 
-    if (ent->h_addrtype != AF_INET6)
-        throw SyntaxException();    
-
-    // We are only interested in the first address ...
-    return senf::INet6Address::from_data(
-        &reinterpret_cast<in6_addr*>(*(ent->h_addr_list))->s6_addr[0]);
+    if (ent && ent->h_addrtype == AF_INET6)
+        // We are only interested in the first address ...
+        return senf::INet6Address::from_data(
+            &reinterpret_cast<in6_addr*>(*(ent->h_addr_list))->s6_addr[0]);
+
+    ///\todo Throw better exceptions here ?
+
+    if (resolve == ResolveINet4)
+        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)
index c40e7cc..2b93f7b 100644 (file)
@@ -99,6 +99,7 @@ namespace senf {
         static INet6Address const AllRouters;  ///< The 'all routers' link-local multicast address
 
         enum NoInit_t { noinit };
+        enum Resolve_t { ResolveINet6, ResolveINet4 };
 
         /** \brief Possible scope values
 
@@ -128,7 +129,7 @@ namespace senf {
                      boost::uint16_t a6=0u, boost::uint16_t a7=0u);
                                         ///< 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
                                         /**< This member will try to convert the given string into
                                              an IP address. from_string() supports all standard IP
@@ -138,9 +139,15 @@ namespace senf {
                                                  protocol like DNS or NIS
                                              \throws SyntaxException if the address cannot be
                                                  converted for some reason
-                                             \param[in] s Address literal or hostname */
-
-        static void from_string(std::string const & s, Callback const & cb);
+                                             \param[in] s Address literal or hostname 
+                                             \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. */
+
+        static void from_string(std::string const & s, Callback const & cb, 
+                                Resolve_t resolve = ResolveINet6);
                                         ///< Convert string to address (async/non-blocking)
                                         /**< This member works like
                                              from_string(std::string const &). However unlike
@@ -152,6 +159,11 @@ namespace senf {
                                              On error, the address passed to \a cb will be empty.
                                              \param[in] s Address literal or hostname
                                              \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 */
 
         template <class InputIterator> 
index f51c6c4..22340c8 100644 (file)
@@ -74,6 +74,10 @@ BOOST_AUTO_UNIT_TEST(inet6Address)
         BOOST_CHECK_EQUAL( addr3, INet6Address::from_string("1200::21") );
         BOOST_CHECK_EQUAL( INet6Address::from_inet4address(INet4Address(0x01020304)),
                            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") );
     }
 
     {
index 41c0f92..a54cc1c 100644 (file)
@@ -73,6 +73,36 @@ prefix_ void senf::INet4SocketAddress::clear()
 ///////////////////////////////////////////////////////////////////////////
 // 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)
     const
 {
@@ -103,32 +133,6 @@ prefix_ std::string senf::INet6SocketAddress::iface()
     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)
 {
     if (iface.empty())
index 320e8ee..a9987e9 100644 (file)
@@ -104,12 +104,6 @@ prefix_ senf::INet6SocketAddress::INet6SocketAddress()
     clear();
 }
 
-prefix_ senf::INet6SocketAddress::INet6SocketAddress(std::string const & addr)
-{
-    clear();
-    assignAddr(addr);
-}
-
 prefix_ senf::INet6SocketAddress::INet6SocketAddress(INet6Address const & addr, unsigned port)
 {
     clear();
@@ -126,14 +120,6 @@ prefix_ senf::INet6SocketAddress::INet6SocketAddress(INet6Address const & addr,
     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()
     const
 {
index e3a95d3..5389b65 100644 (file)
@@ -154,14 +154,17 @@ namespace senf {
         ///@{
 
         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
+                                        /**< \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);
                                         ///< Initialize from address and port
         INet6SocketAddress(INet6Address const & addr, unsigned port, std::string const & iface);
                                         ///< 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 {
     protected:
 
     private:
-        void assignAddr(std::string const & addr);
         void assignIface(std::string const & iface);
 
         struct sockaddr_in6 sockaddr_;
index e512761..ee68de8 100644 (file)
@@ -94,6 +94,9 @@ BOOST_AUTO_UNIT_TEST(inet6SocketAddress)
         BOOST_CHECK_EQUAL( addr.iface(), "" );
         BOOST_CHECK_EQUAL( addr, INet6SocketAddress("[12::21]:12345") );
         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 );
     }
 
     {