283 |
283 |
static void
|
284 |
284 |
iptv_transport_stop(th_transport_t *t)
|
285 |
285 |
{
|
|
286 |
struct ip_mreqn m;
|
|
287 |
struct ifreq ifr;
|
|
288 |
|
286 |
289 |
pthread_mutex_lock(&iptv_recvmutex);
|
287 |
290 |
LIST_REMOVE(t, tht_active_link);
|
288 |
291 |
pthread_mutex_unlock(&iptv_recvmutex);
|
289 |
292 |
assert(t->tht_iptv_fd >= 0);
|
|
293 |
/* First, resolve interface name */
|
|
294 |
memset(&ifr, 0, sizeof(ifr));
|
|
295 |
av_strlcpy(ifr.ifr_name, t->tht_iptv_iface, IFNAMSIZ);
|
|
296 |
ifr.ifr_name[IFNAMSIZ - 1] = 0;
|
|
297 |
if(ioctl(t->tht_iptv_fd, SIOCGIFINDEX, &ifr)) {
|
|
298 |
tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot find interface %s",
|
|
299 |
t->tht_identifier, t->tht_iptv_iface);
|
|
300 |
}
|
|
301 |
|
|
302 |
/* Leave multicast group */
|
|
303 |
memset(&m, 0, sizeof(m));
|
|
304 |
m.imr_multiaddr.s_addr = t->tht_iptv_group.s_addr;
|
|
305 |
m.imr_address.s_addr = 0;
|
|
306 |
m.imr_ifindex = ifr.ifr_ifindex;
|
|
307 |
|
|
308 |
if(setsockopt(t->tht_iptv_fd, SOL_IP, IP_DROP_MEMBERSHIP, &m,
|
|
309 |
sizeof(struct ip_mreqn)) == -1) {
|
|
310 |
tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot leave %s -- %s",
|
|
311 |
t->tht_identifier, inet_ntoa(m.imr_multiaddr), strerror(errno));
|
|
312 |
}
|
|
313 |
|
290 |
314 |
close(t->tht_iptv_fd); // Automatically removes fd from epoll set
|
291 |
315 |
t->tht_iptv_fd = -1;
|