\see \ref console_testserver for a complete example application
- \section intro_usage Using the Console: Configuration files, Network console, ...
+ \section intro_usage Using the Console: Configuration files, Network console
There are several ways to access the node tree:
\li By parsing configuration files
SENF_THROW_SYSTEM_EXCEPTION("");
}
+namespace {
+ void mc4SSMSourceRequest(int operation, int fd, senf::INet4Address const & group,
+ senf::INet4Address const & source, std::string const & iface)
+ {
+ struct group_source_req req;
+ ::memset(&req, 0, sizeof(req));
+ req.gsr_interface = if_nametoindex(iface.c_str());
+ if (req.gsr_interface == 0)
+ throw senf::SystemException("::if_nametoindex()", ENOENT SENF_EXC_DEBUGINFO);
+ req.gsr_group.ss_family = AF_INET;
+ reinterpret_cast<struct sockaddr_in&>(req.gsr_group).sin_addr.s_addr = group.inaddr();
+ req.gsr_source.ss_family = AF_INET;
+ reinterpret_cast<struct sockaddr_in&>(req.gsr_source).sin_addr.s_addr = source.inaddr();
+ if (::setsockopt(fd, SOL_IP, MCAST_JOIN_SOURCE_GROUP, &req, sizeof(req)) < 0)
+ SENF_THROW_SYSTEM_EXCEPTION("::setsockopt()");
+ }
+}
+
+prefix_ void senf::INet4MulticastSocketProtocol::mcJoinSSMSource(INet4Address const & group,
+ INet4Address const & source,
+ std::string const & iface)
+ const
+{
+ mc4SSMSourceRequest(MCAST_JOIN_SOURCE_GROUP, fd(), group, source, iface);
+}
+
+prefix_ void senf::INet4MulticastSocketProtocol::mcLeaveSSMSource(INet4Address const & group,
+ INet4Address const & source,
+ std::string const & iface)
+ const
+{
+ mc4SSMSourceRequest(MCAST_LEAVE_SOURCE_GROUP, fd(), group, source, iface);
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::INet6MulticastSocketProtocol
}
}
+namespace {
+ void mc6SSMSourceRequest(int operation, int fd, senf::INet6Address const & group,
+ senf::INet6Address const & source, std::string const & iface)
+ {
+ struct group_source_req req;
+ ::memset(&req, 0, sizeof(req));
+ req.gsr_interface = if_nametoindex(iface.c_str());
+ if (req.gsr_interface == 0)
+ throw senf::SystemException("::if_nametoindex()", ENOENT SENF_EXC_DEBUGINFO);
+ req.gsr_group.ss_family = AF_INET6;
+ std::copy(group.begin(), group.end(),
+ reinterpret_cast<struct sockaddr_in6&>(req.gsr_group).sin6_addr.s6_addr);
+ req.gsr_source.ss_family = AF_INET6;
+ std::copy(source.begin(), source.end(),
+ reinterpret_cast<struct sockaddr_in6&>(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()");
+ }
+}
+
+prefix_ void senf::INet6MulticastSocketProtocol::mcJoinSSMSource(INet6Address const & group,
+ INet6Address const & source,
+ std::string const & iface)
+ const
+{
+ mc6SSMSourceRequest(MCAST_JOIN_SOURCE_GROUP, fd(), group, source, iface);
+}
+
+prefix_ void senf::INet6MulticastSocketProtocol::mcLeaveSSMSource(INet6Address const & group,
+ INet6Address const & source,
+ std::string const & iface)
+ const
+{
+ mc6SSMSourceRequest(MCAST_LEAVE_SOURCE_GROUP, fd(), group, source, iface);
+}
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "MulticastSocketProtocol.mpp"
///\{
/** \brief Generic addressing type independent multicast protocol facet
+
+ \todo implement complete new multicast API from RFC3678 (as far as supported by linux)
+ \bug mcLeaveSSMSource fails with EADDRNOTAVAIL
*/
class MulticastSocketProtocol
: public virtual SocketProtocol
interface with the given local address.
\param[in] mcAddr address of group to leave
\param[in] iface interface name */
+
+ void mcJoinSSMSource(INet4Address const & group, INet4Address const & source,
+ std::string const & iface) 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
+ group on
+ \param[in] iface interface to join the group on */
+ void mcLeaveSSMSource(INet4Address const & group, INet4Address const & source,
+ std::string const & iface) const;
+ ///< leave SSM multicast group
+ /**< This call will leave the multicast group \a group for
+ traffic from \a source.
+ \param[in] group multicast group to leave
+ \param[in] source SSM multicast source to leave the
+ group from
+ \param[in] iface interface to leave the group on */
};
/** \brief Multicast protocol facet for INet6 addressable multicast enabled sockets
multicast groups received. The group is left from the
default interface.
\param[in] mcAddr address of group to leave */
- void mcDropMembership(INet6Address const & mcAddr, std::string const & iface)
- const;
+ void mcDropMembership(INet6Address const & mcAddr, std::string const & iface) const;
///< leave multicast group on a specific interface
/**< This member will remove \a mcAddr from the list of
multicast groups received. The group is left from the
interface with the given local address.
\param[in] mcAddr address of group to leave
\param[in] iface interface name */
+
+ void mcJoinSSMSource(INet6Address const & group, INet6Address const & source,
+ std::string const & iface) 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
+ group on
+ \param[in] iface interface to join the group on */
+ void mcLeaveSSMSource(INet6Address const & group, INet6Address const & source,
+ std::string const & iface) const;
+ ///< leave SSM multicast group
+ /**< This call will leave the multicast group \a group for
+ traffic from \a source.
+ \param[in] group multicast group to leave
+ \param[in] source SSM multicast source to leave the
+ group from
+ \param[in] iface interface to leave the group on */
};
///\}
BOOST_CHECK( ! sock.protocol().mcLoop() );
sock.protocol().mcLoop(true);
BOOST_CHECK( sock.protocol().mcLoop() );
-
+
sock.protocol().mcIface("lo");
+
+ SENF_CHECK_NO_THROW( sock.protocol().mcJoinSSMSource(
+ senf::INet4Address(0xE0000001u),
+ senf::INet4Address(0x7F000001u),
+ "lo") );
+ // This fails with EADDRNOTAVAIL .. no idea why. I tried with 'eth' interface
+ // and a real address (not loopback) to no avail.
+// SENF_CHECK_NO_THROW( sock.protocol().mcLeaveSSMSource(
+// senf::INet4Address(0xE0000001u),
+// senf::INet4Address(0x7F000001u),
+// "lo") );
+
+ senf::UDPv6ClientSocketHandle sock6;
+
+ SENF_CHECK_NO_THROW( sock6.protocol().mcJoinSSMSource(
+ senf::INet6Address(0xFF00u, 0, 0, 0, 0, 0, 0, 1),
+ senf::INet6Address::Loopback,
+ "lo") );
+ // This fails with EADDRNOTAVAIL .. no idea why. I tried with 'eth' interface
+ // and a real address (not loopback) to no avail.
+// SENF_CHECK_NO_THROW( sock6.protocol().mcLeaveSSMSource(
+// senf::INet6Address(0xFF00u, 0, 0, 0, 0, 0, 0, 1),
+// senf::INet6Address::Loopback,
+// "lo") );
}
///////////////////////////////cc.e////////////////////////////////////////
# define SENF_EXC_DEBUGINFO
# endif
-# define SENF_THROW_SYSTEM_EXCEPTION(desc) throw SystemException(desc SENF_EXC_DEBUGINFO)
+# define SENF_THROW_SYSTEM_EXCEPTION(desc) throw senf::SystemException(desc SENF_EXC_DEBUGINFO)
}