X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Socket%2FProtocols%2FINet%2FMulticastSocketProtocol.cc;h=42f2126b8a51d37190cc108e48c77580b14c43eb;hb=9ded1690d676ba7c7054a7a272debf99102f94c0;hp=ba30fcee99806861e57db68d8efe4a44e7f66c04;hpb=6ba573a99f93543ee32292f79865751b3e9b89a4;p=senf.git diff --git a/Socket/Protocols/INet/MulticastSocketProtocol.cc b/Socket/Protocols/INet/MulticastSocketProtocol.cc index ba30fce..42f2126 100644 --- a/Socket/Protocols/INet/MulticastSocketProtocol.cc +++ b/Socket/Protocols/INet/MulticastSocketProtocol.cc @@ -30,6 +30,7 @@ #include #include #include // for if_nametoindex +#include "../../../Utils/Exception.hh" //#include "MulticastSocketProtocol.mpp" #define prefix_ @@ -43,7 +44,7 @@ prefix_ void senf::MulticastSocketProtocol::broadcastEnabled(bool v) { int ivalue (v); if (::setsockopt(fd(), SOL_SOCKET, SO_BROADCAST, &ivalue, sizeof(ivalue)) < 0) - throw SystemException("::setsockopt(SO_BROADCAST)"); + SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(SO_BROADCAST)"); } prefix_ bool senf::MulticastSocketProtocol::broadcastEnabled() @@ -52,7 +53,7 @@ prefix_ bool senf::MulticastSocketProtocol::broadcastEnabled() int value (0); ::socklen_t len (sizeof(value)); if (::getsockopt(fd(), SOL_SOCKET, SO_BROADCAST, &value, &len) < 0) - throw SystemException("::getsockopt(SO_BROADCAST)"); + SENF_THROW_SYSTEM_EXCEPTION("::getsockopt(SO_BROADCAST)"); return value; } @@ -62,7 +63,7 @@ prefix_ bool senf::MulticastSocketProtocol::mcLoop() int value (0); socklen_t len (sizeof(value)); if (::getsockopt(fd(),SOL_IP,IP_MULTICAST_LOOP,&value,&len) < 0) - throw SystemException(); + SENF_THROW_SYSTEM_EXCEPTION(""); return value; } @@ -71,7 +72,7 @@ prefix_ void senf::MulticastSocketProtocol::mcLoop(bool value) { int ivalue (value); if (::setsockopt(fd(),SOL_IP,IP_MULTICAST_LOOP,&ivalue,sizeof(ivalue)) < 0) - throw SystemException(); + SENF_THROW_SYSTEM_EXCEPTION(""); } prefix_ void senf::MulticastSocketProtocol::mcIface(std::string const & iface) @@ -82,10 +83,10 @@ prefix_ void senf::MulticastSocketProtocol::mcIface(std::string const & iface) if (!iface.empty()) { mreqn.imr_ifindex = if_nametoindex(iface.c_str()); if (mreqn.imr_ifindex == 0) - throw SystemException(EINVAL); + throw SystemException(EINVAL SENF_EXC_DEBUGINFO); } if (::setsockopt(fd(),SOL_IP,IP_MULTICAST_IF,&mreqn,sizeof(mreqn)) < 0) - throw SystemException(); + SENF_THROW_SYSTEM_EXCEPTION(""); } prefix_ unsigned senf::MulticastSocketProtocol::mcTTL() @@ -94,7 +95,7 @@ prefix_ unsigned senf::MulticastSocketProtocol::mcTTL() int value (0); socklen_t len (sizeof(value)); if (::getsockopt(fd(),SOL_IP,IP_MULTICAST_TTL,&value,&len) < 0) - throw SystemException(); + SENF_THROW_SYSTEM_EXCEPTION(""); return value; } @@ -102,7 +103,7 @@ prefix_ void senf::MulticastSocketProtocol::mcTTL(unsigned value) const { if (::setsockopt(fd(),SOL_IP,IP_MULTICAST_TTL,&value,sizeof(value)) < 0) - throw SystemException(); + SENF_THROW_SYSTEM_EXCEPTION(""); } /////////////////////////////////////////////////////////////////////////// @@ -116,11 +117,11 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address co mreqn.imr_address.s_addr = htons(INADDR_ANY); mreqn.imr_ifindex = 0; if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) - throw SystemException("::setsockopt(IP_ADD_MEMBERSHIP"); + SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP)"); } prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr, - INet4Address const & localAddr) + INet4Address const & localAddr) const { struct ip_mreqn mreqn; @@ -128,11 +129,11 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address co mreqn.imr_address.s_addr = localAddr.inaddr(); mreqn.imr_ifindex = 0; if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) - throw SystemException("::setsockopt(IP_ADD_MEMBERSHIP"); + SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP"); } prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr, - std::string const & iface) + std::string const & iface) const { struct ip_mreqn mreqn; @@ -140,9 +141,9 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address co mreqn.imr_address.s_addr = htons(INADDR_ANY); mreqn.imr_ifindex = if_nametoindex(iface.c_str()); if (mreqn.imr_ifindex == 0) - throw SystemException("::if_nametoindex()",ENOENT); + throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO); if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) - throw SystemException("::setsockopt(IP_ADD_MEMBERSHIP"); + SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP"); } prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr) @@ -153,11 +154,11 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address c mreqn.imr_address.s_addr = htons(INADDR_ANY); mreqn.imr_ifindex = 0; if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) - throw SystemException(); + SENF_THROW_SYSTEM_EXCEPTION(""); } prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr, - INet4Address const & localAddr) + INet4Address const & localAddr) const { struct ip_mreqn mreqn; @@ -165,11 +166,11 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address c mreqn.imr_address.s_addr = localAddr.inaddr(); mreqn.imr_ifindex = 0; if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) - throw SystemException(); + SENF_THROW_SYSTEM_EXCEPTION(""); } prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr, - std::string const & iface) + std::string const & iface) const { struct ip_mreqn mreqn; @@ -177,9 +178,43 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address c mreqn.imr_address.s_addr = htons(INADDR_ANY); mreqn.imr_ifindex = if_nametoindex(iface.c_str()); if (mreqn.imr_ifindex == 0) - throw SystemException("::if_nametoindex()",ENOENT); + throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO); if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) - throw SystemException(); + 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(req.gsr_group).sin_addr.s_addr = group.inaddr(); + req.gsr_source.ss_family = AF_INET; + reinterpret_cast(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); } /////////////////////////////////////////////////////////////////////////// @@ -188,47 +223,127 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address c prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address const & mcAddr) const { - struct ipv6_mreq mreqn; - std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr); - mreqn.ipv6mr_interface = 0; - if (::setsockopt(fd(),SOL_IP,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) - throw SystemException("::setsockopt(IPV6_ADD_MEMBERSHIP"); + if (mcAddr.inet4Mapped()) { + struct ip_mreqn mreqn; + mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr(); + mreqn.imr_address.s_addr = htons(INADDR_ANY); + mreqn.imr_ifindex = 0; + if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) + SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP)"); + } + else { + struct ipv6_mreq mreqn; + std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr); + mreqn.ipv6mr_interface = 0; + if (::setsockopt(fd(),SOL_IPV6,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) + SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IPV6_ADD_MEMBERSHIP"); + } } prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address const & mcAddr, - std::string const & iface) + std::string const & iface) { - struct ipv6_mreq mreqn; - std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr); - mreqn.ipv6mr_interface = if_nametoindex(iface.c_str()); - if (mreqn.ipv6mr_interface == 0) - throw SystemException("::if_nametoindex()",ENOENT); - if (::setsockopt(fd(),SOL_IP,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) - throw SystemException("::setsockopt(IPV6_ADD_MEMBERSHIP"); + if (mcAddr.inet4Mapped()) { + struct ip_mreqn mreqn; + mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr(); + mreqn.imr_address.s_addr = htons(INADDR_ANY); + mreqn.imr_ifindex = if_nametoindex(iface.c_str()); + if (mreqn.imr_ifindex == 0) + throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO); + if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) + SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP"); + } + else { + struct ipv6_mreq mreqn; + std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr); + mreqn.ipv6mr_interface = if_nametoindex(iface.c_str()); + if (mreqn.ipv6mr_interface == 0) + throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO); + if (::setsockopt(fd(),SOL_IPV6,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) + SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IPV6_ADD_MEMBERSHIP"); + } } prefix_ void senf::INet6MulticastSocketProtocol::mcDropMembership(INet6Address const & mcAddr) const { - struct ipv6_mreq mreqn; - std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr); - mreqn.ipv6mr_interface = 0; - if (::setsockopt(fd(),SOL_IP,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) - throw SystemException(); + if (mcAddr.inet4Mapped()) { + struct ip_mreqn mreqn; + mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr(); + mreqn.imr_address.s_addr = htons(INADDR_ANY); + mreqn.imr_ifindex = 0; + if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) + SENF_THROW_SYSTEM_EXCEPTION(""); + } + else { + struct ipv6_mreq mreqn; + std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr); + mreqn.ipv6mr_interface = 0; + if (::setsockopt(fd(),SOL_IPV6,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) + SENF_THROW_SYSTEM_EXCEPTION(""); + } } prefix_ void senf::INet6MulticastSocketProtocol::mcDropMembership(INet6Address const & mcAddr, - std::string const & iface) + std::string const & iface) + const +{ + if (mcAddr.inet4Mapped()) { + struct ip_mreqn mreqn; + mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr(); + mreqn.imr_address.s_addr = htons(INADDR_ANY); + mreqn.imr_ifindex = if_nametoindex(iface.c_str()); + if (mreqn.imr_ifindex == 0) + throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO); + if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) + SENF_THROW_SYSTEM_EXCEPTION(""); + } + else { + struct ipv6_mreq mreqn; + std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr); + mreqn.ipv6mr_interface = if_nametoindex(iface.c_str()); + if (mreqn.ipv6mr_interface == 0) + throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO); + if (::setsockopt(fd(),SOL_IPV6,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) + SENF_THROW_SYSTEM_EXCEPTION(""); + } +} + +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(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()"); + } +} + +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 { - struct ipv6_mreq mreqn; - std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr); - mreqn.ipv6mr_interface = if_nametoindex(iface.c_str()); - if (mreqn.ipv6mr_interface == 0) - throw SystemException("::if_nametoindex()",ENOENT); - if (::setsockopt(fd(),SOL_IP,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) - throw SystemException(); + mc6SSMSourceRequest(MCAST_LEAVE_SOURCE_GROUP, fd(), group, source, iface); } ///////////////////////////////cc.e////////////////////////////////////////