Commit 9b63a81e authored by Pekka Pessi's avatar Pekka Pessi

tport_type_udp.c: when binding to multicast address, join to the group, too.

Use "canonic" IP address (from host-part of the SIP URI) to specify
interface.

darcs-hash:20080103170839-65a35-febd17b39ae4db5d5d4ab707780c33d3a69fa4e8.gz
parent 8bbd4ee7
......@@ -35,6 +35,7 @@
#include "config.h"
#include "tport_internal.h"
#include "sofia-sip/hostdomain.h"
#if HAVE_IP_RECVERR || HAVE_IPV6_RECVERR
#include <linux/types.h>
......@@ -113,6 +114,8 @@ int tport_udp_init_primary(tport_primary_t *pri,
unsigned rmem = 0, wmem = 0;
int events = SU_WAIT_IN;
int s;
su_sockaddr_t *su = (su_sockaddr_t *)ai->ai_addr;
int const one = 1; (void)one;
s = su_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (s == INVALID_SOCKET)
......@@ -125,19 +128,50 @@ int tport_udp_init_primary(tport_primary_t *pri,
tport_set_tos(s, ai, pri->pri_params->tpp_tos);
#if HAVE_IP_ADD_MEMBERSHIP
if (ai->ai_family == AF_INET &&
IN_MULTICAST(ntohl(su->su_sin.sin_addr.s_addr))) {
/* Try to join to the multicast group */
/* Bind to the SIP address like
<sip:88.77.66.55:5060;maddr=224.0.1.75;transport=udp> */
struct ip_mreqn imr[1];
struct in_addr address;
memset(imr, 0, sizeof imr);
imr->imr_multiaddr = su->su_sin.sin_addr;
if (host_is_ip4_address(tpn->tpn_canon) &&
inet_pton(AF_INET, tpn->tpn_canon, &address) > 0) {
imr->imr_address = address;
}
if (setsockopt(s, SOL_IP, IP_ADD_MEMBERSHIP, imr, (sizeof imr)) < 0) {
SU_DEBUG_3(("setsockopt(%s): %s\n",
"IP_ADD_MEMBERSHIP", su_strerror(su_errno())));
}
#if HAVE_IP_MULTICAST_LOOP
else
if (setsockopt(s, SOL_IP, IP_MULTICAST_LOOP, &one, sizeof one) < 0) {
SU_DEBUG_3(("setsockopt(%s): %s\n",
"IP_MULTICAST_LOOP", su_strerror(su_errno())));
}
#endif
}
#endif
#if HAVE_IP_RECVERR
if (ai->ai_family == AF_INET || ai->ai_family == AF_INET6) {
int const one = 1;
if (setsockopt(s, SOL_IP, IP_RECVERR, &one, sizeof(one)) < 0) {
if (ai->ai_family == AF_INET)
SU_DEBUG_3(("setsockopt(IPVRECVERR): %s\n", su_strerror(su_errno())));
SU_DEBUG_3(("setsockopt(%s): %s\n",
"IPVRECVERR", su_strerror(su_errno())));
}
events |= SU_WAIT_ERR;
}
#endif
#if HAVE_IPV6_RECVERR
if (ai->ai_family == AF_INET6) {
int const one = 1;
if (setsockopt(s, SOL_IPV6, IPV6_RECVERR, &one, sizeof(one)) < 0)
SU_DEBUG_3(("setsockopt(IPV6_RECVERR): %s\n", su_strerror(su_errno())));
events |= SU_WAIT_ERR;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment