From: g0dil Date: Fri, 10 Oct 2008 08:57:54 +0000 (+0000) Subject: Socket: Add missing InetSocketProtocol baseclass to relevant socket protocols X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=28e21cc5680c097e7daed8c412ee32cf26a75a60;p=senf.git Socket: Add missing InetSocketProtocol baseclass to relevant socket protocols Examples/MultiMCLoop: Add example and test for multiple local multicast socket forwarding PPI: Emit throttle/unthrottle messages on connector connect git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@936 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Examples/MultiMCLoop/MultiMCLoop.cc b/Examples/MultiMCLoop/MultiMCLoop.cc new file mode 100644 index 0000000..6f7540d --- /dev/null +++ b/Examples/MultiMCLoop/MultiMCLoop.cc @@ -0,0 +1,197 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief MultiMCLoop non-inline non-template implementation */ + +//#include "MultiMCLoop.hh" +//#include "MultiMCLoop.ih" + +// Custom includes +#include +#include +#include +#include +#include + +//#include "MultiMCLoop.mpp" +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +typedef senf::UDPv4ClientSocketHandle UDPSocket; + +class MCReader +{ + std::string name; + UDPSocket socket; + senf::scheduler::FdEvent event; + + void handler(int events); + +public: + MCReader(unsigned n, std::string const & name, UDPSocket::Address const & group); +}; + +prefix_ MCReader::MCReader(unsigned n, std::string const & name_, + UDPSocket::Address const & group) + : name (name_), socket (), + event (name, senf::membind(&MCReader::handler, this), socket, + senf::scheduler::FdEvent::EV_READ) +{ + socket.protocol().reuseaddr(true); + socket.bind(group); + socket.protocol().bindInterface("dummy0"); + socket.protocol().mcAddMembership(group.address(), "dummy0"); +} + +prefix_ void MCReader::handler(int events) +{ + std::cout << "I " << name << ": " << socket.read() << "\n"; +} + +/////////////////////////////////////////////////////////////////////////// + +class MCWriter +{ + std::string name; + UDPSocket::Address group; + UDPSocket socket; + senf::ClockService::clock_type interval; + senf::scheduler::TimerEvent event; + unsigned count; + + void handler(); + +public: + MCWriter(std::string const & name, UDPSocket::Address const & group, + senf::ClockService::clock_type interval); +}; + +prefix_ MCWriter::MCWriter(std::string const & name_, UDPSocket::Address const & group_, + senf::ClockService::clock_type interval_) + : name (name_), group (group_), socket (), interval (interval_), + event (name, senf::membind(&MCWriter::handler, this), senf::ClockService::now() + interval), + count (0) +{} + +prefix_ void MCWriter::handler() +{ + std::stringstream ss; + ss << name << "-" << ++count; + std::cout << "O " << name << ": " << ss.str() << "\n"; + socket.writeto(group, ss.str()); + event.timeout(senf::scheduler::eventTime() + interval); +} + +/////////////////////////////////////////////////////////////////////////// + +class IfSetup +{ + std::string iface; + +public: + IfSetup(std::string const & iface_); + ~IfSetup(); + + void sys(std::string const & cmd); + + struct SystemException : public senf::Exception + { SystemException() : senf::Exception("IfSetup::SystemException") {} }; + +}; + +prefix_ IfSetup::IfSetup(std::string const & iface_) + : iface (iface_) +{ + sys((boost::format("ifconfig %s up") % iface).str()); + sys((boost::format("ifconfig %s 192.168.192.1") % iface).str()); + sys((boost::format("ip route add 224.0.0.0/4 dev %s") % iface).str()); +} + +prefix_ IfSetup::~IfSetup() +{ + try { + sys((boost::format("ifconfig %s down") % iface).str()); + } + catch (SystemException & ex) { + std::cerr << ex.what() << "\n"; + } +} + +prefix_ void IfSetup::sys(std::string const & cmd) +{ + int rv (system(cmd.c_str())); + if (rv != 0) + throw SystemException() << ": code " << rv << ": " << cmd; +} + +/////////////////////////////////////////////////////////////////////////// + +void sigintHandler(siginfo_t const &) +{ + senf::scheduler::terminate(); +} + +/////////////////////////////////////////////////////////////////////////// + +int main(int argc, char * argv[]) +{ + try { + IfSetup setup ("dummy0"); + + senf::scheduler::SignalEvent sigint (SIGINT, &sigintHandler); + + UDPSocket::Address g1 ("225.1:43434"); + UDPSocket::Address g2 ("225.2:43434"); + + MCReader r1g1 (1u, "r1g1", g1); + MCReader r2g1 (2u, "r2g1", g1); + MCReader r1g2 (3u, "r1g2", g2); + MCReader r2g2 (4u, "r2g2", g2); + + MCWriter w1g1 ("w1g1", g1, senf::ClockService::milliseconds(600)); + MCWriter w2g1 ("w2g1", g1, senf::ClockService::milliseconds(800)); + MCWriter w1g2 ("w1g2", g2, senf::ClockService::milliseconds(700)); + MCWriter w2g2 ("w2g2", g2, senf::ClockService::milliseconds(900)); + + senf::scheduler::process(); + } + catch (std::exception const & ex) { + std::cerr << ex.what() << "\n"; + return 1; + } +}; + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ +//#include "MultiMCLoop.mpp" + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u multimcloop" +// End: diff --git a/Examples/MultiMCLoop/SConscript b/Examples/MultiMCLoop/SConscript new file mode 100644 index 0000000..83a6234 --- /dev/null +++ b/Examples/MultiMCLoop/SConscript @@ -0,0 +1,7 @@ +Import('env') +import SENFSCons + +########################################################################### + +SENFSCons.Binary(env, 'multimcloop', [ 'MultiMCLoop.cc' ], + LIBS = [ 'Scheduler', 'Socket', 'Utils' ]) diff --git a/PPI/Connectors.cc b/PPI/Connectors.cc index e11e5e2..ab1a038 100644 --- a/PPI/Connectors.cc +++ b/PPI/Connectors.cc @@ -29,6 +29,7 @@ // Custom includes #include "Route.hh" #include "Module.hh" +#include "ModuleManager.hh" //#include "Connectors.mpp" #define prefix_ @@ -51,6 +52,9 @@ prefix_ void senf::ppi::connector::Connector::connect(Connector & target) peer_ = & target; target.peer_ = this; + + if (ModuleManager::instance().running()) + v_init(); } prefix_ std::type_info const & senf::ppi::connector::Connector::packetTypeID() @@ -64,6 +68,24 @@ prefix_ std::type_info const & senf::ppi::connector::Connector::packetTypeID() //////////////////////////////////////// // private members +prefix_ void senf::ppi::connector::PassiveConnector::v_init() +{ + Routes::const_iterator i (routes_.begin()); + Routes::const_iterator const i_end (routes_.end()); + for (; i != i_end; ++i) + if ((*i)->throttled()) + break; + if (i == i_end) + remoteThrottled_ = false; + if (throttled()) + emitThrottle(); + else + emitUnthrottle(); +} + +prefix_ void senf::ppi::connector::PassiveConnector::v_unthrottleEvent() +{} + prefix_ void senf::ppi::connector::PassiveConnector::notifyUnthrottle() { if (throttled() && !nativeThrottled_) { @@ -87,24 +109,36 @@ prefix_ void senf::ppi::connector::PassiveConnector::notifyUnthrottle() //////////////////////////////////////// // private members +prefix_ void senf::ppi::connector::ActiveConnector::v_init() +{ + if (! connected()) + notifyThrottle(); +} + prefix_ void senf::ppi::connector::ActiveConnector::notifyThrottle() { - if (throttleCallback_) - throttleCallback_(); - NotifyRoutes::const_iterator i (notifyRoutes_.begin()); - NotifyRoutes::const_iterator const i_end (notifyRoutes_.end()); - for (; i != i_end; ++i) - (*i)->notifyThrottle(); + if (! throttled_) { + throttled_ = true; + if (throttleCallback_) + throttleCallback_(); + NotifyRoutes::const_iterator i (notifyRoutes_.begin()); + NotifyRoutes::const_iterator const i_end (notifyRoutes_.end()); + for (; i != i_end; ++i) + (*i)->notifyThrottle(); + } } prefix_ void senf::ppi::connector::ActiveConnector::notifyUnthrottle() { - if (unthrottleCallback_) - unthrottleCallback_(); - NotifyRoutes::const_iterator i (notifyRoutes_.begin()); - NotifyRoutes::const_iterator const i_end (notifyRoutes_.end()); - for (; i != i_end; ++i) - (*i)->notifyUnthrottle(); + if (throttled_) { + throttled_ = false; + if (unthrottleCallback_) + unthrottleCallback_(); + NotifyRoutes::const_iterator i (notifyRoutes_.begin()); + NotifyRoutes::const_iterator const i_end (notifyRoutes_.end()); + for (; i != i_end; ++i) + (*i)->notifyUnthrottle(); + } } prefix_ void senf::ppi::connector::ActiveConnector::registerRoute(ForwardingRoute & route) diff --git a/PPI/Connectors.cci b/PPI/Connectors.cci index 8db9cd9..12c14a1 100644 --- a/PPI/Connectors.cci +++ b/PPI/Connectors.cci @@ -56,10 +56,16 @@ prefix_ senf::ppi::connector::Connector::Connector() prefix_ senf::ppi::connector::Connector::~Connector() { - if (peer_) + if (connected()) peer_->peer_ = 0; } +prefix_ bool senf::ppi::connector::Connector::connected() + const +{ + return peer_; +} + //////////////////////////////////////// // private members @@ -68,6 +74,11 @@ prefix_ void senf::ppi::connector::Connector::setModule(module::Module & module) module_ = &module; } +prefix_ void senf::ppi::connector::Connector::init() +{ + v_init(); +} + /////////////////////////////////////////////////////////////////////////// // senf::ppi::connector::PassiveConnector @@ -88,13 +99,16 @@ prefix_ bool senf::ppi::connector::PassiveConnector::throttled() prefix_ void senf::ppi::connector::PassiveConnector::emitThrottle() { - peer().notifyThrottle(); + if (connected()) + peer().notifyThrottle(); } prefix_ void senf::ppi::connector::PassiveConnector::emitUnthrottle() { - peer().notifyUnthrottle(); - v_unthrottleEvent(); + if (connected()) { + peer().notifyUnthrottle(); + v_unthrottleEvent(); + } } prefix_ void senf::ppi::connector::PassiveConnector::notifyThrottle() @@ -107,9 +121,6 @@ prefix_ void senf::ppi::connector::PassiveConnector::notifyThrottle() remoteThrottled_ = true; } -prefix_ void senf::ppi::connector::PassiveConnector::v_unthrottleEvent() -{} - prefix_ void senf::ppi::connector::PassiveConnector::registerRoute(ForwardingRoute & route) { routes_.push_back(&route); @@ -177,14 +188,14 @@ prefix_ void senf::ppi::connector::ActiveConnector::onUnthrottle() prefix_ bool senf::ppi::connector::ActiveConnector::throttled() const { - return peer().throttled(); + return ! connected() || peer().throttled(); } //////////////////////////////////////// // protected members prefix_ senf::ppi::connector::ActiveConnector::ActiveConnector() - : throttleCallback_(), unthrottleCallback_(), notifyRoutes_() + : throttleCallback_(), unthrottleCallback_(), notifyRoutes_(), throttled_(false) {} /////////////////////////////////////////////////////////////////////////// @@ -261,7 +272,8 @@ prefix_ senf::ppi::connector::InputConnector & senf::ppi::connector::OutputConne prefix_ void senf::ppi::connector::OutputConnector::operator()(Packet p) { - peer().enqueue(p); + if (connected()) + peer().enqueue(p); } prefix_ void senf::ppi::connector::OutputConnector::write(Packet p) @@ -329,12 +341,13 @@ prefix_ senf::ppi::connector::GenericPassiveOutput & senf::ppi::connector::Gener prefix_ bool senf::ppi::connector::GenericActiveInput::boolean_test() const { - return ! empty() || ! peer().throttled(); + return ! empty() || (connected() && ! peer().throttled()); } prefix_ void senf::ppi::connector::GenericActiveInput::request() { - peer().emit(); + if (connected()) + peer().emit(); } prefix_ senf::ppi::connector::GenericActiveInput::GenericActiveInput() @@ -352,7 +365,7 @@ prefix_ senf::ppi::connector::GenericPassiveInput & senf::ppi::connector::Generi prefix_ bool senf::ppi::connector::GenericActiveOutput::boolean_test() const { - return ! peer().throttled(); + return connected() && ! peer().throttled(); } prefix_ void senf::ppi::connector::GenericActiveOutput::connect(GenericPassiveInput & target) diff --git a/PPI/Connectors.hh b/PPI/Connectors.hh index 2750224..0874551 100644 --- a/PPI/Connectors.hh +++ b/PPI/Connectors.hh @@ -53,11 +53,11 @@ namespace connector { \li it has an (optional) packet type \e Active connectors are activated from within the module, \e passive connectors are - signaled by the external framework. \e Input modules receive packets, \e output modules send - packets. + signaled by the external framework. \e Input connectors receive packets, \e output + connectors send packets. All passive connectors call some onRequest callback whenever I/O needs to be performed. All - input modules possess a packet queue. + input connectors possess a packet queue. We therefore have 4 connector types each of which is parameterized by the type of packet traversing the connector: @@ -90,7 +90,7 @@ namespace connector { private: void onRequest() { // 'input()' will return a senf::EthernetPacket packet handle - try { output( input().find() ); } + try { output( input().find() ); } catch (senf::InvalidPacketChainException & ex) { ; } } }; @@ -128,16 +128,20 @@ namespace connector { Connector & peer() const; ///< Get peer connected to this connector module::Module & module() const; ///< Get this connectors containing module + bool connected() const; ///< \c true, if connector connected, \c false otherwise + protected: Connector(); virtual ~Connector(); void connect(Connector & target); - + private: virtual std::type_info const & packetTypeID(); void setModule(module::Module & module); + void init(); + virtual void v_init() = 0; Connector * peer_; module::Module * module_; @@ -193,6 +197,8 @@ namespace connector { void emit(); private: + virtual void v_init(); + // Called by the routing to change the remote throttling state void notifyThrottle(); ///< Forward a throttle notification to this connector void notifyUnthrottle(); ///< Forward an unthrottle notification to this connector @@ -268,6 +274,8 @@ namespace connector { ActiveConnector(); private: + virtual void v_init(); + // called by the peer() to forward throttling notifications void notifyThrottle(); void notifyUnthrottle(); @@ -281,6 +289,8 @@ namespace connector { typedef std::vector NotifyRoutes; NotifyRoutes notifyRoutes_; + bool throttled_; + friend class senf::ppi::ForwardingRoute; friend class PassiveConnector; }; @@ -560,7 +570,7 @@ namespace connector { { public: operator()(PacketType packet); ///< Send out a packet - write(PacketType packet); ///< Alias for operator() + void write(PacketType packet); ///< Alias for operator() }; /** \brief Connector passively providing packets @@ -580,7 +590,7 @@ namespace connector { { public: operator()(PacketType packet); ///< Send out a packet - write(PacketType packet); ///< Alias for operator() + void write(PacketType packet); ///< Alias for operator() }; #endif diff --git a/PPI/DebugModules.cci b/PPI/DebugModules.cci index 09fbda1..d1dc071 100644 --- a/PPI/DebugModules.cci +++ b/PPI/DebugModules.cci @@ -88,7 +88,7 @@ senf::ppi::module::debug::PassiveSource::size() //////////////////////////////////////// // private members -prefix_ void senf::ppi::module::debug::PassiveSource::init() +prefix_ void senf::ppi::module::debug::PassiveSource::v_init() { if (empty()) output.throttle(); diff --git a/PPI/DebugModules.hh b/PPI/DebugModules.hh index 536a10c..0d7db73 100644 --- a/PPI/DebugModules.hh +++ b/PPI/DebugModules.hh @@ -120,7 +120,7 @@ namespace debug { private: void request(); - void init(); + virtual void v_init(); Queue packets_; }; diff --git a/PPI/Module.cci b/PPI/Module.cci index 35df877..6a7be73 100644 --- a/PPI/Module.cci +++ b/PPI/Module.cci @@ -39,6 +39,15 @@ // private members prefix_ void senf::ppi::module::Module::init() +{ + ConnectorRegistry::iterator i (connectorRegistry_.begin()); + ConnectorRegistry::iterator i_end (connectorRegistry_.end()); + for (; i != i_end; ++i) + (*i)->init(); + v_init(); +} + +prefix_ void senf::ppi::module::Module::v_init() {} prefix_ senf::ppi::EventManager & senf::ppi::module::Module::eventManager() diff --git a/PPI/Module.hh b/PPI/Module.hh index 1c6aba1..9c19e6c 100644 --- a/PPI/Module.hh +++ b/PPI/Module.hh @@ -289,7 +289,8 @@ namespace module { private: #endif - virtual void init(); ///< Called just before the network is run + void init(); + virtual void v_init(); #ifndef DOXYGEN public: diff --git a/PPI/PassiveQueue.cc b/PPI/PassiveQueue.cc index 08eb690..144c30e 100644 --- a/PPI/PassiveQueue.cc +++ b/PPI/PassiveQueue.cc @@ -38,9 +38,10 @@ //////////////////////////////////////// // private members -prefix_ void senf::ppi::module::PassiveQueue::init() +prefix_ void senf::ppi::module::PassiveQueue::v_init() { - output.throttle(); + if (!input) + output.throttle(); } prefix_ void senf::ppi::module::PassiveQueue::onInput() diff --git a/PPI/PassiveQueue.hh b/PPI/PassiveQueue.hh index 2e118cc..2412c4a 100644 --- a/PPI/PassiveQueue.hh +++ b/PPI/PassiveQueue.hh @@ -70,7 +70,7 @@ namespace module { \see connector::GenericPassiveInput::qdisc() */ private: - void init(); + virtual void v_init(); void onInput(); void onOutput(); diff --git a/Socket/Protocols/INet/MulticastSocketProtocol.cc b/Socket/Protocols/INet/MulticastSocketProtocol.cc index b833144..8ec8629 100644 --- a/Socket/Protocols/INet/MulticastSocketProtocol.cc +++ b/Socket/Protocols/INet/MulticastSocketProtocol.cc @@ -242,6 +242,7 @@ prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address co prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address const & mcAddr, std::string const & iface) + const { if (mcAddr.inet4Mapped()) { struct ip_mreqn mreqn; @@ -311,28 +312,33 @@ senf::INet6MulticastSocketProtocol::mcDropMembership(INet6Address const & mcAddr } namespace { -void mc6SSMSourceRequest(int operation, int fd, senf::INet6Address const & group, - senf::INet6Address const & source, int const & ifacei) -{ - struct group_source_req req; - ::memset(&req, 0, sizeof(req)); - req.gsr_interface = ifacei; - req.gsr_group.ss_family = AF_INET6; - std::copy(group.begin(), group.end(), - reinterpret_cast(req.gsr_group).sin6_addr.s6_addr); - req.gsr_source.ss_family = AF_INET6; - std::copy(source.begin(), source.end(), - reinterpret_cast(req.gsr_source).sin6_addr.s6_addr); - if (::setsockopt(fd, SOL_IPV6, MCAST_JOIN_SOURCE_GROUP, &req, sizeof(req)) < 0) - SENF_THROW_SYSTEM_EXCEPTION("::setsockopt()"); -} -void mc6SSMSourceRequest(int operation, int fd, senf::INet6Address const & group, - senf::INet6Address const & source, std::string const & iface) -{ - int ifacei = if_nametoindex(iface.c_str()); - if (ifacei == 0) - throw senf::SystemException("::if_nametoindex()", ENOENT SENF_EXC_DEBUGINFO); - mc6SSMSourceRequest(operation, fd, group, source, ifacei); + + void mc6SSMSourceRequest(int operation, int fd, senf::INet6Address const & group, + senf::INet6Address const & source, int ifacei) + { + struct group_source_req req; + ::memset(&req, 0, sizeof(req)); + req.gsr_interface = ifacei; + req.gsr_group.ss_family = AF_INET6; + std::copy(group.begin(), group.end(), + reinterpret_cast(req.gsr_group).sin6_addr.s6_addr); + req.gsr_source.ss_family = AF_INET6; + std::copy(source.begin(), source.end(), + reinterpret_cast(req.gsr_source).sin6_addr.s6_addr); + if (::setsockopt(fd, SOL_IPV6, MCAST_JOIN_SOURCE_GROUP, &req, sizeof(req)) < 0) + SENF_THROW_SYSTEM_EXCEPTION("::setsockopt()"); + } + + void mc6SSMSourceRequest(int operation, int fd, senf::INet6Address const & group, + senf::INet6Address const & source, std::string const & iface) + { + int ifacei (0); + if (! iface.empty()) { + ifacei = if_nametoindex(iface.c_str()); + if (ifacei == 0) + throw senf::SystemException("::if_nametoindex()", ENOENT SENF_EXC_DEBUGINFO); + } + mc6SSMSourceRequest(operation, fd, group, source, ifacei); } } @@ -352,12 +358,6 @@ prefix_ void senf::INet6MulticastSocketProtocol::mcJoinSSMSource(INet6Address co { mc6SSMSourceRequest(MCAST_JOIN_SOURCE_GROUP, fd(), group, source, ifacei); } -prefix_ void senf::INet6MulticastSocketProtocol::mcJoinSSMSource(INet6Address const & group, - INet6Address const & source) - const -{ - mc6SSMSourceRequest(MCAST_JOIN_SOURCE_GROUP, fd(), group, source, 0); -} prefix_ void senf::INet6MulticastSocketProtocol::mcLeaveSSMSource(INet6Address const & group, INet6Address const & source, diff --git a/Socket/Protocols/INet/MulticastSocketProtocol.hh b/Socket/Protocols/INet/MulticastSocketProtocol.hh index 90f74e7..3dc6838 100644 --- a/Socket/Protocols/INet/MulticastSocketProtocol.hh +++ b/Socket/Protocols/INet/MulticastSocketProtocol.hh @@ -65,12 +65,17 @@ namespace senf { bool mcLoop() const; ///< Return current multicast loopback state. void mcLoop(bool value) const; ///< Set multicast loopback state - /**< If set to false via \c mcLoop(value) multicast messages will not be looped back to local sockets. Default value is \c true (1). */ + /**< If set to false via \c mcLoop(value) multicast messages + will not be looped back to local sockets. Default value + is \c true. */ void mcIface(std::string const & iface = std::string()) const; ///< Set multicast send interface of the socket /**< \param[in] iface name of interface to send multicast - data from */ + data from + + Under current linux versions this option is broken at + best. Don't use. */ }; /** \brief Multicast protocol facet for INet4 addressable multicast enabled sockets @@ -85,8 +90,7 @@ namespace senf { groups received. The group is joined on the default interface. \param[in] mcAddr address of group to join */ - void mcAddMembership(INet4Address const & mcAddr, INet4Address const & localAddr) - const; + void mcAddMembership(INet4Address const & mcAddr, INet4Address const & localAddr) const; ///< join multicast group on a specific interface /**< This member will add \a mcAddr to the list of multicast groups received. The group is joined on the interface @@ -165,7 +169,7 @@ namespace senf { groups received. The group is joined on the default interface. \param[in] mcAddr address of group to join */ - void mcAddMembership(INet6Address const & mcAddr, std::string const & iface); + void mcAddMembership(INet6Address const & mcAddr, std::string const & iface) const; ///< join multicast group on a specific interface /**< This member will add \a mcAddr to the list of multicast groups received. The group is joined on the given @@ -196,9 +200,10 @@ namespace senf { \param[in] group multicast group to join \param[in] source SSM multicast source to join the group on - \param[in] iface interface to join the group on */ + \param[in] iface interface to join the group on. If set + to the empty string, use the default interface. */ void mcJoinSSMSource(INet6Address const & group, INet6Address const & source, - int ifacei) const; + int ifacei = 0) const; ///< join SSM multicast group /**< This call will join the multicast group \a group for traffic from \a source. A single group may be joined @@ -206,14 +211,7 @@ namespace senf { \param[in] group multicast group to join \param[in] source SSM multicast source to join the group on - \param[in] ifacei interface index to join the group on */ - void mcJoinSSMSource(INet6Address const & group, INet6Address const & source) const; - ///< join SSM multicast group - /**< This call will join the multicast group \a group for - traffic from \a source. A single group may be joined - multiple times on different sources. - \param[in] group multicast group to join - \param[in] source SSM multicast source to join the + \param[in] ifacei optional interface index to join the group on */ void mcLeaveSSMSource(INet6Address const & group, INet6Address const & source, std::string const & iface) const; diff --git a/Socket/Protocols/INet/RawINetSocketProtocol.hh b/Socket/Protocols/INet/RawINetSocketProtocol.hh index 6af734a..abf866b 100644 --- a/Socket/Protocols/INet/RawINetSocketProtocol.hh +++ b/Socket/Protocols/INet/RawINetSocketProtocol.hh @@ -44,7 +44,7 @@ namespace senf { */ class RawINetSocketProtocol - : public virtual SocketProtocol + : public virtual INetSocketProtocol { public: ///\name Abstract Interface Implementation diff --git a/Socket/Protocols/INet/TCPSocketProtocol.hh b/Socket/Protocols/INet/TCPSocketProtocol.hh index b9850d1..232d38a 100644 --- a/Socket/Protocols/INet/TCPSocketProtocol.hh +++ b/Socket/Protocols/INet/TCPSocketProtocol.hh @@ -29,6 +29,7 @@ // Custom includes #include "../../../Socket/SocketProtocol.hh" +#include "INetSocketProtocol.hh" //#include "TCPSocketProtocol.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -44,7 +45,7 @@ namespace senf { which are available on any TCP socket. */ class TCPSocketProtocol - : public virtual SocketProtocol + : public virtual INetSocketProtocol { public: bool nodelay() const; ///< Check current \c SO_NODELAY status diff --git a/Socket/Protocols/INet/UDPSocketProtocol.hh b/Socket/Protocols/INet/UDPSocketProtocol.hh index f1f89eb..e869e5e 100644 --- a/Socket/Protocols/INet/UDPSocketProtocol.hh +++ b/Socket/Protocols/INet/UDPSocketProtocol.hh @@ -30,6 +30,7 @@ // Custom includes #include "../../../Socket/SocketProtocol.hh" #include "INetAddressing.hh" +#include "INetSocketProtocol.hh" //#include "UDPSocketProtocol.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -45,7 +46,7 @@ namespace senf { which are available on any UDP socket. */ class UDPSocketProtocol - : public virtual SocketProtocol + : public virtual INetSocketProtocol { public: ///\name Abstract Interface Implementation