added Socket::joinMulticastGroup() and Socket::leaveMulticastGroup()
This commit is contained in:
parent
72345c7280
commit
05c2905a0a
@ -95,6 +95,8 @@ public:
|
||||
qse_ssize_t receive (void* buf, qse_size_t len, SocketAddress& srcaddr) QSE_CPP_NOEXCEPT;
|
||||
|
||||
/* TODO: sendmsg, recvmsg */
|
||||
int joinMulticastGroup (const SocketAddress& mcaddr, const SocketAddress& ifaddr);
|
||||
int leaveMulticastGroup (const SocketAddress& mcaddr, const SocketAddress& ifaddr);
|
||||
|
||||
// utility functions to retrieve network configuration information.
|
||||
int getIfceIndex (const qse_mchar_t* name);
|
||||
|
@ -67,10 +67,13 @@ public:
|
||||
void setIpaddr (const qse_ip4ad_t* ipaddr) QSE_CPP_NOEXCEPT;
|
||||
void setIpaddr (const qse_ip6ad_t* ipaddr) QSE_CPP_NOEXCEPT;
|
||||
|
||||
const qse_ip4ad_t* getIp4addr () const QSE_CPP_NOEXCEPT;
|
||||
const qse_ip6ad_t* getIp6addr () const QSE_CPP_NOEXCEPT;
|
||||
|
||||
qse_uint16_t getPort() const QSE_CPP_NOEXCEPT; // in network-byte order
|
||||
void setPort (qse_uint16_t port) QSE_CPP_NOEXCEPT; // in network-byte order
|
||||
|
||||
qse_uint32_t getScopeId () QSE_CPP_NOEXCEPT; // in network-byte order
|
||||
qse_uint32_t getScopeId () const QSE_CPP_NOEXCEPT; // in network-byte order
|
||||
void setScopeId (qse_uint32_t scope_id) QSE_CPP_NOEXCEPT; // in network-byte order
|
||||
|
||||
int set (const qse_skad_t* skad) QSE_CPP_NOEXCEPT;
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#if defined(HAVE_NET_IF_H)
|
||||
# include <net/if.h>
|
||||
@ -590,6 +591,88 @@ qse_ssize_t Socket::receive (void* buf, qse_size_t len, SocketAddress& srcaddr)
|
||||
return n;
|
||||
}
|
||||
|
||||
int Socket::joinMulticastGroup (const SocketAddress& mcaddr, const SocketAddress& ifaddr)
|
||||
{
|
||||
int family = mcaddr.getFamily(); // ((struct sockaddr*)mcaddr.getAddrPtr())->sa_family
|
||||
|
||||
if (family != ifaddr.getFamily())
|
||||
{
|
||||
this->setErrorCode (E_EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (family)
|
||||
{
|
||||
#if defined(AF_INET)
|
||||
case AF_INET:
|
||||
{
|
||||
|
||||
struct ip_mreq mreq;
|
||||
QSE_MEMSET (&mreq, 0, QSE_SIZEOF(mreq));
|
||||
|
||||
mreq.imr_multiaddr = *(struct in_addr*)mcaddr.getIp4addr();
|
||||
mreq.imr_interface = *(struct in_addr*)ifaddr.getIp4addr();
|
||||
return ::setsockopt(this->handle, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, QSE_SIZEOF(mreq));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(AF_INET6)
|
||||
case AF_INET6:
|
||||
{
|
||||
struct ipv6_mreq mreq;
|
||||
QSE_MEMSET (&mreq, 0, QSE_SIZEOF(mreq));
|
||||
|
||||
mreq.ipv6mr_multiaddr = *(struct in6_addr*)mcaddr.getIp6addr();
|
||||
mreq.ipv6mr_interface = ifaddr.getScopeId();
|
||||
return ::setsockopt(this->handle, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, QSE_SIZEOF(mreq));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
this->setErrorCode (E_ENOIMPL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Socket::leaveMulticastGroup (const SocketAddress& mcaddr, const SocketAddress& ifaddr)
|
||||
{
|
||||
int family = mcaddr.getFamily(); // ((struct sockaddr*)mcaddr.getAddrPtr())->sa_family
|
||||
|
||||
if (family != ifaddr.getFamily())
|
||||
{
|
||||
this->setErrorCode (E_EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (family)
|
||||
{
|
||||
#if defined(AF_INET)
|
||||
case AF_INET:
|
||||
{
|
||||
struct ip_mreq mreq;
|
||||
QSE_MEMSET (&mreq, 0, QSE_SIZEOF(mreq));
|
||||
|
||||
mreq.imr_multiaddr = *(struct in_addr*)mcaddr.getIp4addr();
|
||||
mreq.imr_interface = *(struct in_addr*)ifaddr.getIp4addr();
|
||||
return ::setsockopt(this->handle, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, QSE_SIZEOF(mreq));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(AF_INET6)
|
||||
case AF_INET6:
|
||||
{
|
||||
struct ipv6_mreq mreq;
|
||||
QSE_MEMSET (&mreq, 0, QSE_SIZEOF(mreq));
|
||||
|
||||
mreq.ipv6mr_multiaddr = *(struct in6_addr*)mcaddr.getIp6addr();
|
||||
mreq.ipv6mr_interface = ifaddr.getScopeId();
|
||||
return ::setsockopt(this->handle, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &mreq, QSE_SIZEOF(mreq));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
this->setErrorCode (E_ENOIMPL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Socket::getIfceIndex (const qse_mchar_t* name)
|
||||
{
|
||||
@ -674,7 +757,7 @@ int Socket::getIfceAddress (const qse_wchar_t* name, SocketAddress* addr)
|
||||
|
||||
int Socket::getIfceNetmask(const qse_mchar_t* name, SocketAddress* addr)
|
||||
{
|
||||
#if defined(SIOCGIFADDR)
|
||||
#if defined(SIOCGIFNETMASK)
|
||||
return this->get_ifce_address(SIOCGIFNETMASK, name, false, addr);
|
||||
#else
|
||||
this->setErrorCode (E_ENOIMPL);
|
||||
@ -684,7 +767,7 @@ int Socket::getIfceNetmask(const qse_mchar_t* name, SocketAddress* addr)
|
||||
|
||||
int Socket::getIfceNetmask (const qse_wchar_t* name, SocketAddress* addr)
|
||||
{
|
||||
#if defined(SIOCGIFADDR)
|
||||
#if defined(SIOCGIFNETMASK)
|
||||
return this->get_ifce_address(SIOCGIFNETMASK, name, true, addr);
|
||||
#else
|
||||
this->setErrorCode (E_ENOIMPL);
|
||||
@ -694,7 +777,7 @@ int Socket::getIfceNetmask (const qse_wchar_t* name, SocketAddress* addr)
|
||||
|
||||
int Socket::getIfceBroadcast(const qse_mchar_t* name, SocketAddress* addr)
|
||||
{
|
||||
#if defined(SIOCGIFADDR)
|
||||
#if defined(SIOCGIFBRDADDR)
|
||||
return this->get_ifce_address(SIOCGIFBRDADDR, name, false, addr);
|
||||
#else
|
||||
this->setErrorCode (E_ENOIMPL);
|
||||
@ -704,7 +787,7 @@ int Socket::getIfceBroadcast(const qse_mchar_t* name, SocketAddress* addr)
|
||||
|
||||
int Socket::getIfceBroadcast (const qse_wchar_t* name, SocketAddress* addr)
|
||||
{
|
||||
#if defined(SIOCGIFADDR)
|
||||
#if defined(SIOCGIFBRDADDR)
|
||||
return this->get_ifce_address(SIOCGIFBRDADDR, name, true, addr);
|
||||
#else
|
||||
this->setErrorCode (E_ENOIMPL);
|
||||
|
@ -139,6 +139,30 @@ void SocketAddress::setIpaddr (const qse_ip6ad_t* ipaddr) QSE_CPP_NOEXCEPT
|
||||
#endif
|
||||
}
|
||||
|
||||
const qse_ip4ad_t* SocketAddress::getIp4addr () const QSE_CPP_NOEXCEPT
|
||||
{
|
||||
#if defined(AF_INET)
|
||||
if (FAMILY(&this->skad) == AF_INET)
|
||||
{
|
||||
struct sockaddr_in* v4 = (struct sockaddr_in*)&this->skad;
|
||||
return (const qse_ip4ad_t*)&v4->sin_addr;
|
||||
}
|
||||
#endif
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
const qse_ip6ad_t* SocketAddress::getIp6addr () const QSE_CPP_NOEXCEPT
|
||||
{
|
||||
#if defined(AF_INET6)
|
||||
if (FAMILY(&this->skad) == AF_INET6)
|
||||
{
|
||||
struct sockaddr_in6* v6 = (struct sockaddr_in6*)&this->skad;
|
||||
return (const qse_ip6ad_t*)&v6->sin6_addr;
|
||||
}
|
||||
#endif
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
qse_uint16_t SocketAddress::getPort () const QSE_CPP_NOEXCEPT
|
||||
{
|
||||
switch (FAMILY(&this->skad))
|
||||
@ -187,7 +211,7 @@ void SocketAddress::setPort (qse_uint16_t port) QSE_CPP_NOEXCEPT
|
||||
}
|
||||
}
|
||||
|
||||
qse_uint32_t SocketAddress::getScopeId () QSE_CPP_NOEXCEPT
|
||||
qse_uint32_t SocketAddress::getScopeId () const QSE_CPP_NOEXCEPT
|
||||
{
|
||||
switch (FAMILY(&this->skad))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user