diff --git a/Socket/BSDSocketProtocol.cc b/Socket/BSDSocketProtocol.cc index b171fb33d8f0f52f53e9668484eb5a33ffeafa2b..117686133adb8acbc6bf2a0fda303c6831c28f14 100644 --- a/Socket/BSDSocketProtocol.cc +++ b/Socket/BSDSocketProtocol.cc @@ -28,48 +28,62 @@ // Custom includes #include <sys/types.h> #include <sys/socket.h> +#include <sys/ioctl.h> #include "SocketHandle.hh" //#include "BSDSocketProtocol.mpp" #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -prefix_ bool satcom::lib::BSDSocketProtocol::reuseaddr() +prefix_ std::pair<bool,unsigned> satcom::lib::BSDSocketProtocol::linger() const { - int value; - socklen_t len (sizeof(value)); - if (::getsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&value,&len) < 0) + struct linger ling; + socklen_t len = sizeof(ling); + ::memset(&ling,sizeof(ling),0); + if (::getsockopt(body().fd(),SOL_SOCKET,SO_LINGER,&ling,&len) < 0) throw SystemException(errno); - return value; + return std::make_pair(ling.l_onoff, ling.l_linger); } -prefix_ void satcom::lib::BSDSocketProtocol::reuseaddr(bool value) +prefix_ void satcom::lib::BSDSocketProtocol::linger(bool enable, unsigned timeout) const { - // FIXME: This is only relevant for addressable sockets (not for e.g. socketpair) - int ivalue (value); - if (::setsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&ivalue,sizeof(ivalue)) < 0) + struct linger ling; + ling.l_onoff = enable; + ling.l_linger = timeout; + if (::setsockopt(body().fd(),SOL_SOCKET,SO_LINGER,&ling,sizeof(ling)) < 0) throw SystemException(errno); } -prefix_ std::pair<bool,unsigned> satcom::lib::BSDSocketProtocol::linger() +prefix_ struct timeval satcom::lib::BSDSocketProtocol::timestamp() + const { - // FIXME: This is really only relevant for stream sockets ... - // TODO: Can the linger timeout be 0 or -1 and what does that mean? - struct linger ling; - socklen_t len = sizeof(ling); - if (::getsockopt(body().fd(),SOL_SOCKET,SO_LINGER,&ling,&len) < 0) + // TODO: Check, why this fails with ENOFILE (!!!!) at least when + // called from a tcp socket. Further investigation necessary ... + struct timeval tv; + if (::ioctl(body().fd(), SIOCGSTAMP, &tv) < 0) throw SystemException(errno); - return std::make_pair(ling.l_onoff,ling.l_linger); + return tv; } -prefix_ void satcom::lib::BSDSocketProtocol::linger(bool enable, unsigned timeout) +/////////////////////////////////////////////////////////////////////////// + +prefix_ bool satcom::lib::AddressableBSDSocketProtocol::reuseaddr() + const { - struct linger ling; - ling.l_onoff = enable; - ling.l_linger = timeout; - if (::setsockopt(body().fd(),SOL_SOCKET,SO_LINGER,&ling,sizeof(ling)) < 0) + int value; + socklen_t len (sizeof(value)); + if (::getsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&value,&len) < 0) + throw SystemException(errno); + return value; +} + +prefix_ void satcom::lib::AddressableBSDSocketProtocol::reuseaddr(bool value) + const +{ + int ivalue (value); + if (::setsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&ivalue,sizeof(ivalue)) < 0) throw SystemException(errno); } diff --git a/Socket/BSDSocketProtocol.hh b/Socket/BSDSocketProtocol.hh index f8d5c004121c13842328f622bafabce087926008..3d3559919ebcd4609b811a0e486546874ce9dfef 100644 --- a/Socket/BSDSocketProtocol.hh +++ b/Socket/BSDSocketProtocol.hh @@ -24,6 +24,7 @@ #define HH_BSDSocketProtocol_ 1 // Custom includes +#include <sys/time.h> #include "SocketProtocol.hh" //#include "BSDSocketProtocol.mpp" @@ -33,14 +34,21 @@ namespace satcom { namespace lib { class BSDSocketProtocol - : public virtual SocketProtocolHelper + : public virtual SocketProtocol + { + public: + std::pair<bool,unsigned> linger() const; + void linger(bool enable, unsigned timeout) const; + + struct timeval timestamp() const; + }; + + class AddressableBSDSocketProtocol + : public virtual SocketProtocol { public: bool reuseaddr() const; void reuseaddr(bool value) const; - - std::pair<bool,unsigned> linger(); - void linger(bool enable, unsigned timeout); }; }} diff --git a/Socket/CommunicationPolicy.cc b/Socket/CommunicationPolicy.cc index 66ef9ae625e7ffeff72aade115eb3f162f30b18d..4b133effa949cfe252ee99164718102321a8f8ee 100644 --- a/Socket/CommunicationPolicy.cc +++ b/Socket/CommunicationPolicy.cc @@ -36,6 +36,12 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// +prefix_ void satcom::lib::ConnectedCommunicationPolicy::listen(FileHandle handle, + unsigned backlog) +{ + ::listen(handle.fd(),backlog); +} + prefix_ int satcom::lib::ConnectedCommunicationPolicy::do_accept(FileHandle handle, struct sockaddr * addr, unsigned len) diff --git a/Socket/CommunicationPolicy.hh b/Socket/CommunicationPolicy.hh index f1d84e77bffedcc15f651e4cd23c3bc505f02bbb..e5ad2076a6ee0270c67af38802bfbacbb933f03c 100644 --- a/Socket/CommunicationPolicy.hh +++ b/Socket/CommunicationPolicy.hh @@ -40,6 +40,7 @@ namespace lib { struct ConnectedCommunicationPolicy : public CommunicationPolicyBase { + static void listen(FileHandle handle, unsigned backlog); template <class Policy> static int accept(ServerSocketHandle<Policy> handle, typename ServerSocketHandle<Policy>::Address & address, diff --git a/Socket/Doxyfile b/Socket/Doxyfile new file mode 100644 index 0000000000000000000000000000000000000000..3a08b6331bdc96aea7ff7620e7d2ede6059e1f14 --- /dev/null +++ b/Socket/Doxyfile @@ -0,0 +1,273 @@ +# Doxyfile 1.4.2 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = "" +PROJECT_NUMBER = "Version 0.0.1" +OUTPUT_DIRECTORY = doc +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = NO +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = YES +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = YES +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = YES +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = NO +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = . +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.C \ + *.CC \ + *.C++ \ + *.II \ + *.I++ \ + *.H \ + *.HH \ + *.H++ \ + *.CS \ + *.PHP \ + *.PHP3 \ + *.M \ + *.MM \ + *.cci \ + *.ct \ + *.cti \ + *.ih +RECURSIVE = NO +EXCLUDE = doc +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = *.test.cc +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = satcom.css +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +SEARCH_INCLUDES = YES +INCLUDE_PATH = libs +INCLUDE_FILE_PATTERNS = +PREDEFINED = DOXYGEN +EXPAND_AS_DEFINED = DefineCommand +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = NO +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = NO +DIRECTORY_GRAPH = NO +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 800 +MAX_DOT_GRAPH_HEIGHT = 1200 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = YES +GENERATE_LEGEND = YES +DOT_CLEANUP = NO +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/Socket/StreamFramingPolicy.hh b/Socket/FramingPolicy.hh similarity index 82% rename from Socket/StreamFramingPolicy.hh rename to Socket/FramingPolicy.hh index 983edc2d53247ed903751496040c1fab81ebcc65..96a4b98a3abe45a54ccdef283bb3f7c6d6080ff9 100644 --- a/Socket/StreamFramingPolicy.hh +++ b/Socket/FramingPolicy.hh @@ -20,12 +20,13 @@ // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef HH_StreamFramingPolicy_ -#define HH_StreamFramingPolicy_ 1 +#ifndef HH_FramingPolicy_ +#define HH_FramingPolicy_ 1 // Custom includes +#include "SocketPolicy.hh" -//#include "StreamFramingPolicy.mpp" +//#include "FramingPolicy.mpp" ///////////////////////////////hh.p//////////////////////////////////////// namespace satcom { @@ -34,12 +35,15 @@ namespace lib { struct StreamFramingPolicy : public FramingPolicyBase {}; + struct DatagramFramingPolicy : public FramingPolicyBase + {}; + }} ///////////////////////////////hh.e//////////////////////////////////////// -//#include "StreamFramingPolicy.cci" -//#include "StreamFramingPolicy.ct" -//#include "StreamFramingPolicy.cti" +//#include "FramingPolicy.cci" +//#include "FramingPolicy.ct" +//#include "FramingPolicy.cti" #endif diff --git a/Socket/INetAddress.cc b/Socket/INetAddressing.cc similarity index 82% rename from Socket/INetAddress.cc rename to Socket/INetAddressing.cc index dfb30340df8ba0dfcd027185bef2072e5b855b87..b2e8edf85157721e432a6ff243653f40da5a8164 100644 --- a/Socket/INetAddress.cc +++ b/Socket/INetAddressing.cc @@ -22,8 +22,8 @@ // Definition of non-inline non-template functions -#include "INetAddress.hh" -//#include "INetAddress.ih" +#include "INetAddressing.hh" +//#include "INetAddressing.ih" // Custom includes #include <strstream> @@ -31,7 +31,7 @@ #include <sys/socket.h> #include <boost/lexical_cast.hpp> -//#include "INetAddress.mpp" +//#include "INetAddressing.mpp" #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// @@ -39,9 +39,9 @@ prefix_ satcom::lib::INet4Address::INet4Address(std::string host, unsigned port) { clear(); // TODO: gethostbyname einbauen - if (::inet_aton(host.c_str(), &addr.sin_addr) == 0) + if (::inet_aton(host.c_str(), &addr_.sin_addr) == 0) throw InvalidINetAddressException(); - addr.sin_port = htons(port); + addr_.sin_port = htons(port); } prefix_ std::string satcom::lib::INet4Address::str() @@ -54,8 +54,8 @@ prefix_ std::string satcom::lib::INet4Address::str() prefix_ void satcom::lib::INet4Address::clear() { - ::memset(&addr,0,sizeof(addr)); - addr.sin_family = AF_INET; + ::memset(&addr_,0,sizeof(addr_)); + addr_.sin_family = AF_INET; } prefix_ void satcom::lib::INet4Address::assignString(std::string address) @@ -65,11 +65,11 @@ prefix_ void satcom::lib::INet4Address::assignString(std::string address) unsigned i = address.find(':'); if (i == std::string::npos) throw InvalidINetAddressException(); - if (::inet_aton(std::string(address,0,i).c_str(), &addr.sin_addr) == 0) + if (::inet_aton(std::string(address,0,i).c_str(), &addr_.sin_addr) == 0) throw InvalidINetAddressException(); try { // Replace lexical_cast with strtoul ? - addr.sin_port = htons(boost::lexical_cast< ::u_int16_t >(std::string(address,i+1))); + addr_.sin_port = htons(boost::lexical_cast< ::u_int16_t >(std::string(address,i+1))); } catch (boost::bad_lexical_cast const & ex) { throw InvalidINetAddressException(); @@ -78,7 +78,7 @@ prefix_ void satcom::lib::INet4Address::assignString(std::string address) ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ -//#include "INetAddress.mpp" +//#include "INetAddressing.mpp" // Local Variables: diff --git a/Socket/INetAddress.cci b/Socket/INetAddressing.cci similarity index 86% rename from Socket/INetAddress.cci rename to Socket/INetAddressing.cci index 20d707ab62cd8a5d6337f1aea5051500d1ce0137..a04def2abd41a11ce837a37f917d937c5bb5de42 100644 --- a/Socket/INetAddress.cci +++ b/Socket/INetAddressing.cci @@ -46,38 +46,38 @@ prefix_ satcom::lib::INet4Address::INet4Address(std::string address) prefix_ bool satcom::lib::INet4Address::operator==(INet4Address const & other) const { - return addr.sin_port == other.addr.sin_port && - addr.sin_addr.s_addr == other.addr.sin_addr.s_addr; + return addr_.sin_port == other.addr_.sin_port && + addr_.sin_addr.s_addr == other.addr_.sin_addr.s_addr; } prefix_ std::string satcom::lib::INet4Address::host() const { // FIXME: thread safety? - return std::string(::inet_ntoa(addr.sin_addr)); + return std::string(::inet_ntoa(addr_.sin_addr)); } prefix_ unsigned satcom::lib::INet4Address::port() const { - return ntohs(addr.sin_port); + return ntohs(addr_.sin_port); } prefix_ struct sockaddr * satcom::lib::INet4Address::sockaddr_p() { - return reinterpret_cast<struct sockaddr *>(&addr); + return reinterpret_cast<struct sockaddr *>(&addr_); } prefix_ struct sockaddr const * satcom::lib::INet4Address::sockaddr_p() const { - return reinterpret_cast<struct sockaddr const *>(&addr); + return reinterpret_cast<struct sockaddr const *>(&addr_); } prefix_ unsigned satcom::lib::INet4Address::sockaddr_len() const { - return sizeof(addr); + return sizeof(addr_); } prefix_ std::ostream & satcom::lib::operator<<(std::ostream & os, INet4Address const & addr) diff --git a/Socket/INetAddress.hh b/Socket/INetAddressing.hh similarity index 62% rename from Socket/INetAddress.hh rename to Socket/INetAddressing.hh index f6a87ab2be70a1471febe093c44e40acd9c830f4..bfc7759bf9a16ca4954b68914aac63bf25f4e0de 100644 --- a/Socket/INetAddress.hh +++ b/Socket/INetAddressing.hh @@ -20,15 +20,18 @@ // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef HH_INetAddress_ -#define HH_INetAddress_ 1 +#ifndef HH_INetAddressing_ +#define HH_INetAddressing_ 1 // Custom includes #include <string> #include <exception> #include <netinet/in.h> +#include "SocketPolicy.hh" +#include "ClientSocketHandle.hh" +#include "CommunicationPolicy.hh" -//#include "INetAddress.mpp" +//#include "INetAddressing.mpp" ///////////////////////////////hh.p//////////////////////////////////////// namespace satcom { @@ -59,7 +62,7 @@ namespace lib { private: void assignString(std::string addr); - struct ::sockaddr_in addr; + struct ::sockaddr_in addr_; }; std::ostream & operator<<(std::ostream & os, INet4Address const & addr); @@ -69,16 +72,42 @@ namespace lib { // TODO: Implement }; + struct INet4AddressingPolicy : public AddressingPolicyBase + { + typedef INet4Address Address; + + template <class Policy> + static void peer(ClientSocketHandle<Policy> handle, Address & addr, + typename IfCommunicationPolicyIs<Policy,ConnectedCommunicationPolicy>::type * = 0); + static void local(FileHandle handle, Address & addr); + + template <class Policy> + static void connect(ClientSocketHandle<Policy> handle, Address const & addr, + typename IfCommunicationPolicyIs<Policy,ConnectedCommunicationPolicy>::type * = 0); + static void bind(FileHandle handle, Address const & addr); + + private: + static void do_peer(FileHandle handle, Address & addr); + static void do_connect(FileHandle handle, Address const & addr); + }; + + struct INet6AddressingPolicy : public AddressingPolicyBase + { + typedef INet6Address Address; + + // TODO: Implement + }; + struct InvalidINetAddressException : public std::exception { char const * what() const throw() { return "invalid inet address"; } }; }} ///////////////////////////////hh.e//////////////////////////////////////// -#include "INetAddress.cci" -//#include "INetAddress.ct" -//#include "INetAddress.cti" -//#include "INetAddress.mpp" +#include "INetAddressing.cci" +//#include "INetAddressing.ct" +//#include "INetAddressing.cti" +//#include "INetAddressing.mpp" #endif diff --git a/Socket/INetAddress.test.cc b/Socket/INetAddressing.test.cc similarity index 96% rename from Socket/INetAddress.test.cc rename to Socket/INetAddressing.test.cc index bcfa6078d4f531668e24fdb162cc59b2ff4aa2c0..dea7b881d2236ea6a297e8dbd60f60e37bc2062f 100644 --- a/Socket/INetAddress.test.cc +++ b/Socket/INetAddressing.test.cc @@ -22,11 +22,11 @@ // Unit tests -//#include "INetAddress.test.hh" -//#include "INetAddress.test.ih" +//#include "INetAddressing.test.hh" +//#include "INetAddressing.test.ih" // Custom includes -#include "INetAddress.hh" +#include "INetAddressing.hh" #include <boost/test/auto_unit_test.hpp> #include <boost/test/test_tools.hpp> diff --git a/Socket/INetProtocol.cc b/Socket/INetProtocol.cc index d1ebe9ec6e800ebb386ab49218f37cf64b24b672..754e44a699af4cd72351ee9ef4832723efe64880 100644 --- a/Socket/INetProtocol.cc +++ b/Socket/INetProtocol.cc @@ -88,6 +88,7 @@ prefix_ void satcom::lib::IPv4Protocol::bind(INet4Address const & address) } prefix_ bool satcom::lib::IPv4Protocol::mcLoop() + const { int value; socklen_t len (sizeof(value)); @@ -97,6 +98,7 @@ prefix_ bool satcom::lib::IPv4Protocol::mcLoop() } prefix_ void satcom::lib::IPv4Protocol::mcLoop(bool value) + const { int ivalue (value); if (::setsockopt(body().fd(),SOL_IP,IP_MULTICAST_LOOP,&ivalue,sizeof(ivalue)) < 0) @@ -104,6 +106,7 @@ prefix_ void satcom::lib::IPv4Protocol::mcLoop(bool value) } prefix_ void satcom::lib::IPv4Protocol::mcAddMembership(INet4Address const & mcAddr) + const { struct ip_mreqn mreqn; mreqn.imr_multiaddr = reinterpret_cast<struct sockaddr_in const *>(mcAddr.sockaddr_p())->sin_addr; @@ -115,6 +118,7 @@ prefix_ void satcom::lib::IPv4Protocol::mcAddMembership(INet4Address const & mcA prefix_ void satcom::lib::IPv4Protocol::mcAddMembership(INet4Address const & mcAddr, INet4Address const & localAddr) + const { struct ip_mreqn mreqn; mreqn.imr_multiaddr = reinterpret_cast<struct sockaddr_in const *>(mcAddr.sockaddr_p())->sin_addr; @@ -125,6 +129,7 @@ prefix_ void satcom::lib::IPv4Protocol::mcAddMembership(INet4Address const & mcA } prefix_ void satcom::lib::IPv4Protocol::mcDropMembership(INet4Address const & mcAddr) + const { struct ip_mreqn mreqn; mreqn.imr_multiaddr = reinterpret_cast<struct sockaddr_in const *>(mcAddr.sockaddr_p())->sin_addr; @@ -136,6 +141,7 @@ prefix_ void satcom::lib::IPv4Protocol::mcDropMembership(INet4Address const & mc prefix_ void satcom::lib::IPv4Protocol::mcDropMembership(INet4Address const & mcAddr, INet4Address const & localAddr) + const { struct ip_mreqn mreqn; mreqn.imr_multiaddr = reinterpret_cast<struct sockaddr_in const *>(mcAddr.sockaddr_p())->sin_addr; @@ -146,6 +152,7 @@ prefix_ void satcom::lib::IPv4Protocol::mcDropMembership(INet4Address const & mc } prefix_ void satcom::lib::IPv4Protocol::mcIface(std::string iface) + const { struct ip_mreqn mreqn; ::memset(&mreqn,sizeof(mreqn),0); @@ -159,6 +166,7 @@ prefix_ void satcom::lib::IPv4Protocol::mcIface(std::string iface) } prefix_ unsigned satcom::lib::IPv4Protocol::mcTTL() + const { int value; socklen_t len (sizeof(value)); @@ -168,6 +176,7 @@ prefix_ unsigned satcom::lib::IPv4Protocol::mcTTL() } prefix_ void satcom::lib::IPv4Protocol::mcTTL(unsigned value) + const { if (::setsockopt(body().fd(),SOL_IP,IP_MULTICAST_TTL,&value,sizeof(value)) < 0) throw SystemException(errno); diff --git a/Socket/INetProtocol.hh b/Socket/INetProtocol.hh index ecfb189c202e881c52307f5f62b564b62778f944..6bf9acb1d202e4d1f4ca2a331179b7eefbfa86dc 100644 --- a/Socket/INetProtocol.hh +++ b/Socket/INetProtocol.hh @@ -27,8 +27,7 @@ // Custom includes #include "SocketProtocol.hh" -#include "SocketPolicy.hh" -#include "INetAddress.hh" +#include "INetAddressing.hh" #include "ClientSocketHandle.hh" #include "CommunicationPolicy.hh" @@ -38,44 +37,18 @@ namespace satcom { namespace lib { - struct INet4AddressingPolicy : public AddressingPolicyBase - { - typedef INet4Address Address; - - template <class Policy> - static void peer(ClientSocketHandle<Policy> handle, Address & addr, - typename IfCommunicationPolicyIs<Policy,ConnectedCommunicationPolicy>::type * = 0); - static void local(FileHandle handle, Address & addr); - - template <class Policy> - static void connect(ClientSocketHandle<Policy> handle, Address const & addr, - typename IfCommunicationPolicyIs<Policy,ConnectedCommunicationPolicy>::type * = 0); - static void bind(FileHandle handle, Address const & addr); - - private: - static void do_peer(FileHandle handle, Address & addr); - static void do_connect(FileHandle handle, Address const & addr); - }; - - struct INet6AddressingPolicy : public AddressingPolicyBase - { - typedef INet6Address Address; - - // TODO: Implement - }; - class IPv4Protocol - : public virtual SocketProtocolHelper + : public virtual SocketProtocol { public: void connect(INet4Address const & address) const; void bind(INet4Address const & address) const; - unsigned mcTTL(); - void mcTTL(unsigned value); + unsigned mcTTL() const; + void mcTTL(unsigned value) const; - bool mcLoop(); - void mcLoop(bool value); + bool mcLoop() const; + void mcLoop(bool value) const; // TODO: Implement real INet4Address datatype and // rename this one to INet4SockAddress ... @@ -83,17 +56,17 @@ namespace lib { // index on add/drop? what does it do (especially if // the local addres is given ?) - void mcAddMembership(INet4Address const & mcAddr); - void mcAddMembership(INet4Address const & mcAddr, INet4Address const & localAddr); + void mcAddMembership(INet4Address const & mcAddr) const; + void mcAddMembership(INet4Address const & mcAddr, INet4Address const & localAddr) const; - void mcDropMembership(INet4Address const & mcAddr); - void mcDropMembership(INet4Address const & mcAddr, INet4Address const & localAddr); + void mcDropMembership(INet4Address const & mcAddr) const; + void mcDropMembership(INet4Address const & mcAddr, INet4Address const & localAddr) const; - void mcIface(std::string iface = std::string()); + void mcIface(std::string iface = std::string()) const; }; class IPv6Protocol - : public virtual SocketProtocolHelper + : public virtual SocketProtocol {}; }} diff --git a/Socket/LLAddressing.cc b/Socket/LLAddressing.cc new file mode 100644 index 0000000000000000000000000000000000000000..23af92050fd0e67c38bb4cd651a63551dc63bdee --- /dev/null +++ b/Socket/LLAddressing.cc @@ -0,0 +1,139 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.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 "LLAddressing.hh" +#include "LLAddressing.ih" + +// Custom includes +#include <net/if.h> +#include <sys/socket.h> + +#include <boost/algorithm/string/classification.hpp> +#include <boost/algorithm/string/finder.hpp> + +#include "Utils/Exception.hh" + +//#include "LLAddressing.mpp" +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +prefix_ unsigned char satcom::lib::detail::hexnibble(char c) +{ + if (c>='0' && c<='9') + return c - '0'; + if (c>='A' && c<='F') + return c - 'A' + 10; + if (c>='a' && c<='f') + return c - 'a' + 10; + throw InvalidLLSocketAddressException(); +} + +prefix_ std::string satcom::lib::LLSocketAddress::interface() + const +{ + if (addr_.sll_ifindex == 0) + return std::string(); + char name[IFNAMSIZ]; + if (! ::if_indextoname(addr_.sll_ifindex, name)) + throw InvalidLLSocketAddressException(); + return std::string(name); +} + +/* +{ + if (addr_.sll_halen == 0) + return std::string(); + std::stringstream s; + + unsigned char const * i = &addr_.sll_addr[0]; + while (1) { + s << std::hex << std::setw(2) << std::setfill('0') << unsigned(*i); + ++i; + if (i == &addr_.sll_addr[addr_.sll_halen]) break; + s << '-'; + } + return s.str(); +} +*/ + + +/* +prefix_ void satcom::lib::LLSocketAddress::address(std::string address) +{ + typedef boost::split_iterator<std::string::iterator> StringSplitIterator; + StringSplitIterator i = boost::make_split_iterator(address, boost::token_finder(boost::is_any_of("-: "))); + unsigned char * j = &addr_.sll_addr[0]; + for (; ! i.eof() && addr_.sll_halen<8; ++i, ++j, ++addr_.sll_halen) { + if ( i->size() != 2 || ! boost::all(*i, boost::is_xdigit()) ) + throw InvalidLLSocketAddressException(); + *j = hex(*i); + } + if (! i.eof()) + throw InvalidLLSocketAddressException(); +} +*/ + +prefix_ void satcom::lib::LLSocketAddress::interface(std::string interface) +{ + if (! interface.empty()) { + addr_.sll_ifindex = if_nametoindex(interface.c_str()); + if (addr_.sll_ifindex == 0) + throw InvalidLLSocketAddressException(); + } +} + + +prefix_ satcom::lib::detail::LLAddressFromStringRange +satcom::lib::llAddress(std::string address) +{ + detail::StringSplitIterator i = + boost::make_split_iterator(address, boost::token_finder(boost::is_any_of("-: "))); + detail::StringSplitIterator i_end; + + detail::HexSplitIterator j (i,detail::HexConverter()); + detail::HexSplitIterator j_end (i_end); + + return detail::LLAddressFromStringRange(j,j_end); +} + +/////////////////////////////////////////////////////////////////////////// +// satcom::lib::LLAddressingPolicy + +prefix_ void satcom::lib::LLAddressingPolicy::local(FileHandle handle, Address &addr) +{ + // TODO: check, wether getsockname works on packet sockets ... + socklen_t len = addr.sockaddr_len(); + if (::getsockname(handle.fd(), addr.sockaddr_p(), &len) < 0) + throw SystemException(errno); +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ +//#include "LLAddressing.mpp" + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/LLAddressing.cci b/Socket/LLAddressing.cci new file mode 100644 index 0000000000000000000000000000000000000000..509b969407e2016978b2190aa083b2568fba73d9 --- /dev/null +++ b/Socket/LLAddressing.cci @@ -0,0 +1,107 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.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 inline non-template functions + +// Custom includes +#include <sys/socket.h> +#include <netinet/in.h> + +#define prefix_ inline +///////////////////////////////cci.p/////////////////////////////////////// + +prefix_ satcom::lib::LLSocketAddress::LLSocketAddress() +{ + clear(); +} + +prefix_ satcom::lib::LLSocketAddress::LLSocketAddress(unsigned protocol, std::string interface) +{ + clear(); + this->protocol(protocol); + this->interface(interface); +} + +prefix_ void satcom::lib::LLSocketAddress::clear() +{ + ::memset(&addr_,0,sizeof(addr_)); + addr_.sll_family = AF_PACKET; +} + +prefix_ unsigned satcom::lib::LLSocketAddress::protocol() + const +{ + return ntohs(addr_.sll_protocol); +} + +prefix_ unsigned satcom::lib::LLSocketAddress::arptype() + const +{ + // TODO: Check, wether this is returned in network or host byte + // order + return ntohs(addr_.sll_hatype); +} + +prefix_ unsigned satcom::lib::LLSocketAddress::pkttype() + const +{ + // TODO: Check, wether this is returned in network or host byte + // order + return ntohs(addr_.sll_pkttype); +} + +prefix_ satcom::lib::LLSocketAddress::LLAddress satcom::lib::LLSocketAddress::address() + const +{ + return LLAddress(&addr_.sll_addr[0], &addr_.sll_addr[addr_.sll_halen]); +} + +prefix_ void satcom::lib::LLSocketAddress::protocol(unsigned protocol) +{ + addr_.sll_protocol = htons(protocol); +} + +prefix_ struct sockaddr * satcom::lib::LLSocketAddress::sockaddr_p() +{ + return reinterpret_cast<struct sockaddr *>(&addr_); +} + +prefix_ struct sockaddr const * satcom::lib::LLSocketAddress::sockaddr_p() + const +{ + return reinterpret_cast<struct sockaddr const *>(&addr_); +} + +prefix_ unsigned satcom::lib::LLSocketAddress::sockaddr_len() + const +{ + return sizeof(addr_); +} + +///////////////////////////////cci.e/////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/LLAddressing.ct b/Socket/LLAddressing.ct new file mode 100644 index 0000000000000000000000000000000000000000..cf38dd47bce7a4a85d10876ff54ba1d61a840cef --- /dev/null +++ b/Socket/LLAddressing.ct @@ -0,0 +1,86 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.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 template functions + +#include "LLAddressing.ih" + +// Custom includes +#include <sstream> +#include <iomanip> +#include <string.h> + +#define prefix_ +///////////////////////////////ct.p//////////////////////////////////////// + +template <class ForwardRange> +prefix_ void satcom::lib::LLSocketAddress::address(ForwardRange const & address) +{ + if (boost::size(address) > sizeof(addr_.sll_addr)) + throw InvalidLLSocketAddressException(); + typename boost::range_const_iterator<ForwardRange>::type i (boost::begin(address)); + ::memset(&addr_.sll_addr[0],sizeof(addr_.sll_addr),0); + addr_.sll_halen = 0; + for (; i != boost::end(address) && addr_.sll_halen<8; ++i, ++addr_.sll_halen) + addr_.sll_addr[addr_.sll_halen] = *i; + if (i != boost::end(address)) + throw InvalidLLSocketAddressException(); +} + +template <class ForwardRange> +prefix_ std::string +satcom::lib::llAddress(ForwardRange const & address, + typename boost::enable_if< boost::is_class<ForwardRange> >::type *) +{ + if (boost::empty(address)) + return std::string(); + std::stringstream s; + typename boost::range_const_iterator< ForwardRange >::type i (boost::begin(address)); + while (1) { + s << std::hex << std::setw(2) << std::setfill('0') << unsigned(*i); + ++ i; + if (i == boost::end(address)) + break; + s << '-'; + } + return s.str(); +} + +template <class ForwardRange> +prefix_ unsigned char satcom::lib::detail::HexConverter::operator()(ForwardRange const & v) + const +{ + if (boost::size(v) != 2) + throw InvalidLLSocketAddressException(); + typename boost::range_iterator< ForwardRange >::type i (boost::begin(v)); + unsigned char n1 = hexnibble(*i) << 4; + return n1 + hexnibble(*(++i)); +} + +///////////////////////////////ct.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/LLAddressing.cti b/Socket/LLAddressing.cti new file mode 100644 index 0000000000000000000000000000000000000000..c1a5e68e1d5cbdeba4c27f8891575b5b515e02ba --- /dev/null +++ b/Socket/LLAddressing.cti @@ -0,0 +1,50 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.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 inline template functions + +#include "LLAddressing.ih" + +// Custom includes +#include <algorithm> // for std::copy + +#define prefix_ inline +///////////////////////////////cti.p/////////////////////////////////////// + +template <class ForwardRange> +prefix_ satcom::lib::LLSocketAddress:: +LLSocketAddress(ForwardRange const & address, std::string interface, + typename boost::enable_if_c<! boost::is_integral<ForwardRange>::value >::type *) +{ + clear(); + this->address(address); + this->interface(interface); +} + +///////////////////////////////cti.e/////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/LLAddressing.hh b/Socket/LLAddressing.hh new file mode 100644 index 0000000000000000000000000000000000000000..17e9f7d934fc86149760d684f8cf6b5fb7aed2b4 --- /dev/null +++ b/Socket/LLAddressing.hh @@ -0,0 +1,134 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.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. + +#ifndef HH_LLAddressing_ +#define HH_LLAddressing_ 1 + +// Custom includes +#include <boost/range/iterator_range.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits.hpp> + +#include <sys/socket.h> +#include <netpacket/packet.h> + +#include "SocketPolicy.hh" +#include "FileHandle.hh" + +//#include "LLAddressing.mpp" +#include "LLAddressing.ih" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace satcom { +namespace lib { + + class LLSocketAddress + { + public: + // Right now we use an arbitrary ForwardRange (see Boost.Range) + // as the representation for a hardware address. The restrictions + // for the range are: + // a) the range must never be larger than 8 elements + // b) the value_type must be convertible to unsigend char + // and really we need only a single-pass range. + // + // Since a hardware address is so short (a maximum of 8 + // bytes), in the aftermath I think a simple container holding + // a maximum of 8 unsigned chars (e.g. Boost.Array with + // additional length parameter) will be much simpler and + // probably even more efficient. This should have a conversion + // constructor from an arbitrary ForwardRange to make it + // compatible e.g. with the Packet library. + // + // However, since I have implemented it already as it is now, + // I'll leave it as it is ... + + typedef boost::iterator_range<unsigned char const *> LLAddress; + + LLSocketAddress(); + // And this is for bind + LLSocketAddress(unsigned protocol, std::string interface=""); + // This is for sending packets .. + // We must use enable_if here, so this constructor will not hide + // above constructor if passed a plain int or short argument + template <class ForwardRange> + LLSocketAddress(ForwardRange const & address, std::string interface, + typename boost::enable_if_c<! boost::is_integral<ForwardRange>::value >::type * = 0); + + void clear(); + + unsigned protocol() const; + std::string interface() const; + unsigned arptype() const; + unsigned pkttype() const; + LLAddress address() const; + + // The mutating interface is purposely restricted to allow only + // changing those members, which are sensible to be changed. + + template <class ForwardRange> + void address(ForwardRange const & address); + void interface(std::string interface); + void protocol(unsigned protocol); + + struct sockaddr * sockaddr_p(); + struct sockaddr const * sockaddr_p() const; + unsigned sockaddr_len() const; + + private: + struct ::sockaddr_ll addr_; + }; + + detail::LLAddressFromStringRange llAddress(std::string address); + // The enable_if condition here allows only for classes as range. + // However, excluding zero-terminated strings (which we want to + // pass to above) I cannot think of a non-class ForwardRange + // except for academic cases + template <class ForwardRange> + std::string llAddress(ForwardRange const & address, + typename boost::enable_if< boost::is_class<ForwardRange> >::type * = 0); + + class LLAddressingPolicy + : public AddressingPolicyBase + { + public: + typedef LLSocketAddress Address; + + static void local(FileHandle handle, Address &addr); + }; + + struct InvalidLLSocketAddressException : public std::exception + { char const * what() const throw() { return "invalid ll address"; } }; +}} + +///////////////////////////////hh.e//////////////////////////////////////// +#include "LLAddressing.cci" +#include "LLAddressing.ct" +#include "LLAddressing.cti" +//#include "LLAddressing.mpp" +#endif + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/LLAddressing.ih b/Socket/LLAddressing.ih new file mode 100644 index 0000000000000000000000000000000000000000..57ec8b19e56cf728f46ce3f77c83fa65161aec49 --- /dev/null +++ b/Socket/LLAddressing.ih @@ -0,0 +1,56 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.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. + +#ifndef IH_LLAddressing_ +#define IH_LLAddressing_ 1 + +// Custom includes +#include <boost/algorithm/string/split.hpp> + +///////////////////////////////ih.p//////////////////////////////////////// + +namespace satcom { +namespace lib { +namespace detail { + + struct HexConverter { + typedef unsigned char result_type; + template <class ForwardRange> + result_type operator()(ForwardRange const & v) const; + }; + + typedef boost::split_iterator<std::string::iterator> StringSplitIterator; + typedef boost::transform_iterator< HexConverter, StringSplitIterator > HexSplitIterator; + typedef boost::iterator_range<HexSplitIterator> LLAddressFromStringRange; + + unsigned char hexnibble(char c); + +}}} + +///////////////////////////////ih.e//////////////////////////////////////// +#endif + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/LLAddressing.test.cc b/Socket/LLAddressing.test.cc new file mode 100644 index 0000000000000000000000000000000000000000..cdbbe453c63f3516b576798057cfa6282a7b077a --- /dev/null +++ b/Socket/LLAddressing.test.cc @@ -0,0 +1,85 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.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. + +// Unit tests + +//#include "LLAddressing.test.hh" +//#include "LLAddressing.test.ih" + +// Custom includes +#include "LLAddressing.hh" + +#include <boost/test/auto_unit_test.hpp> +#include <boost/test/test_tools.hpp> + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +BOOST_AUTO_UNIT_TEST(llAddress) +{ + { + satcom::lib::LLSocketAddress a; + + BOOST_CHECK_EQUAL( a.protocol(), 0u ); + BOOST_CHECK_EQUAL( a.interface(), "" ); + BOOST_CHECK_EQUAL( a.arptype(), 0u ); + BOOST_CHECK_EQUAL( a.pkttype(), 0u ); + BOOST_CHECK_EQUAL( a.address(), "" ); + + a.address(satcom::lib::llAddress("05-10-1A-2f-25-30")); + BOOST_CHECK_EQUAL( satcom::lib::llAddress(a.address()), "05-10-1a-2f-25-30" ); + a.interface("lo"); + BOOST_CHECK_EQUAL( a.interface(), "lo" ); + a.protocol(123); + BOOST_CHECK_EQUAL( a.protocol(), 123u ); + } + + { + satcom::lib::LLSocketAddress a ( + satcom::lib::llAddress("11-12-13-14-15-16"), "lo"); + + BOOST_CHECK_EQUAL( a.protocol(), 0u ); + BOOST_CHECK_EQUAL( a.interface(), "lo" ); + BOOST_CHECK_EQUAL( a.arptype(), 0u ); + BOOST_CHECK_EQUAL( a.pkttype(), 0u ); + BOOST_CHECK_EQUAL( satcom::lib::llAddress(a.address()), "11-12-13-14-15-16" ); + } + + { + satcom::lib::LLSocketAddress a (123, "lo"); + + BOOST_CHECK_EQUAL( a.protocol(), 123u ); + BOOST_CHECK_EQUAL( a.interface(), "lo" ); + BOOST_CHECK_EQUAL( a.arptype(), 0u ); + BOOST_CHECK_EQUAL( a.pkttype(), 0u ); + BOOST_CHECK_EQUAL( satcom::lib::llAddress(a.address()), "" ); + } +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/PacketSocketHandle.cc b/Socket/PacketSocketHandle.cc new file mode 100644 index 0000000000000000000000000000000000000000..5288c2d0690bb08923d89a7f0e4dc395877aaca6 --- /dev/null +++ b/Socket/PacketSocketHandle.cc @@ -0,0 +1,125 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.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 "PacketSocketHandle.hh" +#include "PacketSocketHandle.ih" + +// Custom includes +#include <sys/types.h> +#include <sys/socket.h> +#include <netpacket/packet.h> +#include <net/ethernet.h> +#include <netinet/in.h> +#include <net/if.h> +#include <errno.h> + +//#include "PacketSocketHandle.mpp" +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +prefix_ void satcom::lib::PacketProtocol::init_client(SocketType type, int protocol) + const +{ + int socktype = SOCK_RAW; + if (type == DatagramSocket) + socktype = SOCK_DGRAM; + if (protocol == -1) + protocol = ETH_P_ALL; + int sock = ::socket(PF_PACKET, socktype, htons(protocol)); + if (sock < 0) + throw SystemException(errno); + body().fd(sock); +} + +prefix_ std::auto_ptr<satcom::lib::SocketProtocol> satcom::lib::PacketProtocol::clone() + const +{ + return std::auto_ptr<SocketProtocol>(new PacketProtocol()); +} + +prefix_ unsigned satcom::lib::PacketProtocol::available() + const +{ + if (! body().readable()) + return 0; + ssize_t l = ::recv(body().fd(),0,0,MSG_PEEK | MSG_TRUNC); + if (l < 0) + throw SystemException(errno); + return l; +} + +prefix_ bool satcom::lib::PacketProtocol::eof() + const +{ + return false; +} + +prefix_ void satcom::lib::PacketProtocol::promisc(std::string interface, PromiscMode mode) +{ + // 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 satcom::lib::PacketProtocol::do_mc(std::string interface, + detail::LLAddressCopier const & copier, bool add) +{ + struct packet_mreq mreq; + mreq.mr_ifindex = ::if_nametoindex(interface.c_str()); + if (mreq.mr_ifindex == 0) + throw SystemException(EINVAL); + mreq.mr_type = PACKET_MR_MULTICAST; + mreq.mr_alen = copier(&mreq.mr_address[0]); + if (::setsockopt(body().fd(),SOL_PACKET, + add ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP, + &mreq, sizeof(mreq)) < 0) + throw SystemException(errno); +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ +//#include "PacketSocketHandle.mpp" + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/PacketSocketHandle.ct b/Socket/PacketSocketHandle.ct new file mode 100644 index 0000000000000000000000000000000000000000..964ca76893bb281576cb9867cfe3468e66d826c3 --- /dev/null +++ b/Socket/PacketSocketHandle.ct @@ -0,0 +1,53 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.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 template functions + +#include "PacketSocketHandle.ih" + +// Custom includes + +#define prefix_ +///////////////////////////////ct.p//////////////////////////////////////// + +template <class ForwardRange> +prefix_ unsigned +satcom::lib::detail::Range_LLAddressCopier<ForwardRange>::operator()(unsigned char * target) + const +{ + std::size_t len (0); + typename boost::range_const_iterator<ForwardRange>::type i (boost::begin(range_)); + for (; i != boost::end(range_) && len<8; ++i, ++len, ++target) + *target = *i; + if (i != boost::end(range_)) + throw InvalidLLSocketAddressException(); + return len; +} + +///////////////////////////////ct.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/PacketSocketHandle.cti b/Socket/PacketSocketHandle.cti new file mode 100644 index 0000000000000000000000000000000000000000..2a28089f9b67d62828b83c2e0adb9cef6075b096 --- /dev/null +++ b/Socket/PacketSocketHandle.cti @@ -0,0 +1,67 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.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 inline template functions + +#include "PacketSocketHandle.ih" + +// Custom includes + +#define prefix_ inline +///////////////////////////////cti.p/////////////////////////////////////// + +template <class ForwardRange> +prefix_ void satcom::lib::PacketProtocol::mcAdd(std::string interface, + ForwardRange const & address) +{ + do_mc(interface,address,true); +} + +template <class ForwardRange> +prefix_ void satcom::lib::PacketProtocol::mcDrop(std::string interface, + ForwardRange const & address) +{ + do_mc(interface,address,false); +} + +template <class ForwardRange> +prefix_ satcom::lib::detail::Range_LLAddressCopier<ForwardRange>:: +Range_LLAddressCopier(ForwardRange const & range) + : range_ (range) +{} + +template <class ForwardRange> +prefix_ void satcom::lib::PacketProtocol::do_mc(std::string interface, + ForwardRange const & address, bool add) +{ + detail::Range_LLAddressCopier<ForwardRange> copier (address); + do_mc(interface, copier); +} + +///////////////////////////////cti.e/////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/PacketSocketHandle.hh b/Socket/PacketSocketHandle.hh new file mode 100644 index 0000000000000000000000000000000000000000..57869db0788d8256577227d3b65dbbe0c57fbe95 --- /dev/null +++ b/Socket/PacketSocketHandle.hh @@ -0,0 +1,98 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.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. + +#ifndef HH_PacketSocketHandle_ +#define HH_PacketSocketHandle_ 1 + +// Custom includes +#include "SocketPolicy.hh" +#include "SocketProtocol.hh" +#include "ProtocolClientSocketHandle.hh" +#include "LLAddressing.hh" +#include "FramingPolicy.hh" +#include "CommunicationPolicy.hh" +#include "ReadWritePolicy.hh" +#include "BufferingPolicy.hh" +#include "BSDSocketProtocol.hh" + +//#include "PacketSocketHandle.mpp" +#include "PacketSocketHandle.ih" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace satcom { +namespace lib { + + typedef MakeSocketPolicy< + LLAddressingPolicy, + DatagramFramingPolicy, + UnconnectedCommunicationPolicy, + ReadablePolicy, + WriteablePolicy, + SocketBufferingPolicy + >::policy Packet_Policy; + + class PacketProtocol + : public ConcreteSocketProtocol<Packet_Policy>, + public BSDSocketProtocol + { + public: + enum SocketType { RawSocket, DatagramSocket }; + + void init_client(SocketType type = RawSocket, int protocol = -1) const; + + std::auto_ptr<SocketProtocol> clone() const; + + enum PromiscMode { Promiscuous, AllMulticast, None }; + + void promisc(std::string interface, PromiscMode mode); + // See LLSocketAddress for a discussion/rationale for + // ForwardRange here + template <class ForwardRange> + void mcAdd(std::string interface, ForwardRange const & address); + template <class ForwardRange> + void mcDrop(std::string interface, ForwardRange const & address); + + unsigned available() const; + bool eof() const; + + private: + template<class ForwardRange> + void do_mc(std::string interface, ForwardRange const & address, bool add); + void do_mc(std::string interface, detail::LLAddressCopier const & copier, bool add); + }; + + typedef ProtocolClientSocketHandle<PacketProtocol> PacketSocketHandle; + +}} + +///////////////////////////////hh.e//////////////////////////////////////// +//#include "PacketSocketHandle.cci" +#include "PacketSocketHandle.ct" +#include "PacketSocketHandle.cti" +//#include "PacketSocketHandle.mpp" +#endif + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/PacketSocketHandle.ih b/Socket/PacketSocketHandle.ih new file mode 100644 index 0000000000000000000000000000000000000000..f7e10753b22d07178e17dfc7218301fc76f7314f --- /dev/null +++ b/Socket/PacketSocketHandle.ih @@ -0,0 +1,59 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.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. + +#ifndef IH_PacketSocketHandle_ +#define IH_PacketSocketHandle_ 1 + +// Custom includes + +///////////////////////////////ih.p//////////////////////////////////////// + +namespace satcom { +namespace lib { +namespace detail { + + struct LLAddressCopier + { + virtual ~LLAddressCopier() {} + virtual unsigned operator()(unsigned char * target) const = 0; + }; + + template <class ForwardRange> + struct Range_LLAddressCopier + { + Range_LLAddressCopier(ForwardRange const & range); + + unsigned operator()(unsigned char * target) const; + + ForwardRange const & range_; + }; + +}}} + +///////////////////////////////ih.e//////////////////////////////////////// +#endif + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/PacketSocketHandle.test.cc b/Socket/PacketSocketHandle.test.cc new file mode 100644 index 0000000000000000000000000000000000000000..ef3c25e522abe76cc0ff317e915b778b91649a1d --- /dev/null +++ b/Socket/PacketSocketHandle.test.cc @@ -0,0 +1,59 @@ +// $Id$ +// +// Copyright (C) 2006 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <stefan.bund@fokus.fraunhofer.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. + +// Unit tests + +//#include "PacketSocketHandle.test.hh" +//#include "PacketSocketHandle.test.ih" + +#include "PacketSocketHandle.hh" + +// Custom includes +#include <iostream> +#include <unistd.h> + +#include <boost/test/auto_unit_test.hpp> +#include <boost/test/test_tools.hpp> + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +BOOST_AUTO_UNIT_TEST(packetSocketHandle) +{ + // We have a Problem here .. this is only allowed, if we are root + if (getuid() != 0) { + BOOST_WARN_MESSAGE(getuid() == 0, "Cannot test PacketSocketHandle as non-root user"); + return; + } + { + satcom::lib::PacketSocketHandle sock; + } +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// c-file-style: "satcom" +// End: diff --git a/Socket/ProtocolClientSocketHandle.cti b/Socket/ProtocolClientSocketHandle.cti index a88accada46eef47de5f7b0649bf7cfc895133fb..d33f3e13d9df9fceeacd02f0396eee114df94a00 100644 --- a/Socket/ProtocolClientSocketHandle.cti +++ b/Socket/ProtocolClientSocketHandle.cti @@ -51,7 +51,9 @@ prefix_ SocketProtocol const & satcom::lib::ProtocolClientSocketHandle<SocketProtocol>::protocol() { BOOST_ASSERT( dynamic_cast<SocketProtocol const *>(&this->body().protocol()) ); - return static_cast<SocketProtocol const &>(this->body().protocol()); + // Need dynamic_cast here, since satcom::lib::SocketProtocol is a + // virtual base + return dynamic_cast<SocketProtocol const &>(this->body().protocol()); } template <class SocketProtocol> diff --git a/Socket/ProtocolServerSocketHandle.cti b/Socket/ProtocolServerSocketHandle.cti index 1ab9e71da1b58a85e07b5c05ae2987e12039df92..157bc5665110486ac7f0bbf2427dcc4b68b73338 100644 --- a/Socket/ProtocolServerSocketHandle.cti +++ b/Socket/ProtocolServerSocketHandle.cti @@ -44,7 +44,9 @@ prefix_ SocketProtocol const & satcom::lib::ProtocolServerSocketHandle<SocketProtocol>::protocol() { BOOST_ASSERT( dynamic_cast<SocketProtocol const *>(&this->body().protocol()) ); - return static_cast<SocketProtocol const &>(this->body().protocol()); + // Need dynamic_cast here, since satcom::lib::SocketProtocol is a + // virtual base + return dynamic_cast<SocketProtocol const &>(this->body().protocol()); } template <class SocketProtocol> diff --git a/Socket/SConscript b/Socket/SConscript index 03990f8e117717e45a0e1adc220aa1a01742a6bf..1375a71b66400082f73520ffe85b9189f52b1e3d 100644 --- a/Socket/SConscript +++ b/Socket/SConscript @@ -3,9 +3,13 @@ import SatSCons ########################################################################### +sources = SatSCons.GlobSources() + SatSCons.StandardTargets(env) SatSCons.Lib(env, library = 'Socket', - sources = SatSCons.GlobSources(), + sources = sources, LIBS = [ 'Utils' ]) + +SatSCons.Doxygen(env,sources) diff --git a/Socket/ServerSocketHandle.cti b/Socket/ServerSocketHandle.cti index add971bde991b5a3de0a9a3f588fb83a3bcf6bd3..17caf770eca62e3b2ed16841c63bd82d9ce078cd 100644 --- a/Socket/ServerSocketHandle.cti +++ b/Socket/ServerSocketHandle.cti @@ -62,6 +62,12 @@ prefix_ void satcom::lib::ServerSocketHandle<Policy>::bind(AddressParam addr) Policy::AddressingPolicy::bind(*this,addr); } +template <class Policy> +prefix_ void satcom::lib::ServerSocketHandle<Policy>::listen(unsigned backlog) +{ + Policy::CommunicationPolicy::listen(*this,backlog); +} + template <class Policy> prefix_ typename satcom::lib::ServerSocketHandle<Policy>::Address satcom::lib::ServerSocketHandle<Policy>::local() diff --git a/Socket/ServerSocketHandle.hh b/Socket/ServerSocketHandle.hh index ade54cecf8623859adfc3c61b7055cf5bc55c1be..28cbadac2afadfb13dc8a722484f50dfeed44b2c 100644 --- a/Socket/ServerSocketHandle.hh +++ b/Socket/ServerSocketHandle.hh @@ -78,6 +78,7 @@ namespace lib { ///@{ void bind (AddressParam addr); + void listen (unsigned backlog=0); Address local (); void local (Address & addr); diff --git a/Socket/SocketProtocol.cci b/Socket/SocketProtocol.cci index ae71b14042b2ab47d8cd6e837fbdedf2f9f78bb2..a10def64e3cbeeaccea5cac689dc0058baff3004 100644 --- a/Socket/SocketProtocol.cci +++ b/Socket/SocketProtocol.cci @@ -30,14 +30,14 @@ #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// -prefix_ satcom::lib::SocketProtocolHelper::SocketProtocolHelper() - : body_() +prefix_ satcom::lib::SocketProtocol::SocketProtocol() + : body_(0) {} -prefix_ satcom::lib::SocketProtocolHelper::~SocketProtocolHelper() +prefix_ satcom::lib::SocketProtocol::~SocketProtocol() {} -prefix_ satcom::lib::SocketBody & satcom::lib::SocketProtocolHelper::body() +prefix_ satcom::lib::SocketBody & satcom::lib::SocketProtocol::body() const { BOOST_ASSERT( body_ ); diff --git a/Socket/SocketProtocol.hh b/Socket/SocketProtocol.hh index 306d7f8fac5ea115b2f22ece36504f750cf9ae36..71bb15424493c7eeb312db74b10e7fcc329b71ca 100644 --- a/Socket/SocketProtocol.hh +++ b/Socket/SocketProtocol.hh @@ -36,23 +36,7 @@ namespace lib { class FileHandle; class SocketPolicyBase; - class SocketProtocolHelper - : boost::noncopyable - { - public: - SocketProtocolHelper(); - virtual ~SocketProtocolHelper() = 0; - - SocketBody & body() const; - - private: - SocketBody * body_; - - friend class SocketBody; - }; - - class SocketProtocol - : public virtual SocketProtocolHelper + class SocketProtocol : boost::noncopyable { public: /////////////////////////////////////////////////////////////////////////// @@ -62,6 +46,9 @@ namespace lib { ///\name Structors and default members ///@{ + SocketProtocol(); + virtual ~SocketProtocol() = 0; + // default default constructor // no copy // no conversion constructors @@ -69,6 +56,7 @@ namespace lib { ///@} /////////////////////////////////////////////////////////////////////////// + SocketBody & body() const; virtual SocketPolicyBase const & policy() const = 0; /////////////////////////////////////////////////////////////////////////// @@ -81,15 +69,14 @@ namespace lib { protected: private: - // That SocketBody instance owns us and controls our lifetime - // Do we need this ?? - }; + // backpointer to owning SocketBody instance + SocketBody * body_; + friend class SocketBody; + }; - /** \brief - */ template <class SocketPolicy> class ConcreteSocketProtocol - : public SocketProtocol + : public virtual SocketProtocol { public: /////////////////////////////////////////////////////////////////////////// diff --git a/Socket/TCPProtocol.cc b/Socket/TCPProtocol.cc index 835504471a30b7a2f4af4e7b5700444cc14c044c..f444ac3bc849be6946c7a6ccf04f6c51c9a7acc8 100644 --- a/Socket/TCPProtocol.cc +++ b/Socket/TCPProtocol.cc @@ -73,6 +73,19 @@ prefix_ unsigned satcom::lib::TCPProtocol::siocoutq() return n; } +prefix_ unsigned satcom::lib::TCPProtocol::available() + const +{ + return siocinq(); +} + +prefix_ bool satcom::lib::TCPProtocol::eof() + const +{ + return body().readable() && available()==0; +} + + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "TCPProtocol.mpp" diff --git a/Socket/TCPProtocol.hh b/Socket/TCPProtocol.hh index fc3a80e4808e7f6e6b87856c2854ec6a162ae23d..adf029fea9e108f38646969b0fa4bed38375e6a1 100644 --- a/Socket/TCPProtocol.hh +++ b/Socket/TCPProtocol.hh @@ -33,7 +33,7 @@ namespace satcom { namespace lib { class TCPProtocol - : public virtual SocketProtocolHelper + : public virtual SocketProtocol { public: bool nodelay() const; @@ -41,6 +41,8 @@ namespace lib { unsigned siocinq() const; unsigned siocoutq() const; + unsigned available() const; + bool eof() const; }; }} diff --git a/Socket/TCPSocketHandle.cc b/Socket/TCPSocketHandle.cc index 6b6835a7665c47dc81573afa3c872447569ec96a..0eb1446df18aba288d211ca3c30005c18d25022c 100644 --- a/Socket/TCPSocketHandle.cc +++ b/Socket/TCPSocketHandle.cc @@ -62,14 +62,14 @@ prefix_ void satcom::lib::TCPv4SocketProtocol::init_server() body().fd(sock); } -prefix_ void -satcom::lib::TCPv4SocketProtocol::init_server(INet4Address const & address) +prefix_ void satcom::lib::TCPv4SocketProtocol::init_server(INet4Address const & address, + unsigned backlog) const { init_server(); bind(address); reuseaddr(true); - if (::listen(body().fd(),1) < 0) + if (::listen(body().fd(),backlog) < 0) throw SystemException(errno); } @@ -79,18 +79,6 @@ prefix_ std::auto_ptr<satcom::lib::SocketProtocol> satcom::lib::TCPv4SocketProto return std::auto_ptr<SocketProtocol>(new TCPv4SocketProtocol()); } -prefix_ unsigned satcom::lib::TCPv4SocketProtocol::available() - const -{ - return siocinq(); -} - -prefix_ bool satcom::lib::TCPv4SocketProtocol::eof() - const -{ - return body().readable() && available()==0; -} - ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "TCPSocketHandle.mpp" diff --git a/Socket/TCPSocketHandle.hh b/Socket/TCPSocketHandle.hh index d7d85454c0d692cb13d5b154978ec7e2909f59e2..f7024246096ca329e954dc2ce902fd14fd449daf 100644 --- a/Socket/TCPSocketHandle.hh +++ b/Socket/TCPSocketHandle.hh @@ -27,7 +27,7 @@ #include "INetProtocol.hh" #include "TCPProtocol.hh" #include "BSDSocketProtocol.hh" -#include "StreamFramingPolicy.hh" +#include "FramingPolicy.hh" #include "CommunicationPolicy.hh" #include "ReadWritePolicy.hh" #include "BufferingPolicy.hh" @@ -53,7 +53,8 @@ namespace lib { : public ConcreteSocketProtocol<TCPv4Socket_Policy>, public IPv4Protocol, public TCPProtocol, - public BSDSocketProtocol + public BSDSocketProtocol, + public AddressableBSDSocketProtocol { public: /////////////////////////////////////////////////////////////////////////// @@ -62,29 +63,25 @@ namespace lib { void init_client() const; void init_client(INet4Address const & address) const; void init_server() const; - void init_server(INet4Address const & address) const; + void init_server(INet4Address const & address, unsigned backlog=1) const; std::auto_ptr<SocketProtocol> clone() const; - unsigned available() const; - bool eof() const; }; typedef ProtocolClientSocketHandle<TCPv4SocketProtocol> TCPv4ClientSocketHandle; typedef ProtocolServerSocketHandle<TCPv4SocketProtocol> TCPv4ServerSocketHandle; typedef MakeSocketPolicy< - INet6AddressingPolicy, - StreamFramingPolicy, - ConnectedCommunicationPolicy, - ReadablePolicy, - WriteablePolicy, - SocketBufferingPolicy + TCPv4Socket_Policy, + INet6AddressingPolicy >::policy TCPv6Socket_Policy; class TCPv6SocketProtocol : public ConcreteSocketProtocol<TCPv6Socket_Policy>, public IPv6Protocol, - public TCPProtocol + public TCPProtocol, + public BSDSocketProtocol, + public AddressableBSDSocketProtocol { // TODO: Implement }; diff --git a/Socket/TCPSocketHandle.test.cc b/Socket/TCPSocketHandle.test.cc index 9465419e14c2ab7b37d2127327c90b5bbe592618..b8792af3cdbfca1efd0e5d862a453f5436b9594e 100644 --- a/Socket/TCPSocketHandle.test.cc +++ b/Socket/TCPSocketHandle.test.cc @@ -140,6 +140,8 @@ 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); @@ -149,6 +151,37 @@ BOOST_AUTO_UNIT_TEST(tcpv4ClientSocketHandle) BOOST_CHECK( sock.eof() ); BOOST_CHECK( !sock ); } + + { + satcom::lib::TCPv4ClientSocketHandle sock; + + // Since this is a TCP socket, most of the calls will fail or + // are at least not sensible ... + // I'll have to move those to a UDPSocket test ... they should + // realy only be in the UDP Protocol implementation + // TODO: Move all these into a IPv4MulticastProtocol class and + // use that on a UDPv4SocketHandle implementation + BOOST_CHECK_NO_THROW( sock.protocol().mcTTL() ); + BOOST_CHECK_THROW( sock.protocol().mcTTL(1), satcom::lib::SystemException ); + BOOST_CHECK_NO_THROW( sock.protocol().mcLoop() ); + BOOST_CHECK_NO_THROW( sock.protocol().mcLoop(false) ); + BOOST_CHECK_NO_THROW( sock.protocol().mcAddMembership("224.0.0.1:0") ); + BOOST_CHECK_NO_THROW( sock.protocol().mcAddMembership("224.0.0.1:0","127.0.0.1:0") ); + BOOST_CHECK_NO_THROW( sock.protocol().mcDropMembership("224.0.0.1:0","127.0.0.1:0") ); + BOOST_CHECK_NO_THROW( sock.protocol().mcDropMembership("224.0.0.1:0") ); + BOOST_CHECK_THROW( sock.protocol().mcIface("lo"), satcom::lib::SystemException ); + + // The following setsockopts are hard to REALLY test ... + BOOST_CHECK_NO_THROW( sock.protocol().nodelay(true) ); + BOOST_CHECK( sock.protocol().nodelay() ); + BOOST_CHECK_EQUAL( sock.protocol().siocinq(), 0u ); + BOOST_CHECK_EQUAL( sock.protocol().siocoutq(), 0u ); + + BOOST_CHECK_NO_THROW( sock.protocol().reuseaddr(true) ); + BOOST_CHECK( sock.protocol().reuseaddr() ); + BOOST_CHECK_NO_THROW( sock.protocol().linger(true,0) ); + BOOST_CHECK( sock.protocol().linger() == std::make_pair(true, 0u) ); + } } ///////////////////////////////////////////////////////////////////////////