diff -durN hts-tvheadend-2.11.old//src/iptv_input.c hts-tvheadend-2.11//src/iptv_input.c --- hts-tvheadend-2.11.old//src/iptv_input.c 2010-01-17 07:51:43.000000000 +1000 +++ hts-tvheadend-2.11//src/iptv_input.c 2010-10-18 16:15:43.000000000 +1100 @@ -283,12 +283,36 @@ static void iptv_transport_stop(th_transport_t *t) { + struct ip_mreqn m; + struct ifreq ifr; + pthread_mutex_lock(&iptv_recvmutex); LIST_REMOVE(t, tht_active_link); pthread_mutex_unlock(&iptv_recvmutex); assert(t->tht_iptv_fd >= 0); + /* First, resolve interface name */ + memset(&ifr, 0, sizeof(ifr)); + av_strlcpy(ifr.ifr_name, t->tht_iptv_iface, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ - 1] = 0; + if(ioctl(t->tht_iptv_fd, SIOCGIFINDEX, &ifr)) { + tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot find interface %s", + t->tht_identifier, t->tht_iptv_iface); + } + + /* Leave multicast group */ + memset(&m, 0, sizeof(m)); + m.imr_multiaddr.s_addr = t->tht_iptv_group.s_addr; + m.imr_address.s_addr = 0; + m.imr_ifindex = ifr.ifr_ifindex; + + if(setsockopt(t->tht_iptv_fd, SOL_IP, IP_DROP_MEMBERSHIP, &m, + sizeof(struct ip_mreqn)) == -1) { + tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot leave %s -- %s", + t->tht_identifier, inet_ntoa(m.imr_multiaddr), strerror(errno)); + } + close(t->tht_iptv_fd); // Automatically removes fd from epoll set t->tht_iptv_fd = -1;