From: g0dil Date: Thu, 15 Feb 2007 13:42:40 +0000 (+0000) Subject: Add TCPv6 SocketHandle implementation X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=9ca82f3198ce01fa2daf50aa8f46e0eb630d275c;p=senf.git Add TCPv6 SocketHandle implementation git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@200 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Example.dox b/Example.dox index e42aac5..f2d86f6 100644 --- a/Example.dox +++ b/Example.dox @@ -89,9 +89,10 @@ application, check out the library, go to the \c Sniffer directory and execute -
-      # scons -u
-      # ./Sniffer
+
+    # scons -u
+    # ./Sniffer
+    
\see \ref components \n \ref build \n diff --git a/Mainpage.dox b/Mainpage.dox index b472354..03e5784 100644 --- a/Mainpage.dox +++ b/Mainpage.dox @@ -29,10 +29,7 @@ mailing lists. \see \ref usage\n - \ref example\n - Current status: Cross reference of action points\n - The BerliOS project page\n - The SENF Wiki at BerliOS + \ref example */ /** \page usage Using the SENF framework @@ -94,8 +91,9 @@ repository. Change to your development directory and use the following subversion command -
-      $ svn checkout http://svn.berlios.de/svnroot/repos/senf/trunk senf
+
+    $ svn checkout http://svn.berlios.de/svnroot/repos/senf/trunk senf
+    
This will create a new directory \c senf within the current directory. For further documentation on the use of Subversion, see @@ -109,9 +107,10 @@ To build the library, execute all unit tests and build the Sniffer test application, use -
-      $ scons
-      $ scons all_tests
+
+    $ scons
+    $ scons all_tests
+    
in the \c senf directory. This assumes, that you want to build the library with your default gcc and requires the boost libraries to @@ -223,8 +222,9 @@ check out the needed directories from the BerliOS SENF repository. Change to the 'Foo' directory and type -
-        $ svn propedit svn:externals .
+
+    $ svn propedit svn:externals .
+    
The default editor (probably VI) will be started with the current value of the svn:externals property (which will probably be @@ -236,16 +236,18 @@ For example, if you want to use the \c Scheduler and \c Socket module, the file will look like -
-        senfscons http://svn.berlios.de/svnroot/repos/senf/trunk/senfscons
-        Utils http://svn.berlios.de/svnroot/repos/senf/trunk/Utils
-        Scheduler http://svn.berlios.de/svnroot/repos/senf/trunk/Scheduler
-        Socket http://svn.berlios.de/svnroot/repos/senf/trunk/Socket
+
+    senfscons http://svn.berlios.de/svnroot/repos/senf/trunk/senfscons
+    Utils http://svn.berlios.de/svnroot/repos/senf/trunk/Utils
+    Scheduler http://svn.berlios.de/svnroot/repos/senf/trunk/Scheduler
+    Socket http://svn.berlios.de/svnroot/repos/senf/trunk/Socket
+    
exit the editor and the property will be set. Now run -
-        $ svn update
+
+    $ svn update
+    
and the code will be checked out into the corresponding directories. @@ -268,8 +270,9 @@ add \c SConfig to the list of files ignored by Subversion in the project root. In the project root execute -
-      $ svn propedit svn:ignore .
+
+    $ svn propedit svn:ignore .
+    
and add \c SConfig as a new line to the property. @@ -277,21 +280,24 @@ You should now be able to build your project using -
-      $ scons
+
+    $ scons
+    
If you have not changed the \c SConstruct file, this will build all modules you have importet into your project. To build and execute the unit tests, use -
-      $ scons all_tests
+
+    $ scons all_tests
+    
you can also build only a subdirectory by changing to it and running -
-      $ scons -u [target]
+
+    $ scons -u [target]
+    
\see SENFSCons reference \n SCons documentation \n diff --git a/Socket/INetAddressing.cc b/Socket/INetAddressing.cc index b1efabc..301d86c 100644 --- a/Socket/INetAddressing.cc +++ b/Socket/INetAddressing.cc @@ -148,14 +148,6 @@ prefix_ void senf::INet6SocketAddress::clear() sockaddr_.sin6_family = AF_INET6; } -prefix_ void senf::INet6SocketAddress::address(std::string const & addr) -{ - if (addr[0]=='[') - assignAddr(addr); - else - host(addr); -} - prefix_ std::string senf::INet6SocketAddress::address() const { diff --git a/Socket/INetAddressing.hh b/Socket/INetAddressing.hh index d97c83c..4a8deca 100644 --- a/Socket/INetAddressing.hh +++ b/Socket/INetAddressing.hh @@ -107,7 +107,16 @@ namespace senf { /** \brief IPv6 network address - \todo Implement + INet6Address represents a 128bit IPv6 network address. This class supports all standard + numeric string representations of IPv6 addresses. This class does not integrate with \c + gethostbyname() and so does not support host names. + + The conversion constructors allow the use of string constants whereever an INet6Address is + expected. Especially, it is possible to assign a string to an address to change it's value. + + \implementation The char const * constructor overload is needed to support + string-literals where an INet6Address is expected (the C++ standard does not allow + chaining conversion constructors like char const * -> std::string -» INet6Address) */ class INet6Address { @@ -127,17 +136,19 @@ namespace senf { ///@} /////////////////////////////////////////////////////////////////////////// - void clear(); - std::string address() const; + void clear(); ///< Clear address + std::string address() const; ///< Return printable address representation - bool operator==(INet6Address const & other) const; - bool operator!=(INet6Address const & other) const; + bool operator==(INet6Address const & other) const; ///< Compare addresses for equality + bool operator!=(INet6Address const & other) const; ///< Inverse of above - struct in6_addr & addr(); - struct in6_addr const & addr() const; - struct in6_addr * addr_p(); + struct in6_addr & addr(); ///< Access internal address representation + struct in6_addr const & addr() const; + ///< Access internal address representation in const context + struct in6_addr * addr_p(); ///< Get pointer to internal address repr struct in6_addr const * addr_p() const; - unsigned addr_len() const; + ///< Get const pointer to internal address repr + unsigned addr_len() const; ///< Size of an IPv6 address (16 bytes) protected: @@ -145,14 +156,40 @@ namespace senf { struct in6_addr addr_; }; + + /** \brief Output INet6Address instance as it's string representation + */ std::ostream & operator<<(std::ostream & os, INet6Address const & addr); /** \brief IPv6 socket address + This class wrapps the standard \c sockaddr_in6 structure. INet6SocketAddress provides access + to all members of the sockaddr_in6 structure. Additionally, INet6SocketAddress supports the + string representation + + \par "" [ address [ \@ interface ] ]: port + + Where \e address is an arbitrary numeric IPv6 address, \e interface is an optional network + interface name and \e port is the port number. The interface specification is only valid if + \e address is link-local address. The URL representation of an IPv6 address is as above + without the optional interface spec. + + INet6SocketAddress supports conversion constructors from it's string + representation. Therefore, wherever a INet6SocketAddress instance is expected, a string may + be used instead. + \implementation The sockaddr_in6 structure has an sin6_flowinfo member. However RFC3493 does - not give the use of this field and specifies, that the field should be ignored ... so that's - what we do. Furthermore, the GNU libc reference states, that this field is not implemented - in the library. + not give the use of this field and specifies, that the field should be ignored ... so + that's what we do. Furthermore, the GNU libc reference states, that this field is not + implemented in the library. + + \implementation We need to return the address in host() by value since we need to return a + INet6Address. However, sockaddr_in6 does not have one ... + + \implementation The char const * constructor overload is needed to support + string-literals where an INet6SocketAddress is expected (the C++ standard does not allow + chaining conversion constructors like char const * -> \c std::string -> \c + INet6SocketAddress) \idea Implement a INet6Address_ref class which has an interface identical to INet6Address and is convertible to INet6Address (the latter has a conversion constructor taking the @@ -170,32 +207,35 @@ namespace senf { ///\name Structors and default members ///@{ - INet6SocketAddress(); - INet6SocketAddress(std::string const & addr); - INet6SocketAddress(char const * addr); + INet6SocketAddress(); ///< Create empty instance + INet6SocketAddress(std::string const & addr); + ///< Initialize/convert from string represenation + INet6SocketAddress(char const * addr); ///< Same as above to support string literals 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 ///@} /////////////////////////////////////////////////////////////////////////// - bool operator==(INet6SocketAddress const & other) const; - bool operator!=(INet6SocketAddress const & other) const; + bool operator==(INet6SocketAddress const & other) const; ///< Check addresses for equality + bool operator!=(INet6SocketAddress const & other) const; ///< Inverse of above - void clear(); + void clear(); ///< Clear socket address - std::string address() const; - void address(std::string const & addr); + std::string address() const; ///< Get printable address representation - INet6Address host() const; - void host(INet6Address const & addr); + INet6Address host() const; ///< Get address + void host(INet6Address const & addr); ///< Change address - unsigned port() const; - void port(unsigned poirt); + unsigned port() const; ///< Get port number + void port(unsigned poirt); ///< Change port number - std::string iface() const; - void iface(std::string const & iface); + std::string iface() const; ///< Get interface name + void iface(std::string const & iface); ///< Change interface ///\name Generic SocketAddress interface ///@{ @@ -215,6 +255,8 @@ namespace senf { struct sockaddr_in6 sockaddr_; }; + /** \brief Output INet6SocketAddress instance as it's string representation + */ std::ostream & operator<<(std::ostream & os, INet6SocketAddress const & addr); /** \brief Signal invalid INet address syntax @@ -257,7 +299,7 @@ namespace senf { /** \brief Addressing policy supporting IPv6 addressing \par Address Type: - INet6Address + INet6SocketAddress This addressing policy implements addressing using Internet V6 addresses. @@ -265,8 +307,6 @@ namespace senf { The various members are directly importet from GenericAddressingPolicy which see for a detailed documentation. - - \todo implement */ struct INet6AddressingPolicy : public AddressingPolicyBase, diff --git a/Socket/INetProtocol.cc b/Socket/INetProtocol.cc index 4006369..ca93fa9 100644 --- a/Socket/INetProtocol.cc +++ b/Socket/INetProtocol.cc @@ -37,7 +37,7 @@ ///////////////////////////////cc.p//////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// -// senf::INet4Protocol +// senf::IPv4Protocol prefix_ void senf::IPv4Protocol::connect(INet4Address const & address) const @@ -148,6 +148,22 @@ prefix_ void senf::IPv4Protocol::mcTTL(unsigned value) throw SystemException(errno); } +/////////////////////////////////////////////////////////////////////////// +// senf::IPv6Protocol + +prefix_ void senf::IPv6Protocol::connect(INet6SocketAddress const & address) + const +{ + if (::connect(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0) + throw SystemException(errno); +} + +prefix_ void senf::IPv6Protocol::bind(INet6SocketAddress const & address) + const +{ + if (::bind(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0) + throw SystemException(errno); +} ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ diff --git a/Socket/INetProtocol.hh b/Socket/INetProtocol.hh index 482f88e..e1116bd 100644 --- a/Socket/INetProtocol.hh +++ b/Socket/INetProtocol.hh @@ -127,12 +127,20 @@ namespace senf { This protocol facet introduces all the socket api protocol members which are related to IPv6 addressing. - - \todo implement */ class IPv6Protocol : public virtual SocketProtocol - {}; + { + public: + void connect(INet6SocketAddress const & address) const; ///< Connect to remote address + /**< \todo make this obsolete by allowing access to the + ClientSocketHandle from ConcreateSocketProtocol + \param[in] address Address to connect to */ + void bind(INet6SocketAddress const & address) const; ///< Set local socket address + /**< \todo make this obsolete by allowing access to the + ClientSocketHandle from ConcreateSocketProtocol + \param[in] address Address to set */ + }; /// @} diff --git a/Socket/TCPSocketHandle.cc b/Socket/TCPSocketHandle.cc index 7202fe3..3023e2a 100644 --- a/Socket/TCPSocketHandle.cc +++ b/Socket/TCPSocketHandle.cc @@ -38,6 +38,9 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// +// senf::TCPv4SocketProtocol + prefix_ void senf::TCPv4SocketProtocol::init_client() const { @@ -81,6 +84,52 @@ prefix_ std::auto_ptr senf::TCPv4SocketProtocol::clone() return std::auto_ptr(new TCPv4SocketProtocol()); } +/////////////////////////////////////////////////////////////////////////// +// senf::TCPv6SocketProtocol:: + +prefix_ void senf::TCPv6SocketProtocol::init_client() + const +{ + int sock = ::socket(PF_INET6,SOCK_STREAM,0); + if (sock < 0) + throw SystemException(errno); + body().fd(sock); +} + +prefix_ void +senf::TCPv6SocketProtocol::init_client(INet6Address const & address) + const +{ + init_client(); + connect(address); +} + +prefix_ void senf::TCPv6SocketProtocol::init_server() + const +{ + int sock = ::socket(PF_INET,SOCK_STREAM,0); + if (sock < 0) + throw SystemException(errno); + body().fd(sock); +} + +prefix_ void senf::TCPv6SocketProtocol::init_server(INet6Address const & address, + unsigned backlog) + const +{ + init_server(); + bind(address); + reuseaddr(true); + if (::listen(body().fd(),backlog) < 0) + throw SystemException(errno); +} + +prefix_ std::auto_ptr senf::TCPv6SocketProtocol::clone() + const +{ + return std::auto_ptr(new TCPv6SocketProtocol()); +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "TCPSocketHandle.mpp" diff --git a/Socket/TCPSocketHandle.hh b/Socket/TCPSocketHandle.hh index 484e622..f94e439 100644 --- a/Socket/TCPSocketHandle.hh +++ b/Socket/TCPSocketHandle.hh @@ -160,8 +160,6 @@ namespace senf { ProtocolServerSocketHandle via the Socket Handle typedefs above. \see TCPv4SocketProtocol - - \todo Implement */ class TCPv6SocketProtocol : public ConcreteSocketProtocol, @@ -170,6 +168,47 @@ namespace senf { public BSDSocketProtocol, public AddressableBSDSocketProtocol { + /////////////////////////////////////////////////////////////////////////// + // internal interface + + ///\name Constructors + ///@{ + + void init_client() const; ///< Create unconnected client socket + /**< \note This member is implicitly called from the + ProtocolClientSocketHandle::ProtocolClientSocketHandle() + constructor */ + void init_client(INet4Address const & address) const; + ///< Create client socket and connect + /**< Creates a new client socket and connects to the given + address. + + \param[in] address remote address to connect to */ + /**< \note This member is implicitly called from the + ProtocolClientSocketHandle::ProtocolClientSocketHandle() + constructor */ + void init_server() const; ///< Create server socket + /**< \note This member is implicitly called from the + ProtocolServerSocketHandle::ProtocolServerSocketHandle() + constructor */ + void init_server(INet4Address const & address, unsigned backlog=1) const; + ///< Create server socket and listen + /**< Creates a new server socket, binds to \a address end + starts listening for new connections with a backlog of + \a backlog connections. It also enables reuseaddr(). + + \param[in] address address to listen on + \param[in] backlog size of the listen backlog */ + /**< \note This member is implicitly called from the + ProtocolServerSocketHandle::ProtocolServerSocketHandle() + constructor */ + + ///@} + ///\name Abstract Interface Implementation + + std::auto_ptr clone() const; + + ///@} }; typedef ProtocolClientSocketHandle TCPv6ClientSocketHandle; diff --git a/doclib/doxy-header-overview.html b/doclib/doxy-header-overview.html index e0f52b3..0a43bb6 100644 --- a/doclib/doxy-header-overview.html +++ b/doclib/doxy-header-overview.html @@ -17,11 +17,9 @@ div.tabs ul li.$projectname a { background-color: #EDE497; }
-
+ + + \ No newline at end of file diff --git a/doclib/doxy-header.html b/doclib/doxy-header.html index a630f59..8eab863 100644 --- a/doclib/doxy-header.html +++ b/doclib/doxy-header.html @@ -17,11 +17,9 @@ div.tabs ul li.$projectname a { background-color: #EDE497; }
-
+