Fix BUG items
g0dil [Tue, 22 May 2007 08:16:26 +0000 (08:16 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@245 270642c3-0616-0410-b53a-bc976706d245

Socket/BSDSocketProtocol.cc
Socket/BSDSocketProtocol.hh
Socket/PacketSocketHandle.cc
Socket/PacketSocketHandle.hh
Socket/PacketSocketHandle.test.cc
Socket/ReadWritePolicy.cc
Socket/ReadWritePolicy.hh
Socket/TCPSocketHandle.test.cc
Socket/UDPSocketHandle.test.cc [new file with mode: 0644]
senfscons/xrefhtml.xslt

index 20afd8a..07201cf 100644 (file)
@@ -60,11 +60,6 @@ prefix_ void senf::BSDSocketProtocol::linger(bool enable, unsigned timeout)
 prefix_ struct timeval senf::BSDSocketProtocol::timestamp()
     const
 {
-    /** \bug Check, why this fails with ENOFILE (!!!!) at least when
-        called from a tcp socket.Maybe this is only available for
-        datagram sockets ? That could make sense from the description
-        (what is the last packet passed to the user on a stream
-        socket?)  Further investigation necessary ... */
     struct timeval tv;
     if (::ioctl(body().fd(), SIOCGSTAMP, &tv) < 0)
         throw SystemException(errno);
index bfdef2b..63c8d42 100644 (file)
@@ -65,7 +65,8 @@ namespace senf {
                                              the last network packet passed to the user has been
                                              received from the network. This allows precise network
                                              timing.
-                                             \returns timestamp when packet was received */
+                                             \returns timestamp when packet was received 
+                                             \todo Move this to DatagramSocketProtocol class */
     };
 
     /** \brief Protocol facet providing basic connection oriented BSD socket functions
index 007a1a3..f3234ac 100644 (file)
@@ -77,33 +77,6 @@ prefix_ bool senf::PacketProtocol::eof()
     return false;
 }
 
-prefix_ void senf::PacketProtocol::promisc(std::string interface, PromiscMode mode)
-    const
-{
-    /** \bug There are some failures here ... need to investigate */
-
-    // The interface is really stupid: as far as i understand, it is possible to
-    // enable PROMISC and ALLMULTI seperately, however PROMISC is really a superset
-    // of ALLMULTI ... grmpf ... therefore we allways set/reset both to implement sane
-    // semantics
-
-    struct packet_mreq mreq;
-    mreq.mr_ifindex = ::if_nametoindex(interface.c_str());
-    if (mreq.mr_ifindex == 0)
-        throw SystemException(EINVAL);
-    mreq.mr_alen = 0;
-
-    mreq.mr_type = PACKET_MR_PROMISC;
-    int command = mode == Promiscuous ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP;
-    if (::setsockopt(body().fd(),SOL_PACKET,command,&mreq,sizeof(mreq)) < 0)
-        throw SystemException(errno);
-
-    mreq.mr_type = PACKET_MR_ALLMULTI;
-    command = mode == AllMulticast ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP;
-    if (::setsockopt(body().fd(),SOL_PACKET,command,&mreq,sizeof(mreq)) < 0)
-        throw SystemException(errno);
-}
-
 prefix_ void senf::PacketProtocol::do_mc_i(std::string interface,
                                                   detail::LLAddressCopier const & copier, bool add)
     const
index 1acde96..5eb3719 100644 (file)
@@ -22,6 +22,8 @@
 
 /** \file
     \brief PacketProtocol and PacketSocketHandle public header
+
+    \todo Implement global promisc() helper based on ioctl() interface.
  */
 
 #ifndef HH_PacketSocketHandle_
@@ -83,8 +85,6 @@ namespace senf {
     public:
         enum SocketType { RawSocket, DatagramSocket };
                                         ///< Socket types
-        enum PromiscMode { Promiscuous, AllMulticast, None };
-                                        ///< Interface modes
 
         ///\name Constructors
         ///@{
@@ -112,23 +112,6 @@ namespace senf {
 
         ///\name Protocol Interface
         ///@{
-        void promisc(std::string interface, PromiscMode mode) const;
-                                        ///< Change interface mode
-                                        /**< This member will change the reception on the given
-                                             interface. The modes available are
-
-                                             <dl>
-                                             <dt><em>None</em></dt><dd>No special mode set. Only receive
-                                             packets addressed to the interface or of joined
-                                             multicast groups</dd>
-                                             <dt><em>AllMulticast</em></dt><dd>Additionally receive all
-                                             multicast traffic</dd>
-                                             <dt><em> Promiscuous</em></dt><dd>Receive all packets on the
-                                             wire</dd>
-                                             </dl>
-
-                                             \param[in] interface interface to modify
-                                             \param[in] mode new interface mode */
 
         // See LLSocketAddress for a discussion/rationale for ForwardRange here
         template <class ForwardRange>
index 769b3d7..9b731f5 100644 (file)
@@ -48,26 +48,17 @@ BOOST_AUTO_UNIT_TEST(packetSocketHandle)
     {
         senf::PacketSocketHandle sock;
 
-        BOOST_CHECK_NO_THROW( sock.bind(senf::LLSocketAddress("lo")) );
+        BOOST_CHECK_NO_THROW( sock.bind(senf::LLSocketAddress("eth0")) );
         senf::LLSocketAddress a;
         BOOST_CHECK_NO_THROW( sock.local(a) );
-        BOOST_CHECK_EQUAL( a.interface(), "lo" );
+        BOOST_CHECK_EQUAL( a.interface(), "eth0" );
 
         // How am I supposed to test read and write .. grmpf ..
 
-        /*
-        BOOST_CHECK_NO_THROW( sock.protocol().promisc(
-                                  "lo",senf::PacketProtocol::Promiscuous) );
-        BOOST_CHECK_NO_THROW( sock.protocol().promisc(
-                                  "lo",senf::PacketProtocol::AllMulticast) );
-        BOOST_CHECK_NO_THROW( sock.protocol().promisc(
-                                  "lo",senf::PacketProtocol::None) );
-        */
-
         BOOST_CHECK_NO_THROW( sock.protocol().mcAdd(
-                                  "lo",senf::llAddress("01-02-03-04-05-06")) );
+                                  "eth0",senf::llAddress("01-02-03-04-05-06")) );
         BOOST_CHECK_NO_THROW( sock.protocol().mcDrop(
-                                  "lo",senf::llAddress("01-02-03-04-05-06")) );
+                                  "eth0",senf::llAddress("01-02-03-04-05-06")) );
 
         BOOST_CHECK_NO_THROW( sock.protocol().available() );
         BOOST_CHECK( ! sock.eof() );
index 8d55091..ed753ee 100644 (file)
@@ -102,7 +102,7 @@ prefix_ unsigned senf::WriteablePolicy::do_write(FileHandle handle, char const *
 
 prefix_ unsigned senf::WriteablePolicy::do_writeto(FileHandle handle,
                                                           char const * buffer, unsigned size,
-                                                          struct sockaddr * addr, socklen_t len)
+                                                          struct sockaddr const * addr, socklen_t len)
 {
     int rv = -1;
     do {
index 552b873..3cb6495 100644 (file)
@@ -123,7 +123,7 @@ namespace senf {
     private:
         static unsigned do_write(FileHandle handle, char const * buffer, unsigned size);
         static unsigned do_writeto(FileHandle handle, char const * buffer, unsigned size,
-                                   struct sockaddr * addr, socklen_t len);
+                                   struct sockaddr const * addr, socklen_t len);
     };
 
     /** \brief WritePolicy for unwriteable sockets
index 85a0e95..7faefa4 100644 (file)
@@ -175,8 +175,6 @@ BOOST_AUTO_UNIT_TEST(tcpv4ClientSocketHandle)
         BOOST_CHECK_EQUAL( sock.sndbuf(), 2048u );
         BOOST_CHECK_NO_THROW( sock.write("TEST-WRITE") );
         BOOST_CHECK_EQUAL( sock.read(), "TEST-WRITE" );
-        // this fails with ENOFILE ... why ????
-        // BOOST_CHECK_NO_THROW( sock.protocol().timestamp() );
         BOOST_CHECK( !sock.eof() );
         sock.write("QUIT");
         sleep(1);
diff --git a/Socket/UDPSocketHandle.test.cc b/Socket/UDPSocketHandle.test.cc
new file mode 100644 (file)
index 0000000..3102685
--- /dev/null
@@ -0,0 +1,178 @@
+// Copyright (C) 2007 
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+//     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 UDPSocketHandle.test unit tests */
+
+//#include "UDPSocketHandle.test.hh"
+//#include "UDPSocketHandle.test.ih"
+
+// Custom includes
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include "UDPSocketHandle.hh"
+#include <iostream>
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+
+    void error(char const * fn, char const * proc="")
+    {
+        std::cerr << "\n" << proc << ((*proc)?": ":"") << fn << ": " << strerror(errno) << std::endl;
+    }
+
+    void fail(char const * proc, char const * fn)
+    {
+        error(fn,proc);
+        _exit(1);
+    }
+
+    int server_pid = 0;
+
+    void start(void (*fn)())
+    {
+        server_pid = ::fork();
+        if (server_pid < 0) BOOST_FAIL("fork()");
+        if (server_pid == 0) {
+            (*fn)();
+            _exit(0);
+        }
+    }
+
+    void wait()
+    {
+        int status;
+        if (waitpid(server_pid,&status,0)<0)
+            BOOST_FAIL("waitpid()");
+        BOOST_CHECK_EQUAL( status , 0 );
+    }
+
+    void stop()
+    {
+        if (server_pid) {
+            kill(server_pid,9);
+            wait();
+            server_pid = 0;
+        }
+    }
+
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+    void server_v4()
+    {
+        int sock = socket(PF_INET,SOCK_DGRAM,0);
+        if (sock<0) fail("server_v4","socket()");
+        struct sockaddr_in sin;
+        ::memset(&sin,0,sizeof(sin));
+        sin.sin_family = AF_INET;
+        sin.sin_port = htons(12345);
+        sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+        if (bind(sock,(struct sockaddr *)&sin,sizeof(sin))<0) fail("server_v4","bind()");
+
+        sin.sin_port = htons(23456);
+        char buffer[1024];
+        while (1) {
+            int n = read(sock,buffer,1024);
+            if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
+                break;
+            sendto(sock,buffer,n,0,(struct sockaddr *)&sin,sizeof(sin));
+        }
+
+        if (close(sock) < 0) fail("server_v4","close()");
+    }
+
+    void server_v6()
+    {
+        int sock = socket(PF_INET6,SOCK_DGRAM,0);
+        if (sock<0) fail("server_v6","socket()");
+        struct sockaddr_in6 sin;
+        ::memset(&sin,0,sizeof(sin));
+        sin.sin6_family = AF_INET6;
+        sin.sin6_port = htons(12345);
+        sin.sin6_addr = in6addr_loopback;
+        if (bind(sock,(struct sockaddr *)&sin,sizeof(sin))<0) fail("server_v6","bind()");
+
+        sin.sin6_port = htons(23456);
+        char buffer[1024];
+        while (1) {
+            int n = read(sock,buffer,1024);
+            if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
+                break;
+            sendto(sock,buffer,n,0,(struct sockaddr *)&sin,sizeof(sin));
+        }
+
+        if (close(sock) < 0) fail("server_v6","close()");
+    }
+
+}
+
+BOOST_AUTO_UNIT_TEST(udpv4ClientSocketHandle)
+{
+    try {
+        alarm(10);
+        start(server_v4);
+        senf::UDPv4ClientSocketHandle sock;
+        BOOST_CHECK_NO_THROW( sock.bind("127.0.0.1:23456") );
+        BOOST_CHECK( sock.local() == "127.0.0.1:23456" );
+        BOOST_CHECK_NO_THROW( sock.rcvbuf(2048) );
+        BOOST_CHECK_EQUAL( sock.rcvbuf(), 2048u );
+        BOOST_CHECK_NO_THROW( sock.sndbuf(2048) );
+        BOOST_CHECK_EQUAL( sock.sndbuf(), 2048u );
+        BOOST_CHECK_NO_THROW( sock.writeto("127.0.0.1:12345","TEST-WRITE") );
+        BOOST_CHECK_EQUAL( sock.read(), "TEST-WRITE" );
+        BOOST_CHECK_NO_THROW( sock.protocol().timestamp() );
+        sock.writeto("127.0.0.1:12345","QUIT");
+        sleep(1);
+        stop();
+        sleep(1);
+        alarm(0);
+    } catch (...) {
+        alarm(0);
+        sleep(1);
+        stop();
+        sleep(1);
+        throw;
+    }
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// End:
index 3733386..b9c6e7c 100644 (file)
       <div class="nav">\r
         <xsl:text> -- </xsl:text>\r
         <xsl:for-each select="str:split($types)">\r
-          <xsl:element name="a">\r
-            <xsl:attribute name="href">#<xsl:value-of select="."/></xsl:attribute>\r
-            <xsl:value-of select="translate(.,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/><xsl:text>S</xsl:text>\r
-          </xsl:element>\r
-          <xsl:text> -- </xsl:text>\r
+          <xsl:variable name="type" select="string(.)"/>\r
+          <xsl:if test="$doc//xreflist[@type=$type]">\r
+            <xsl:element name="a">\r
+              <xsl:attribute name="href">#<xsl:value-of select="."/></xsl:attribute>\r
+              <xsl:value-of select="translate(.,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/><xsl:text>S</xsl:text>\r
+            </xsl:element>\r
+            <xsl:text> -- </xsl:text>\r
+          </xsl:if>\r
         </xsl:for-each>\r
       </div>\r
       <xsl:for-each select="str:split($types)">\r
         <xsl:variable name="type" select="string(.)"/>\r
-        <xsl:element name="div">\r
-          <xsl:attribute name="class"><xsl:value-of select="$type"/></xsl:attribute>\r
-          <xsl:element name="a">\r
-            <xsl:attribute name="name"><xsl:value-of select="$type"/></xsl:attribute>\r
-            <h2>Open <xsl:value-of select="translate($type,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>s</h2>\r
+        <xsl:if test="$doc//xreflist[@type=$type]">\r
+          <xsl:element name="div">\r
+            <xsl:attribute name="class"><xsl:value-of select="$type"/></xsl:attribute>\r
+            <xsl:element name="a">\r
+              <xsl:attribute name="name"><xsl:value-of select="$type"/></xsl:attribute>\r
+              <h2>Open <xsl:value-of select="translate($type,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>s</h2>\r
+            </xsl:element>\r
+            <xsl:for-each select="$doc//xreflist[@type=$type]">\r
+              <xsl:sort select="@module"/>\r
+              <h3><xsl:value-of select="@module"/> module</h3>\r
+              <dl>\r
+                <xsl:apply-templates/>\r
+              </dl>\r
+            </xsl:for-each>\r
           </xsl:element>\r
-          <xsl:for-each select="$doc//xreflist[@type=$type]">\r
-            <xsl:sort select="@module"/>\r
-            <h3><xsl:value-of select="@module"/> module</h3>\r
-            <dl>\r
-              <xsl:apply-templates/>\r
-            </dl>\r
-          </xsl:for-each>\r
-        </xsl:element>\r
+        </xsl:if>\r
       </xsl:for-each>\r
     </div>\r
   </xsl:template>\r