Console: Implement BSDSocketAddress and BSDAddressingPolicy
g0dil [Tue, 3 Jun 2008 10:53:41 +0000 (10:53 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@865 270642c3-0616-0410-b53a-bc976706d245

21 files changed:
Scheduler/Scheduler.hh
Socket/CommunicationPolicy.cti
Socket/Protocols/BSDAddressingPolicy.cc [moved from Socket/Protocols/GenericAddressingPolicy.cc with 82% similarity]
Socket/Protocols/BSDAddressingPolicy.cti [moved from Socket/Protocols/GenericAddressingPolicy.cti with 78% similarity]
Socket/Protocols/BSDAddressingPolicy.hh [moved from Socket/Protocols/GenericAddressingPolicy.hh with 80% similarity]
Socket/Protocols/BSDAddressingPolicy.test.cc [new file with mode: 0644]
Socket/Protocols/BSDSocketAddress.cc [new file with mode: 0644]
Socket/Protocols/BSDSocketAddress.cci [new file with mode: 0644]
Socket/Protocols/BSDSocketAddress.hh [new file with mode: 0644]
Socket/Protocols/BSDSocketAddress.test.cc [new file with mode: 0644]
Socket/Protocols/INet/INetAddressing.cc
Socket/Protocols/INet/INetAddressing.cci
Socket/Protocols/INet/INetAddressing.hh
Socket/Protocols/Raw/LLAddressing.cci
Socket/Protocols/Raw/LLAddressing.hh
Socket/Protocols/UN/UNAddressing.cc
Socket/Protocols/UN/UNAddressing.cci [new file with mode: 0644]
Socket/Protocols/UN/UNAddressing.hh
Socket/Protocols/UN/UNAddressing.test.cc
Socket/Protocols/main.test.cc [new file with mode: 0644]
Socket/ReadWritePolicy.cti

index 4869e8f..411890c 100644 (file)
@@ -324,6 +324,10 @@ namespace senf {
                                              returns. */
         
         ClockService::clock_type eventTime() const; ///< Return date/time of last event
+                                        /**< This is the timestamp, the last event has been
+                                             signaled. This is the real time at which the event is
+                                             delivered \e not the time it should have been delivered
+                                             (in the case of timers). */
 
     protected:
 
index 375372c..6675ed4 100644 (file)
@@ -53,7 +53,7 @@ accept(ServerSocketHandle<SPolicy> handle,
        typename ServerSocketHandle<SPolicy>::Address & address,
        typename IfAddressingPolicyIsNot<SPolicy,NoAddressingPolicy>::type *)
 {
-    return do_accept(handle,address.sockaddr_p(),address.sockaddr_len());
+    return do_accept(handle,address.sockaddr_p(),address.socklen());
 }
 #else
 template <class SPolicy>
similarity index 82%
rename from Socket/Protocols/GenericAddressingPolicy.cc
rename to Socket/Protocols/BSDAddressingPolicy.cc
index 9031707..c3f6e12 100644 (file)
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief GenericAddressingPolicy non-inline non-template implementation
+    \brief BSDAddressingPolicyMixin non-inline non-template implementation
  */
 
-#include "GenericAddressingPolicy.hh"
-//#include "GenericAddressingPolicy.ih"
+#include "BSDAddressingPolicy.hh"
+//#include "BSDAddressingPolicy.ih"
 
 // Custom includes
 #include <sys/socket.h>
 #include <sys/types.h>
 #include "../../Utils/Exception.hh"
 
-//#include "GenericAddressingPolicy.mpp"
+//#include "BSDAddressingPolicy.mpp"
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
-prefix_ void senf::GenericAddressingPolicy_Base::do_local(FileHandle handle,
+prefix_ void senf::BSDAddressingPolicyMixinBase::do_local(FileHandle handle,
                                                                  struct sockaddr * addr,
-                                                                 unsigned len)
+                                                                 socklen_t * len)
 {
-    if (::getsockname(handle.fd(),addr,&len) < 0)
+    if (::getsockname(handle.fd(),addr,len) < 0)
         SENF_THROW_SYSTEM_EXCEPTION("");
 }
 
-prefix_ void senf::GenericAddressingPolicy_Base::do_peer(FileHandle handle,
+prefix_ void senf::BSDAddressingPolicyMixinBase::do_peer(FileHandle handle,
                                                                 struct sockaddr * addr,
-                                                                unsigned len)
+                                                                socklen_t * len)
 {
-    if (::getpeername(handle.fd(),addr,&len) < 0)
+    if (::getpeername(handle.fd(),addr,len) < 0)
         SENF_THROW_SYSTEM_EXCEPTION("");
 }
 
-prefix_ void senf::GenericAddressingPolicy_Base::do_bind(FileHandle handle,
+prefix_ void senf::BSDAddressingPolicyMixinBase::do_bind(FileHandle handle,
                                                                 struct sockaddr const * addr,
-                                                                unsigned len)
+                                                                socklen_t len)
 {
     if (::bind(handle.fd(),addr,len) < 0)
         SENF_THROW_SYSTEM_EXCEPTION("");
 }
 
-prefix_ void senf::GenericAddressingPolicy_Base::do_connect(FileHandle handle,
+prefix_ void senf::BSDAddressingPolicyMixinBase::do_connect(FileHandle handle,
                                                                    struct sockaddr const * addr,
-                                                                   unsigned len)
+                                                                   socklen_t len)
 {
     while(1) {
         if (::connect(handle.fd(),addr,len) < 0)
@@ -89,7 +89,7 @@ prefix_ void senf::GenericAddressingPolicy_Base::do_connect(FileHandle handle,
 
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_
-//#include "GenericAddressingPolicy.mpp"
+//#include "BSDAddressingPolicy.mpp"
 
 \f
 // Local Variables:
similarity index 78%
rename from Socket/Protocols/GenericAddressingPolicy.cti
rename to Socket/Protocols/BSDAddressingPolicy.cti
index 6cba6c2..abac866 100644 (file)
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief GenericAddressingPolicy inline template implementation
+    \brief BSDAddressingPolicyMixin inline template implementation
  */
 
-//#include "GenericAddressingPolicy.ih"
+//#include "BSDAddressingPolicy.ih"
 
 // Custom includes
 
 ///////////////////////////////cti.p///////////////////////////////////////
 
 ///////////////////////////////////////////////////////////////////////////
-// senf::GenericAddressingPolicy<Address>
+// senf::BSDAddressingPolicyMixin<Address>
 
 #ifndef DOXYGEN
 template <class Address>
 template <class SPolicy>
-prefix_ void senf::GenericAddressingPolicy<Address>::
+prefix_ void senf::BSDAddressingPolicyMixin<Address>::
 peer(SocketHandle<SPolicy> handle, Address & addr,
      typename IfCommunicationPolicyIs<SPolicy,ConnectedCommunicationPolicy>::type *)
 {
-    addr.clear();
     try {
-        do_peer(handle,addr.sockaddr_p(),addr.sockaddr_len());
+        do_peer(handle,addr.sockaddr_p(),addr.socklen_p());
     } catch (Exception & e) {
         e << "; could not get peer for address \"" << addr << "\"";
         throw;
@@ -52,7 +51,7 @@ peer(SocketHandle<SPolicy> handle, Address & addr,
 #else
 template <class Address>
 template <class SPolicy>
-prefix_ void senf::GenericAddressingPolicy<Address>::
+prefix_ void senf::BSDAddressingPolicyMixin<Address>::
 peer(SocketHandle<SPolicy> handle, Address & addr)
 {}
 #endif
@@ -60,12 +59,12 @@ peer(SocketHandle<SPolicy> handle, Address & addr)
 #ifndef DOXYGEN
 template <class Address>
 template <class SPolicy>
-prefix_ void senf::GenericAddressingPolicy<Address>::
+prefix_ void senf::BSDAddressingPolicyMixin<Address>::
 connect(SocketHandle<SPolicy> handle, Address const & addr,
         typename IfCommunicationPolicyIs<SPolicy,ConnectedCommunicationPolicy>::type *)
 {
     try {
-        do_connect(handle,addr.sockaddr_p(),addr.sockaddr_len());
+        do_connect(handle,addr.sockaddr_p(),addr.socklen());
     } catch (Exception & e) {
         e << "; could not connect to address \"" << addr << "\"";
         throw;
@@ -74,18 +73,17 @@ connect(SocketHandle<SPolicy> handle, Address const & addr,
 #else
 template <class Address>
 template <class SPolicy>
-prefix_ void senf::GenericAddressingPolicy<Address>::
+prefix_ void senf::BSDAddressingPolicyMixin<Address>::
 connect(SocketHandle<SPolicy> handle, Address const & addr)
 {}
 #endif
 
 template <class Address>
-prefix_ void senf::GenericAddressingPolicy<Address>::local(FileHandle handle,
+prefix_ void senf::BSDAddressingPolicyMixin<Address>::local(FileHandle handle,
                                                            Address & addr)
 {
-    addr.clear();
     try {
-        do_local(handle,addr.sockaddr_p(),addr.sockaddr_len());
+        do_local(handle,addr.sockaddr_p(),addr.socklen_p());
     } catch (Exception & e) {
         // TODO: identify socket by some meaningful attribute
         e << "; could not get name for address \"" << addr << "\"";
@@ -94,11 +92,11 @@ prefix_ void senf::GenericAddressingPolicy<Address>::local(FileHandle handle,
 }
 
 template <class Address>
-prefix_ void senf::GenericAddressingPolicy<Address>::bind(FileHandle handle,
+prefix_ void senf::BSDAddressingPolicyMixin<Address>::bind(FileHandle handle,
                                                                  Address const & addr)
 {
     try {
-        do_bind(handle,addr.sockaddr_p(),addr.sockaddr_len());
+        do_bind(handle,addr.sockaddr_p(),addr.socklen());
     } catch (Exception & e) {
         e << "; could not bind to address \"" << addr << "\"";
         throw;
similarity index 80%
rename from Socket/Protocols/GenericAddressingPolicy.hh
rename to Socket/Protocols/BSDAddressingPolicy.hh
index b1d2997..079a940 100644 (file)
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief GenericAddressingPolicy public header
+    \brief BSDAddressingPolicyMixin public header
  */
 
 /** \defgroup addr_group Addressing classes
  */
 
-#ifndef HH_GenericAddressingPolicy_
-#define HH_GenericAddressingPolicy_ 1
+#ifndef HH_BSDAddressingPolicyMixin_
+#define HH_BSDAddressingPolicyMixin_ 1
 
 // Custom includes
-#include "../../Socket/SocketHandle.hh"
-#include "../../Socket/FileHandle.hh"
-#include "../../Socket/SocketPolicy.hh"
-#include "../../Socket/CommunicationPolicy.hh"
+#include "../SocketHandle.hh"
+#include "../FileHandle.hh"
+#include "../SocketPolicy.hh"
+#include "../CommunicationPolicy.hh"
+#include "BSDSocketAddress.hh"
 
-//#include "GenericAddressingPolicy.mpp"
+//#include "BSDAddressingPolicy.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
 
 namespace senf {
@@ -44,16 +45,16 @@ namespace senf {
     /// \addtogroup policy_impl_group
     /// @{
 
-    /** \brief Non-template implementation class of GenericAddressingPolicy template
+    /** \brief Non-template implementation class of BSDAddressingPolicyMixin template
 
         \internal
      */
-    struct GenericAddressingPolicy_Base
+    struct BSDAddressingPolicyMixinBase
     {
-        static void do_local(FileHandle handle, struct sockaddr * addr, unsigned len);
-        static void do_peer(FileHandle handle, struct sockaddr * addr, unsigned len);
-        static void do_bind(FileHandle handle, struct sockaddr const * addr, unsigned len);
-        static void do_connect(FileHandle handle, struct sockaddr const * addr, unsigned len);
+        static void do_local(FileHandle handle, struct sockaddr * addr, socklen_t * len);
+        static void do_peer(FileHandle handle, struct sockaddr * addr, socklen_t * len);
+        static void do_bind(FileHandle handle, struct sockaddr const * addr, socklen_t len);
+        static void do_connect(FileHandle handle, struct sockaddr const * addr, socklen_t len);
     };
 
     /** \brief Template for generic AddressingPolicy implementation based on the BSD socket API
@@ -63,7 +64,7 @@ namespace senf {
         (connect/bind/getsockname/getpeername).
 
         The \a Address template parameter specifies the address type of the addressing policy. This
-        type must have two members: \c sockaddr_p() and \c sockaddr_len(). The first must return a
+        type must have two members: \c sockaddr_p() and \c socklen(). The first must return a
         <tt>struct sockaddr *</tt> to the address, the second must return the size of the address in
         bytes. The pointer returned by \c sockaddr_p() must be non-const if called on a non-const
         address. <em>The underlying socket address stored at that pointer might be
@@ -81,8 +82,8 @@ namespace senf {
         storage representation of the address.
      */
     template <class Address>
-    struct GenericAddressingPolicy
-        : private GenericAddressingPolicy_Base
+    struct BSDAddressingPolicyMixin
+        : private BSDAddressingPolicyMixinBase
     {
 #       ifndef DOXYGEN
         template <class SPolicy>
@@ -126,13 +127,25 @@ namespace senf {
 
     /// @}
 
+    struct BSDAddressingPolicy
+        : public AddressingPolicyBase,
+          private BSDAddressingPolicyMixin<GenericBSDSocketAddress>
+    {
+        typedef GenericBSDSocketAddress Address;
+
+        using BSDAddressingPolicyMixin<GenericBSDSocketAddress>::peer;
+        using BSDAddressingPolicyMixin<GenericBSDSocketAddress>::local;
+        using BSDAddressingPolicyMixin<GenericBSDSocketAddress>::connect;
+        using BSDAddressingPolicyMixin<GenericBSDSocketAddress>::bind;
+    };
+
 }
 
 ///////////////////////////////hh.e////////////////////////////////////////
-//#include "GenericAddressingPolicy.cci"
-//#include "GenericAddressingPolicy.ct"
-#include "GenericAddressingPolicy.cti"
-//#include "GenericAddressingPolicy.mpp"
+//#include "BSDAddressingPolicy.cci"
+//#include "BSDAddressingPolicy.ct"
+#include "BSDAddressingPolicy.cti"
+//#include "BSDAddressingPolicy.mpp"
 #endif
 
 \f
diff --git a/Socket/Protocols/BSDAddressingPolicy.test.cc b/Socket/Protocols/BSDAddressingPolicy.test.cc
new file mode 100644 (file)
index 0000000..0f7ef79
--- /dev/null
@@ -0,0 +1,60 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief BSDAddressingPolicy.test unit tests */
+
+//#include "BSDAddressingPolicy.test.hh"
+//#include "BSDAddressingPolicy.test.ih"
+
+// Custom includes
+#include "BSDAddressingPolicy.hh"
+#include "INet/TCPSocketHandle.hh"
+
+#include "../../Utils/auto_unit_test.hh"
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+BOOST_AUTO_UNIT_TEST(bsdAddressingPolicy)
+{
+    typedef senf::ClientSocketHandle<senf::MakeSocketPolicy<
+        senf::BSDAddressingPolicy>::policy> BSDHandle;
+
+    senf::TCPv4ClientSocketHandle tcph;
+    BOOST_CHECK_EQUAL( BSDHandle(tcph).local(), tcph.local() );
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/Socket/Protocols/BSDSocketAddress.cc b/Socket/Protocols/BSDSocketAddress.cc
new file mode 100644 (file)
index 0000000..b3a3635
--- /dev/null
@@ -0,0 +1,76 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief BSDSocketAddress non-inline non-template implementation */
+
+//#include "BSDSocketAddress.hh"
+//#include "BSDSocketAddress.ih"
+
+// Custom includes
+#include "INet/INetAddressing.hh"
+#include "UN/UNAddressing.hh"
+#include "Raw/LLAddressing.hh"
+
+//#include "BSDSocketAddress.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ std::ostream & senf::operator<<(std::ostream & os, BSDSocketAddress const & addr)
+{
+    switch(addr.family()) {
+    case INet4SocketAddress::addressFamily :
+        os << sockaddr_cast<INet4SocketAddress>(addr);
+        break;
+    case INet6SocketAddress::addressFamily :
+        os << sockaddr_cast<INet6SocketAddress>(addr);
+        break;
+    case UNSocketAddress::addressFamily :
+        os << sockaddr_cast<UNSocketAddress>(addr);
+        break;
+    case LLSocketAddress::addressFamily :
+        os << sockaddr_cast<LLSocketAddress>(addr);
+        break;
+    case AF_UNSPEC :
+        os << "[unspecified address]";
+        break;
+    default:
+        os << "[unknown address family " << addr.family() << "]";
+        break;
+    }
+    return os;
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "BSDSocketAddress.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/Socket/Protocols/BSDSocketAddress.cci b/Socket/Protocols/BSDSocketAddress.cci
new file mode 100644 (file)
index 0000000..30bb0e7
--- /dev/null
@@ -0,0 +1,208 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief BSDSocketAddress inline non-template implementation */
+
+//#include "BSDSocketAddress.ih"
+
+// Custom includes
+#include <memory.h>
+#include <algorithm>
+#include <typeinfo>
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::BSDSocketAddress
+
+prefix_ struct sockaddr const * senf::BSDSocketAddress::sockaddr_p()
+    const
+{
+    return static_cast<GenericBSDSocketAddress const *>(this)->sockaddr_p();
+}
+
+prefix_ short senf::BSDSocketAddress::family()
+    const
+{
+    return sockaddr_p()->sa_family;
+}
+
+prefix_ socklen_t senf::BSDSocketAddress::socklen()
+    const
+{
+    return len_;
+}
+
+prefix_ socklen_t const * senf::BSDSocketAddress::socklen_p()
+    const
+{
+    return & len_;
+}
+
+prefix_ void senf::BSDSocketAddress::socklen(socklen_t len)
+{
+    len_ = len;
+}
+
+prefix_ bool senf::BSDSocketAddress::operator==(BSDSocketAddress const & other)
+    const
+{
+    return socklen()==other.socklen() && memcmp(sockaddr_p(), other.sockaddr_p(), socklen())==0;
+}
+
+prefix_ bool senf::BSDSocketAddress::operator!=(BSDSocketAddress const & other)
+    const
+{
+    return ! operator==(other);
+}
+
+prefix_ bool senf::BSDSocketAddress::boolean_test()
+    const
+{
+    return socklen() > sizeof(short) && family() != AF_UNSPEC &&
+        unsigned(std::count(reinterpret_cast<unsigned char const *>(sockaddr_p())+sizeof(short),
+                            reinterpret_cast<unsigned char const *>(sockaddr_p())+socklen(),
+                   0u)) < socklen()-2;
+}
+
+////////////////////////////////////////
+// protected members
+
+prefix_ senf::BSDSocketAddress::BSDSocketAddress(socklen_t len, short family)
+    : len_ (len)
+{
+    ::memset(sockaddr_p(), 0u, len_);
+    sockaddr_p()->sa_family = family;
+}
+
+// WARNING: THIS COPY CONSTRUCTOR IS NOT GENERALLY SAFE !!!!!!
+// It is only safe if:
+// a) source and target class are identical derived classes (e.g. Both INet4)
+// b) target is GenericBSDSocketAddress (sockaddr_storage).
+//
+// In these cases, the storage space available for the target is at least as large as that
+// available for the source ant the copy is ok.
+//
+// To ensure this behavior, the copy constructor is protected here and is made accessible only
+// via the corresponding derived classes.
+//
+// The same holds for the copy-assignment operator
+prefix_ senf::BSDSocketAddress::BSDSocketAddress(BSDSocketAddress const & other)
+    : len_ (other.socklen())
+{
+    ::memcpy(sockaddr_p(), other.sockaddr_p(), len_);
+}
+
+prefix_ senf::BSDSocketAddress &
+senf::BSDSocketAddress::operator=(BSDSocketAddress const & other)
+{
+    len_ = other.socklen();
+    ::memcpy(sockaddr_p(), other.sockaddr_p(), len_);
+    return *this;
+}
+
+
+prefix_ struct sockaddr * senf::BSDSocketAddress::sockaddr_p()
+{
+    return static_cast<GenericBSDSocketAddress *>(this)->sockaddr_p();
+}
+
+prefix_ socklen_t * senf::BSDSocketAddress::socklen_p()
+{
+    return & len_;
+}
+
+////////////////////////////////////////
+// related
+
+template <class Target>
+prefix_ Target & senf::sockaddr_cast(BSDSocketAddress & source)
+{
+    if (source.family() != Target::addressFamily)
+        throw std::bad_cast();
+    return static_cast<Target &>(source);
+}
+
+template <class Target>
+prefix_ Target const & senf::sockaddr_cast(BSDSocketAddress const & source)
+{
+    if (source.family() != Target::addressFamily)
+        throw std::bad_cast();
+    return static_cast<Target const &>(source);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::GenericBSDSocketAddress
+
+prefix_ senf::GenericBSDSocketAddress::GenericBSDSocketAddress()
+    : BSDSocketAddress(sizeof(sockaddr_storage), AF_UNSPEC)
+{}
+
+prefix_ senf::GenericBSDSocketAddress::GenericBSDSocketAddress(BSDSocketAddress const & other)
+    : BSDSocketAddress(other)
+{}
+
+prefix_ senf::GenericBSDSocketAddress&
+senf::GenericBSDSocketAddress::operator=(const BSDSocketAddress & other)
+{
+    BSDSocketAddress::operator=(other);
+    return *this;
+}
+
+prefix_
+senf::GenericBSDSocketAddress::GenericBSDSocketAddress(const GenericBSDSocketAddress& other)
+    : BSDSocketAddress(other)
+{}
+
+prefix_ senf::GenericBSDSocketAddress&
+senf::GenericBSDSocketAddress::operator=(const GenericBSDSocketAddress& other)
+{
+    BSDSocketAddress::operator=(other);
+    return *this;
+}
+
+prefix_ struct sockaddr const * senf::GenericBSDSocketAddress::sockaddr_p()
+    const
+{
+    return reinterpret_cast<struct sockaddr const *>(& addr_);
+}
+
+prefix_ struct sockaddr * senf::GenericBSDSocketAddress::sockaddr_p()
+{
+    return reinterpret_cast<struct sockaddr *>(& addr_);
+}
+
+/////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/Socket/Protocols/BSDSocketAddress.hh b/Socket/Protocols/BSDSocketAddress.hh
new file mode 100644 (file)
index 0000000..6b2dfe2
--- /dev/null
@@ -0,0 +1,137 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief BSDSocketAddress public header */
+
+#ifndef HH_BSDSocketAddress_
+#define HH_BSDSocketAddress_ 1
+
+// Custom includes
+#include "../../Utils/safe_bool.hh"
+#include <sys/socket.h>
+#include <iostream>
+
+//#include "BSDSocketAddress.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+
+    /** \brief
+      */
+    class BSDSocketAddress
+        : public senf::comparable_safe_bool<BSDSocketAddress>
+    {
+    public:
+        
+        bool operator==(BSDSocketAddress const & other) const;
+        bool operator!=(BSDSocketAddress const & other) const;
+
+        bool boolean_test() const;
+        short family() const;
+
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Generic \c sockaddr interface
+        ///\{
+
+        struct sockaddr const * sockaddr_p() const;
+        socklen_t socklen() const;
+        socklen_t const * socklen_p() const;
+
+        ///\}
+
+    protected:
+        BSDSocketAddress(socklen_t len, short family);
+        BSDSocketAddress(BSDSocketAddress const & other);
+        BSDSocketAddress & operator=(BSDSocketAddress const & other);
+
+        struct sockaddr * sockaddr_p();
+        socklen_t * socklen_p();
+
+        void socklen(socklen_t len);
+
+    private:
+
+        socklen_t len_;
+    };
+
+    template <class Target>
+    Target & sockaddr_cast(BSDSocketAddress & source);
+
+    template <class Target>
+    Target const & sockaddr_cast(BSDSocketAddress const & source);
+
+    std::ostream & operator<<(std::ostream & os, BSDSocketAddress const & addr);
+
+    /** \brief
+      */
+    class GenericBSDSocketAddress
+        : public BSDSocketAddress
+    {
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Structors and default members
+        ///@{
+
+        GenericBSDSocketAddress();
+        GenericBSDSocketAddress(BSDSocketAddress const & other);
+        GenericBSDSocketAddress& operator=(const BSDSocketAddress & other);
+
+        GenericBSDSocketAddress(const GenericBSDSocketAddress& other);
+        GenericBSDSocketAddress& operator=(const GenericBSDSocketAddress& other);
+        
+        ///@}
+        ///////////////////////////////////////////////////////////////////////////
+        ///\name Generic \c sockaddr interface
+        ///\{
+
+        struct sockaddr const * sockaddr_p() const;
+        struct sockaddr * sockaddr_p();
+
+        using BSDSocketAddress::socklen_p;
+
+        ///\}
+
+    protected:
+
+    private:
+        struct sockaddr_storage addr_;
+    };
+
+}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "BSDSocketAddress.cci"
+//#include "BSDSocketAddress.ct"
+//#include "BSDSocketAddress.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/Socket/Protocols/BSDSocketAddress.test.cc b/Socket/Protocols/BSDSocketAddress.test.cc
new file mode 100644 (file)
index 0000000..774b945
--- /dev/null
@@ -0,0 +1,66 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief BSDSocketAddress.test unit tests */
+
+//#include "BSDSocketAddress.test.hh"
+//#include "BSDSocketAddress.test.ih"
+
+// Custom includes
+#include "BSDSocketAddress.hh"
+#include "INet/INetAddressing.hh"
+
+#include "../../Utils/auto_unit_test.hh"
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+BOOST_AUTO_UNIT_TEST(bsdSocketAddress)
+{
+    senf::GenericBSDSocketAddress g1;
+    senf::GenericBSDSocketAddress g2 (senf::INet4SocketAddress("1.2.3.4:5678"));
+
+    BOOST_CHECK_EQUAL( g2.family(), senf::INet4SocketAddress::addressFamily+0 );
+    BOOST_CHECK_EQUAL( senf::sockaddr_cast<senf::INet4SocketAddress>(g2).port(), 5678u );
+    BOOST_CHECK_THROW( senf::sockaddr_cast<senf::INet6SocketAddress>(g2), std::bad_cast );
+    BOOST_CHECK( g2 );
+    BOOST_CHECK( ! g1 );
+    BOOST_CHECK( g1 != g2 );
+    g1 = g2;
+    BOOST_CHECK( g1 == g2 );
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
index d3c4e36..ef448a8 100644 (file)
@@ -44,8 +44,8 @@
 // senf::INet4SocketAddress
 
 prefix_ senf::INet4SocketAddress::INet4SocketAddress(std::string const & addr)
+    : BSDSocketAddress (sizeof(sockaddr_in), AF_INET)
 {
-    clear();
     unsigned portIx = addr.find(':');
     try {
         port( boost::lexical_cast< ::u_int16_t >(portIx == std::string::npos 
@@ -59,32 +59,25 @@ prefix_ senf::INet4SocketAddress::INet4SocketAddress(std::string const & addr)
 }
 
 prefix_ senf::INet4SocketAddress::INet4SocketAddress(INet4Address const & addr, unsigned p)
+    : BSDSocketAddress (sizeof(sockaddr_in), AF_INET)
 {
-    clear();
     address(addr);
     port(p);
 }
 
 prefix_ senf::INet4SocketAddress::INet4SocketAddress(unsigned p)
+    : BSDSocketAddress (sizeof(sockaddr_in), AF_INET)
 {
-    clear();
     port(p);
 }
 
-prefix_ void senf::INet4SocketAddress::clear()
-{
-    ::memset(&addr_,0,sizeof(addr_));
-    addr_.sin_family = AF_INET;
-}
-
 ///////////////////////////////////////////////////////////////////////////
 // senf::INet6SocketAddress
 
 prefix_ senf::INet6SocketAddress::INet6SocketAddress(std::string const & addr,
                                                      INet6Address::Resolve_t resolve)
+    : BSDSocketAddress (sizeof(sockaddr_in6), AF_INET6)
 {
-    clear();
-
     // Format of addr: "[" address [ "%" interface ] "]" ":" port
     //             or: host ":" port
     //             or: port
@@ -113,20 +106,6 @@ prefix_ senf::INet6SocketAddress::INet6SocketAddress(std::string const & addr,
     }
 }
 
-prefix_ bool senf::INet6SocketAddress::operator==(INet6SocketAddress const & other)
-    const
-{
-    return ::memcmp(&sockaddr_.sin6_addr, &other.sockaddr_.sin6_addr, sizeof(sockaddr_.sin6_addr))==0 &&
-        sockaddr_.sin6_port == other.sockaddr_.sin6_port &&
-        sockaddr_.sin6_scope_id == other.sockaddr_.sin6_scope_id;
-}
-
-prefix_ void senf::INet6SocketAddress::clear()
-{
-    ::memset(&sockaddr_,0,sizeof(sockaddr_));
-    sockaddr_.sin6_family = AF_INET6;
-}
-
 prefix_ std::string senf::INet6SocketAddress::iface()
     const
 {
index 3687001..dc6bd0c 100644 (file)
 // senf::INet4Address
 
 prefix_ senf::INet4SocketAddress::INet4SocketAddress()
-{
-    clear();
-}
+    : BSDSocketAddress (sizeof(sockaddr_in), AF_INET)
+{}
 
-prefix_ bool senf::INet4SocketAddress::operator==(INet4SocketAddress const & other)
-    const
+prefix_ senf::INet4SocketAddress::INet4SocketAddress(const INet4SocketAddress& other)
+    : BSDSocketAddress(other)
+{}
+
+prefix_ senf::INet4SocketAddress&
+senf::INet4SocketAddress::operator=(const INet4SocketAddress& other)
 {
-    return addr_.sin_port == other.addr_.sin_port &&
-        addr_.sin_addr.s_addr == other.addr_.sin_addr.s_addr;
+    BSDSocketAddress::operator=(other);
+    return *this;
 }
 
 prefix_ senf::INet4Address senf::INet4SocketAddress::address()
@@ -57,12 +60,6 @@ prefix_ unsigned senf::INet4SocketAddress::port()
     return ntohs(addr_.sin_port);
 }
 
-prefix_ bool senf::INet4SocketAddress::boolean_test()
-    const
-{
-    return port() || address();
-}
-
 prefix_ void senf::INet4SocketAddress::address(INet4Address const & addr)
 {
     addr_.sin_addr.s_addr = addr.inaddr();
@@ -73,23 +70,6 @@ prefix_ void senf::INet4SocketAddress::port(unsigned p)
     addr_.sin_port = htons(p);
 }
 
-prefix_ struct sockaddr * senf::INet4SocketAddress::sockaddr_p()
-{
-    return reinterpret_cast<struct sockaddr *>(&addr_);
-}
-
-prefix_ struct sockaddr const * senf::INet4SocketAddress::sockaddr_p()
-    const
-{
-    return reinterpret_cast<struct sockaddr const *>(&addr_);
-}
-
-prefix_ unsigned senf::INet4SocketAddress::sockaddr_len()
-    const
-{
-    return sizeof(addr_);
-}
-
 prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4SocketAddress const & addr)
 {
     os << addr.address() << ":" << addr.port();
@@ -100,32 +80,42 @@ prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4SocketAddress co
 // senf::INet6SocketAddress
 
 prefix_ senf::INet6SocketAddress::INet6SocketAddress()
-{
-    clear();
-}
+    : BSDSocketAddress (sizeof(sockaddr_in6), AF_INET6)
+{}
 
 prefix_ senf::INet6SocketAddress::INet6SocketAddress(INet6Address const & addr, unsigned port)
+    : BSDSocketAddress (sizeof(sockaddr_in6), AF_INET6)
 {
-    clear();
     std::copy(addr.begin(), addr.end(), &sockaddr_.sin6_addr.s6_addr[0]);
     sockaddr_.sin6_port = htons(port);
 }
 
 prefix_ senf::INet6SocketAddress::INet6SocketAddress(INet6Address const & addr, unsigned port,
                                                      std::string const & iface)
+    : BSDSocketAddress (sizeof(sockaddr_in6), AF_INET6)
 {
-    clear();
     std::copy(addr.begin(), addr.end(), &sockaddr_.sin6_addr.s6_addr[0]);
     sockaddr_.sin6_port = htons(port);
     assignIface(iface);
 }
 
 prefix_ senf::INet6SocketAddress::INet6SocketAddress(unsigned port)
+    : BSDSocketAddress (sizeof(sockaddr_in6), AF_INET6)
 {
-    clear();
     sockaddr_.sin6_port = htons(port);
 }
 
+prefix_ senf::INet6SocketAddress::INet6SocketAddress(const INet6SocketAddress& other)
+    : BSDSocketAddress (other)
+{}
+
+prefix_ senf::INet6SocketAddress&
+senf::INet6SocketAddress::operator=(const INet6SocketAddress& other)
+{
+    BSDSocketAddress::operator=(other);
+    return *this;
+}
+
 prefix_ senf::INet6Address senf::INet6SocketAddress::address()
     const
 {
@@ -153,29 +143,6 @@ prefix_ void senf::INet6SocketAddress::iface(std::string const & iface)
     assignIface(iface);
 }
 
-prefix_ bool senf::INet6SocketAddress::boolean_test()
-    const
-{
-    return address() || port() || sockaddr_.sin6_scope_id;
-}
-
-prefix_ struct sockaddr * senf::INet6SocketAddress::sockaddr_p()
-{
-    return reinterpret_cast<struct sockaddr *>(&sockaddr_);
-}
-
-prefix_ struct sockaddr const * senf::INet6SocketAddress::sockaddr_p()
-    const
-{
-    return reinterpret_cast<struct sockaddr const *>(&sockaddr_);
-}
-
-prefix_ unsigned senf::INet6SocketAddress::sockaddr_len()
-    const
-{
-    return sizeof(sockaddr_);
-}
-
 prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6SocketAddress const & addr)
 {
     os << '[' << addr.address();
index 57efbe4..aeb76bd 100644 (file)
 #include <string>
 #include <exception>
 #include <netinet/in.h>
-#include <boost/operators.hpp>
-#include "../../../Socket/SocketPolicy.hh"
-#include "../../../Socket/ClientSocketHandle.hh"
-#include "../../../Socket/CommunicationPolicy.hh"
-#include "../../../Socket/Protocols/GenericAddressingPolicy.hh"
-#include "../../../Utils/safe_bool.hh"
+#include "../../SocketPolicy.hh"
+#include "../../ClientSocketHandle.hh"
+#include "../../CommunicationPolicy.hh"
+#include "../BSDAddressingPolicy.hh"
+#include "../BSDSocketAddress.hh"
 #include "INet4Address.hh"
 #include "INet6Address.hh"
 
@@ -56,10 +55,11 @@ namespace senf {
         \ingroup addr_group
      */
     class INet4SocketAddress
-        : public boost::equality_comparable<INet4SocketAddress>, 
-          public senf::comparable_safe_bool<INet4SocketAddress>
+        : public BSDSocketAddress
     {
     public:
+        static short const addressFamily = AF_INET;
+
         ///////////////////////////////////////////////////////////////////////////
         ///\name Structors and default members
         ///@{
@@ -85,30 +85,20 @@ namespace senf {
                                         ///< Set port, address is set to 0.0.0.0
                                         /**< \param[in] port port number */
 
+        INet4SocketAddress(const INet4SocketAddress& other);
+        INet4SocketAddress& operator=(const INet4SocketAddress& other);
+
         ///@}
         ///////////////////////////////////////////////////////////////////////////
 
-        bool operator==(INet4SocketAddress const & other) const;
-                                        ///< Check INet4SocketAddress for equality
-
         INet4Address address() const;   ///< Return address
         unsigned port() const;          ///< Return port number
 
-        bool boolean_test() const;      ///< \c true, if address is not empty (i.e. 0.0.0.0:0)
-
-        void clear();                   ///< Clear address/port to 0.0.0.0:0
-
         void address(INet4Address const & addr); ///< Set address
         void port(unsigned p);          ///< Set port number
 
-        /// \name Generic Address Interface
-        /// @{
-
-        struct sockaddr * sockaddr_p();
-        struct sockaddr const * sockaddr_p() const;
-        unsigned sockaddr_len() const;
-
-        /// @}
+        using BSDSocketAddress::sockaddr_p;
+        using BSDSocketAddress::socklen_p;
 
     private:
         struct ::sockaddr_in addr_;
@@ -152,10 +142,11 @@ namespace senf {
         \ingroup addr_group
      */
     class INet6SocketAddress
-        : public boost::equality_comparable<INet6SocketAddress>, 
-          public senf::comparable_safe_bool<INet6SocketAddress>
+        : public BSDSocketAddress
     {
     public:
+        static short const addressFamily = AF_INET6;
+
         ///////////////////////////////////////////////////////////////////////////
         ///\name Structors and default members
         ///@{
@@ -181,15 +172,13 @@ namespace senf {
                                         /**< The address is set to [::]
                                              \param[in] port port number  */
 
+        INet6SocketAddress(const INet6SocketAddress& other);
+        INet6SocketAddress& operator=(const INet6SocketAddress& other);
+
         ///@}
         ///////////////////////////////////////////////////////////////////////////
 
-        bool operator==(INet6SocketAddress const & other) const; ///< Check addresses for equality
-
-        void clear();                   ///< Clear socket address
-
         INet6Address address() const;    ///< Get printable address representation
-
         void address(INet6Address const & addr); ///< Change address
 
         unsigned port() const;          ///< Get port number
@@ -198,16 +187,8 @@ namespace senf {
         std::string iface() const;      ///< Get interface name
         void iface(std::string const & iface); ///< Change interface
 
-        bool boolean_test() const;      ///< \c true, if address is not empty (i.e. [::]:0)
-
-        ///\name Generic SocketAddress interface
-        ///@{
-
-        struct sockaddr * sockaddr_p();
-        struct sockaddr const * sockaddr_p() const;
-        unsigned sockaddr_len() const;
-
-        ///@}
+        using BSDSocketAddress::sockaddr_p;
+        using BSDSocketAddress::socklen_p;
 
     protected:
 
@@ -234,19 +215,19 @@ namespace senf {
         addresses.
 
         The various members are directly imported from
-        GenericAddressingPolicy which see for a detailed
+        BSDAddressingPolicyMixin which see for a detailed
         documentation.
      */
     struct INet4AddressingPolicy
-        : public AddressingPolicyBase,
-          private GenericAddressingPolicy<INet4SocketAddress>
+        : public BSDAddressingPolicy,
+          private BSDAddressingPolicyMixin<INet4SocketAddress>
     {
         typedef INet4SocketAddress Address;
 
-        using GenericAddressingPolicy<INet4SocketAddress>::peer;
-        using GenericAddressingPolicy<INet4SocketAddress>::local;
-        using GenericAddressingPolicy<INet4SocketAddress>::connect;
-        using GenericAddressingPolicy<INet4SocketAddress>::bind;
+        using BSDAddressingPolicyMixin<INet4SocketAddress>::peer;
+        using BSDAddressingPolicyMixin<INet4SocketAddress>::local;
+        using BSDAddressingPolicyMixin<INet4SocketAddress>::connect;
+        using BSDAddressingPolicyMixin<INet4SocketAddress>::bind;
     };
 
     /** \brief Addressing policy supporting IPv6 addressing
@@ -258,19 +239,19 @@ namespace senf {
         addresses.
 
         The various members are directly imported from
-        GenericAddressingPolicy which see for a detailed
+        BSDAddressingPolicyMixin which see for a detailed
         documentation.
      */
     struct INet6AddressingPolicy
-        : public AddressingPolicyBase,
-          private GenericAddressingPolicy<INet6SocketAddress>
+        : public BSDAddressingPolicy,
+          private BSDAddressingPolicyMixin<INet6SocketAddress>
     {
         typedef INet6SocketAddress Address;
 
-        using GenericAddressingPolicy<INet6SocketAddress>::peer;
-        using GenericAddressingPolicy<INet6SocketAddress>::local;
-        using GenericAddressingPolicy<INet6SocketAddress>::connect;
-        using GenericAddressingPolicy<INet6SocketAddress>::bind;
+        using BSDAddressingPolicyMixin<INet6SocketAddress>::peer;
+        using BSDAddressingPolicyMixin<INet6SocketAddress>::local;
+        using BSDAddressingPolicyMixin<INet6SocketAddress>::connect;
+        using BSDAddressingPolicyMixin<INet6SocketAddress>::bind;
     };
 
     /// @}
index dc04dea..411e7b9 100644 (file)
 #define prefix_ inline
 ///////////////////////////////cci.p///////////////////////////////////////
 
-prefix_ void senf::LLSocketAddress::clear()
-{
-    ::memset(&addr_,0,sizeof(addr_));
-    addr_.sll_family = AF_PACKET;
-}
-
 prefix_ void senf::LLSocketAddress::address(MACAddress const & addr)
 {
     std::copy(addr.begin(), addr.end(),&addr_.sll_addr[0]);
 }
 
 prefix_ senf::LLSocketAddress::LLSocketAddress()
-{
-    clear();
-}
+    : BSDSocketAddress (sizeof(sockaddr_ll), AF_PACKET)
+{}
 
 prefix_ void senf::LLSocketAddress::protocol(unsigned prot)
 {
@@ -53,26 +46,36 @@ prefix_ void senf::LLSocketAddress::protocol(unsigned prot)
 }
 
 prefix_ senf::LLSocketAddress::LLSocketAddress(unsigned prot, std::string const & iface)
+    : BSDSocketAddress (sizeof(sockaddr_ll), AF_PACKET)
 {
-    clear();
     protocol(prot);
     interface(iface);
 }
 
 prefix_ senf::LLSocketAddress::LLSocketAddress(std::string const &iface)
+    : BSDSocketAddress (sizeof(sockaddr_ll), AF_PACKET)
 {
-    clear();
     interface(iface);
 }
 
 prefix_ senf::LLSocketAddress::LLSocketAddress(MACAddress const & addr,
                                                std::string const & iface)
+    : BSDSocketAddress (sizeof(sockaddr_ll), AF_PACKET)
 {
-    clear();
     address(addr);
     interface(iface);
 }
 
+prefix_ senf::LLSocketAddress::LLSocketAddress(const LLSocketAddress& other)
+    : BSDSocketAddress (other)
+{}
+
+prefix_ senf::LLSocketAddress& senf::LLSocketAddress::operator=(const LLSocketAddress& other)
+{
+    BSDSocketAddress::operator=(other);
+    return *this;
+}
+
 prefix_ unsigned senf::LLSocketAddress::protocol()
     const
 {
@@ -97,23 +100,6 @@ prefix_ senf::MACAddress senf::LLSocketAddress::address()
     return MACAddress::from_data(&addr_.sll_addr[0]);
 }
 
-prefix_ struct sockaddr * senf::LLSocketAddress::sockaddr_p()
-{
-    return reinterpret_cast<struct sockaddr *>(&addr_);
-}
-
-prefix_ struct sockaddr const * senf::LLSocketAddress::sockaddr_p()
-    const
-{
-    return reinterpret_cast<struct sockaddr const *>(&addr_);
-}
-
-prefix_ unsigned senf::LLSocketAddress::sockaddr_len()
-    const
-{
-    return sizeof(addr_);
-}
-
 prefix_ std::ostream & senf::operator<<(std::ostream & os, LLSocketAddress const & llAddr)
 {
     // TODO: expose more bytes from sockaddr_ll addr_
index bd82689..7c9591d 100644 (file)
 // Custom includes
 #include <sys/socket.h>
 #include <netpacket/packet.h>
-#include "../../../Socket/SocketPolicy.hh"
-#include "../../../Socket/FileHandle.hh"
-#include "../../../Socket/Protocols/GenericAddressingPolicy.hh"
+#include "../../SocketPolicy.hh"
+#include "../../FileHandle.hh"
+#include "../BSDAddressingPolicy.hh"
+#include "../BSDSocketAddress.hh"
 #include "MACAddress.hh"
 
 //#include "LLAddressing.mpp"
@@ -54,8 +55,11 @@ namespace senf {
         \nosubgrouping
      */
     class LLSocketAddress
+        : public BSDSocketAddress
     {
     public:
+        static short const addressFamily = AF_PACKET;
+
         /** \brief Valid pkttype() values
 
             These are the possible values returned by pkttype() 
@@ -95,16 +99,18 @@ namespace senf {
                                              \param addr Address to send data to
                                              \param iface Interface to send packet from */
 
+        LLSocketAddress(const LLSocketAddress& other);
+        LLSocketAddress& operator=(const LLSocketAddress& other);
+
         ///@}
         ///////////////////////////////////////////////////////////////////////////
 
-        void clear();                   ///< Clear the address
-
-        unsigned protocol() const;      ///< Return address protocol (ethertype)
+        MACAddress address() const;     ///< Return address
         std::string interface() const;  ///< Return interface name
+        unsigned protocol() const;      ///< Return address protocol (ethertype)
+
         unsigned arptype() const;       ///< Return the hatype field (ARP hardware type)
         PktType pkttype() const;        ///< Return type of packet
-        MACAddress address() const;     ///< Return address
 
         // The mutating interface is purposely restricted to allow only
         // changing those members, which are sensible to be changed.
@@ -113,14 +119,8 @@ namespace senf {
         void interface(std::string const & iface); ///< Change interface
         void protocol(unsigned prot);   ///< Change protocol
 
-        ///\name Generic SocketAddress interface
-        ///@{
-
-        struct sockaddr * sockaddr_p();
-        struct sockaddr const * sockaddr_p() const;
-        unsigned sockaddr_len() const;
-
-        ///@}
+        using BSDSocketAddress::sockaddr_p;
+        using BSDSocketAddress::socklen_p;
 
     private:
         struct ::sockaddr_ll addr_;
@@ -146,12 +146,12 @@ namespace senf {
      */
     struct LLAddressingPolicy
         : public AddressingPolicyBase,
-          private GenericAddressingPolicy<LLSocketAddress>
+          private BSDAddressingPolicyMixin<LLSocketAddress>
     {
         typedef LLSocketAddress Address;
 
-        using GenericAddressingPolicy<LLSocketAddress>::local;
-        using GenericAddressingPolicy<LLSocketAddress>::bind;
+        using BSDAddressingPolicyMixin<LLSocketAddress>::local;
+        using BSDAddressingPolicyMixin<LLSocketAddress>::bind;
     };
 
     /// @}
index 8eab74b..59c5cfa 100644 (file)
 //#include "UNAddressing.ih"
 
 // Custom includes
-
+#include "../AddressExceptions.hh"
 
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
-prefix_ senf::UNSocketAddress::UNSocketAddress()
-{}
-
-prefix_ senf::UNSocketAddress::UNSocketAddress(std::string const & path)
-{
-    clear();
-    ::strncpy(addr_.sun_path, path.c_str(), sizeof(addr_.sun_path));
-    addr_.sun_path[sizeof(addr_.sun_path)-1] = 0;
-}
-
-prefix_ bool senf::UNSocketAddress::operator==(UNSocketAddress const & other)
-    const
-{
-    return path() == other.path();
-}
-
-prefix_ std::string senf::UNSocketAddress::path()
-    const
-{
-    return std::string(addr_.sun_path);
-}
-
-prefix_ bool senf::UNSocketAddress::boolean_test()
-    const
-{
-    return addr_.sun_path[0] != 0;
-}
-
-prefix_ void senf::UNSocketAddress::clear()
-{
-    ::memset(&addr_, 0, sizeof(addr_));
-    addr_.sun_family = AF_UNIX;
-}
-
-prefix_ sockaddr * senf::UNSocketAddress::sockaddr_p()
-{
-    return reinterpret_cast <struct sockaddr  *> (&addr_); 
-}
-
-prefix_ sockaddr const * senf::UNSocketAddress::sockaddr_p()
-    const
-{
-    return reinterpret_cast <struct sockaddr const  *> (&addr_); 
-}
-
-prefix_ unsigned senf::UNSocketAddress::sockaddr_len()
-    const
-{
-    return sizeof(addr_);
-}
-
-prefix_ std::ostream & senf::operator<<(std::ostream & os,
-                                  senf::UNSocketAddress::UNSocketAddress const & addr)
+prefix_ void senf::UNSocketAddress::path(std::string const & path)
 {
-    os << addr.path();
-    return os;
+    if (path.size() > sizeof(sockaddr_un)-sizeof(short)-1)
+        throw AddressSyntaxException();
+    socklen(path.size()+sizeof(short));
+    memcpy(addr_.sun_path, path.c_str(), socklen()-sizeof(short));
+    addr_.sun_path[socklen()-sizeof(short)+1] = 0;
 }
 
 ///////////////////////////////cc.e////////////////////////////////////////
diff --git a/Socket/Protocols/UN/UNAddressing.cci b/Socket/Protocols/UN/UNAddressing.cci
new file mode 100644 (file)
index 0000000..e66fa88
--- /dev/null
@@ -0,0 +1,81 @@
+// $Id$
+//
+// Copyright (C) 2008 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief UNAddressing inline non-template implementation */
+
+//#include "UNAddressing.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::UNSocketAddress
+
+prefix_ senf::UNSocketAddress::UNSocketAddress()
+    : BSDSocketAddress (sizeof(sockaddr_un), AF_UNIX)
+{}
+
+prefix_ senf::UNSocketAddress::UNSocketAddress(std::string const & p)
+    : BSDSocketAddress (sizeof(sockaddr_un), AF_UNIX)
+{
+    path(p);
+}
+
+prefix_ senf::UNSocketAddress::UNSocketAddress(const UNSocketAddress& other)
+    : BSDSocketAddress (other)
+{}
+
+prefix_ senf::UNSocketAddress& senf::UNSocketAddress::operator=(const UNSocketAddress& other)
+{
+    BSDSocketAddress::operator=(other);
+    return *this;
+}
+
+prefix_ std::string senf::UNSocketAddress::path()
+    const
+{
+    return std::string(addr_.sun_path, socklen()-sizeof(short));
+}
+
+prefix_ std::ostream & senf::operator<<(std::ostream & os,
+                                  senf::UNSocketAddress::UNSocketAddress const & addr)
+{
+    os << addr.path();
+    return os;
+}
+
+///////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
index c3d56bb..b08b6e3 100644 (file)
@@ -31,8 +31,8 @@
 #include <string>
 #include <sys/socket.h>
 #include <sys/un.h>
-#include "../../../Socket/Protocols/GenericAddressingPolicy.hh"
-#include "../../../Utils/safe_bool.hh"
+#include "../BSDAddressingPolicy.hh"
+#include "../BSDSocketAddress.hh"
 
 //#include "UNAddressing.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
@@ -49,25 +49,24 @@ namespace senf {
         \ingroup addr_group
      */
     class UNSocketAddress
-        : public comparable_safe_bool<UNSocketAddress>
+        : public BSDSocketAddress
     {
     public:
+        static short const addressFamily = AF_UNIX;
+        
         UNSocketAddress(); 
+
         explicit UNSocketAddress(std::string const & path);
                                         ///< Construct an address constant from given path
 
-        bool operator==(UNSocketAddress const & other) const;
-                                        ///< Compare UNSocketAddress for equality
+        UNSocketAddress(const UNSocketAddress& other);
+        UNSocketAddress& operator=(const UNSocketAddress& other);
 
         std::string path() const ;      ///< Return path as string
+        void path(std::string const & path);
 
-        bool boolean_test() const;      ///< \c true, if address is not empty
-        
-        void clear();                   ///< Clear address
-
-        struct sockaddr * sockaddr_p() ;
-        struct sockaddr const * sockaddr_p() const;
-        unsigned sockaddr_len() const;
+        using BSDSocketAddress::sockaddr_p;
+        using BSDSocketAddress::socklen_p;
 
     private:
         struct sockaddr_un addr_;
@@ -91,26 +90,26 @@ namespace senf {
         addresses.
 
         The various members are directly imported from
-        GenericAddressingPolicy which see for a detailed
+        BSDAddressingPolicyMixin which see for a detailed
         documentation.
      */
     struct UNAddressingPolicy
-        : public AddressingPolicyBase,
-          private GenericAddressingPolicy<UNSocketAddress>
+        : public BSDAddressingPolicy,
+          private BSDAddressingPolicyMixin<UNSocketAddress>
     {
         typedef UNSocketAddress Address;
 
-        using GenericAddressingPolicy<UNSocketAddress>::peer;
-        using GenericAddressingPolicy<UNSocketAddress>::local;
-        using GenericAddressingPolicy<UNSocketAddress>::connect;
-        using GenericAddressingPolicy<UNSocketAddress>::bind;
+        using BSDAddressingPolicyMixin<UNSocketAddress>::peer;
+        using BSDAddressingPolicyMixin<UNSocketAddress>::local;
+        using BSDAddressingPolicyMixin<UNSocketAddress>::connect;
+        using BSDAddressingPolicyMixin<UNSocketAddress>::bind;
     };
 
     ///@}
 }
 
 ///////////////////////////////hh.e////////////////////////////////////////
-//#include "UNAddressing.cci"
+#include "UNAddressing.cci"
 //#include "UNAddressing.ct"
 //#include "UNAddressing.cti"
 #endif
index 3f6f015..5863d4b 100644 (file)
@@ -44,7 +44,7 @@ BOOST_AUTO_UNIT_TEST(unSocketAddress)
 //    std::string testS = "/tmp/senfTestSocket";
 //    senf::UNSocketAddress addr (testS) ; 
 //    int mySock = socket(AF_UNIX, SOCK_DGRAM, 0); 
-//    if (bind(mySock, addr.sockaddr_p(), addr.sockaddr_len())) { 
+//    if (bind(mySock, addr.sockaddr_p(), addr.socklen())) { 
 //        std::cout << "Error while binding name to unix socket" << std::endl;
 //    }
 
diff --git a/Socket/Protocols/main.test.cc b/Socket/Protocols/main.test.cc
new file mode 100644 (file)
index 0000000..c6b4f24
--- /dev/null
@@ -0,0 +1,49 @@
+// $Id$
+//
+// Copyright (C) 2006
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+// Definition of non-inline non-template functions
+
+//#include "test.hh"
+//#include "test.ih"
+
+// Custom includes
+#define BOOST_AUTO_TEST_MAIN
+#include "../../Utils/auto_unit_test.hh"
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
+// End:
index 36e2f52..618c2d3 100644 (file)
@@ -38,7 +38,7 @@ readfrom(ClientSocketHandle<SPolicy> handle, char * buffer, unsigned size,
          typename SPolicy::AddressingPolicy::Address & address,
          typename IfCommunicationPolicyIs<SPolicy,UnconnectedCommunicationPolicy>::type *)
 {
-    return do_readfrom(handle, buffer, size, address.sockaddr_p(), address.sockaddr_len());
+    return do_readfrom(handle, buffer, size, address.sockaddr_p(), address.socklen());
 }
 #else
 template <class SPolicy>
@@ -71,7 +71,7 @@ writeto(ClientSocketHandle<SPolicy> handle,
         char const * buffer, unsigned size,
         typename IfCommunicationPolicyIs<SPolicy,UnconnectedCommunicationPolicy>::type *)
 {
-    return do_writeto(handle, buffer, size, addr.sockaddr_p(), addr.sockaddr_len());
+    return do_writeto(handle, buffer, size, addr.sockaddr_p(), addr.socklen());
 }
 #else
 template <class SPolicy>