Skip to content
Snippets Groups Projects
Commit 310f0375 authored by g0dil's avatar g0dil
Browse files

Socket/Protocols/INet: Extend INet6SocketAddress syntax to support more...

Socket/Protocols/INet: Extend INet6SocketAddress syntax to support more flexible syntax variantes (embedded v4 address, hostname + zoneid ...)
Socket/Protocols/INet: Add (linux specific) support for v6 mapped v4 multicast addresses
parent d5eb54d5
No related branches found
No related tags found
No related merge requests found
...@@ -127,7 +127,7 @@ prefix_ bool senf::INet6Address::unicast() ...@@ -127,7 +127,7 @@ prefix_ bool senf::INet6Address::unicast()
prefix_ bool senf::INet6Address::multicast() prefix_ bool senf::INet6Address::multicast()
const const
{ {
return (*this)[0] == 0xFFu; return (*this)[0] == 0xFFu || inet4Mapped() && inet4address().multicast();
} }
prefix_ senf::INet6Address::ScopeId senf::INet6Address::scope() prefix_ senf::INet6Address::ScopeId senf::INet6Address::scope()
......
...@@ -216,6 +216,12 @@ namespace senf { ...@@ -216,6 +216,12 @@ namespace senf {
bool unicast() const; ///< \c true, if address is unicast bool unicast() const; ///< \c true, if address is unicast
bool multicast() const; ///< \c true, if address is multicast bool multicast() const; ///< \c true, if address is multicast
/**< To support a linux specific extension, INet4 multicast
addressed mapped to INet6 are also interpreted as
multicast addresses. This is NOT part of the standard,
however the standard officially only allows unicast v4
addresses to be mapped to v6 so this does not collide
with any standard conforming use. */
ScopeId scope() const; ///< Get address's scope ScopeId scope() const; ///< Get address's scope
/**< The scope of an address is one of the \ref ScopeId /**< The scope of an address is one of the \ref ScopeId
......
...@@ -89,12 +89,12 @@ prefix_ senf::INet6SocketAddress::INet6SocketAddress(std::string const & addr, ...@@ -89,12 +89,12 @@ prefix_ senf::INet6SocketAddress::INet6SocketAddress(std::string const & addr,
// or: host ":" port // or: host ":" port
// or: port // or: port
static boost::regex const addressRx ("(?:(?:\\[([a-f0-9A-F:]+)(?:%(.+))?\\]|(.+)):)?([0-9]+)"); static boost::regex const addressRx ("(?:(?:\\[([^%]+)(?:%(.+))?\\]|(.+)):)?([0-9]+)");
// Subexpression numbers: // Subexpression numbers:
enum { NumericAddr = 1, enum { Address = 1,
ZoneId = 2, ZoneId = 2,
Hostname = 3, Hostname = 3,
Port = 4 }; Port = 4 };
boost::smatch match; boost::smatch match;
if (! regex_match(addr, match, addressRx)) if (! regex_match(addr, match, addressRx))
...@@ -105,9 +105,9 @@ prefix_ senf::INet6SocketAddress::INet6SocketAddress(std::string const & addr, ...@@ -105,9 +105,9 @@ prefix_ senf::INet6SocketAddress::INet6SocketAddress(std::string const & addr,
sockaddr_.sin6_port = htons(boost::lexical_cast<boost::uint16_t>(match[Port])); sockaddr_.sin6_port = htons(boost::lexical_cast<boost::uint16_t>(match[Port]));
if (match[NumericAddr].matched || match[Hostname].matched) { if (match[Address].matched || match[Hostname].matched) {
INet6Address a (INet6Address::from_string( INet6Address a (INet6Address::from_string(
match[NumericAddr].matched ? match[NumericAddr] : match[Hostname], match[Address].matched ? match[Address] : match[Hostname],
resolve)); resolve));
std::copy(a.begin(), a.end(), &sockaddr_.sin6_addr.s6_addr[0]); std::copy(a.begin(), a.end(), &sockaddr_.sin6_addr.s6_addr[0]);
} }
......
...@@ -121,7 +121,7 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address co ...@@ -121,7 +121,7 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address co
} }
prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr, prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr,
INet4Address const & localAddr) INet4Address const & localAddr)
const const
{ {
struct ip_mreqn mreqn; struct ip_mreqn mreqn;
...@@ -133,7 +133,7 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address co ...@@ -133,7 +133,7 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address co
} }
prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr, prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr,
std::string const & iface) std::string const & iface)
const const
{ {
struct ip_mreqn mreqn; struct ip_mreqn mreqn;
...@@ -158,7 +158,7 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address c ...@@ -158,7 +158,7 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address c
} }
prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr, prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr,
INet4Address const & localAddr) INet4Address const & localAddr)
const const
{ {
struct ip_mreqn mreqn; struct ip_mreqn mreqn;
...@@ -170,7 +170,7 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address c ...@@ -170,7 +170,7 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address c
} }
prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr, prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr,
std::string const & iface) std::string const & iface)
const const
{ {
struct ip_mreqn mreqn; struct ip_mreqn mreqn;
...@@ -189,47 +189,91 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address c ...@@ -189,47 +189,91 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address c
prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address const & mcAddr) prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address const & mcAddr)
const const
{ {
struct ipv6_mreq mreqn; if (mcAddr.inet4Mapped()) {
std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr); struct ip_mreqn mreqn;
mreqn.ipv6mr_interface = 0; mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
if (::setsockopt(fd(),SOL_IPV6,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) mreqn.imr_address.s_addr = htons(INADDR_ANY);
SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IPV6_ADD_MEMBERSHIP"); 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, prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address const & mcAddr,
std::string const & iface) std::string const & iface)
{ {
struct ipv6_mreq mreqn; if (mcAddr.inet4Mapped()) {
std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr); struct ip_mreqn mreqn;
mreqn.ipv6mr_interface = if_nametoindex(iface.c_str()); mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
if (mreqn.ipv6mr_interface == 0) mreqn.imr_address.s_addr = htons(INADDR_ANY);
throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO); mreqn.imr_ifindex = if_nametoindex(iface.c_str());
if (::setsockopt(fd(),SOL_IPV6,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) if (mreqn.imr_ifindex == 0)
SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IPV6_ADD_MEMBERSHIP"); 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) prefix_ void senf::INet6MulticastSocketProtocol::mcDropMembership(INet6Address const & mcAddr)
const const
{ {
struct ipv6_mreq mreqn; if (mcAddr.inet4Mapped()) {
std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr); struct ip_mreqn mreqn;
mreqn.ipv6mr_interface = 0; mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
if (::setsockopt(fd(),SOL_IPV6,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) mreqn.imr_address.s_addr = htons(INADDR_ANY);
SENF_THROW_SYSTEM_EXCEPTION(""); 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 prefix_ void
senf::INet6MulticastSocketProtocol::mcDropMembership(INet6Address const & mcAddr, senf::INet6MulticastSocketProtocol::mcDropMembership(INet6Address const & mcAddr,
std::string const & iface) std::string const & iface)
const const
{ {
struct ipv6_mreq mreqn; if (mcAddr.inet4Mapped()) {
std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr); struct ip_mreqn mreqn;
mreqn.ipv6mr_interface = if_nametoindex(iface.c_str()); mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
if (mreqn.ipv6mr_interface == 0) mreqn.imr_address.s_addr = htons(INADDR_ANY);
throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO); mreqn.imr_ifindex = if_nametoindex(iface.c_str());
if (::setsockopt(fd(),SOL_IPV6,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0) if (mreqn.imr_ifindex == 0)
SENF_THROW_SYSTEM_EXCEPTION(""); 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("");
}
} }
///////////////////////////////cc.e//////////////////////////////////////// ///////////////////////////////cc.e////////////////////////////////////////
......
...@@ -128,6 +128,9 @@ namespace senf { ...@@ -128,6 +128,9 @@ namespace senf {
}; };
/** \brief Multicast protocol facet for INet6 addressable multicast enabled sockets /** \brief Multicast protocol facet for INet6 addressable multicast enabled sockets
This implementation supports INet6 mapped INet4 multicast addresses. This is a linux
specific extension and NOT part of the relevant RFCs.
*/ */
class INet6MulticastSocketProtocol class INet6MulticastSocketProtocol
: public MulticastSocketProtocol : public MulticastSocketProtocol
...@@ -139,14 +142,6 @@ namespace senf { ...@@ -139,14 +142,6 @@ namespace senf {
groups received. The group is joined on the default groups received. The group is joined on the default
interface. interface.
\param[in] mcAddr address of group to join */ \param[in] mcAddr address of group to join */
void mcAddMembership(INet6Address const & mcAddr, INet6Address 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
with the given local address.
\param[in] mcAddr address of group to join
\param[in] localAddr address of interface to join on */
void mcAddMembership(INet6Address const & mcAddr, std::string const & iface); void mcAddMembership(INet6Address const & mcAddr, std::string const & iface);
///< join multicast group on a specific interface ///< join multicast group on a specific interface
/**< This member will add \a mcAddr to the list of multicast /**< This member will add \a mcAddr to the list of multicast
...@@ -161,15 +156,6 @@ namespace senf { ...@@ -161,15 +156,6 @@ namespace senf {
multicast groups received. The group is left from the multicast groups received. The group is left from the
default interface. default interface.
\param[in] mcAddr address of group to leave */ \param[in] mcAddr address of group to leave */
void mcDropMembership(INet6Address const & mcAddr, INet6Address const & localAddr)
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] localAddr address of interface to leave
from */
void mcDropMembership(INet6Address const & mcAddr, std::string const & iface) void mcDropMembership(INet6Address const & mcAddr, std::string const & iface)
const; const;
///< leave multicast group on a specific interface ///< leave multicast group on a specific interface
......
...@@ -41,6 +41,7 @@ BerliOS ...@@ -41,6 +41,7 @@ BerliOS
bitfield bitfield
bool bool
boostfn boostfn
broadcastEnabled
bund bund
calculateChecksum calculateChecksum
callables callables
...@@ -209,6 +210,7 @@ iberty ...@@ -209,6 +210,7 @@ iberty
IDE IDE
IdleEvent IdleEvent
ietf ietf
iface
ifndef ifndef
ih ih
impl impl
...@@ -262,9 +264,11 @@ libSocket ...@@ -262,9 +264,11 @@ libSocket
libUtils libUtils
LINKFLAGS LINKFLAGS
LinkScope LinkScope
linux
ListB ListB
ListN ListN
ListPolicy ListPolicy
localAddr
localhost localhost
loopback loopback
mac mac
...@@ -272,6 +276,10 @@ MACAddress ...@@ -272,6 +276,10 @@ MACAddress
MACAddressParser MACAddressParser
mainpage mainpage
manualparse manualparse
mcAddMembership
mcAddr
mcDropMembership
mcLoop
mem mem
memberfn memberfn
mixin mixin
...@@ -279,6 +287,7 @@ mkdir ...@@ -279,6 +287,7 @@ mkdir
MPEGDVBBundle MPEGDVBBundle
mpp mpp
multicast multicast
MulticastSocketProtocol
MyClass MyClass
mycommand mycommand
mydir mydir
...@@ -412,6 +421,7 @@ RegistrationProxy ...@@ -412,6 +421,7 @@ RegistrationProxy
repos repos
rerference rerference
rfc rfc
RFCs
RO RO
RP RP
SafePacketParser SafePacketParser
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment