Project

General

Profile

Bug #2138 » 0001-Hack-implement-iptv-udp-handler-stop-in-order-to-lea.patch

Nikolai L., 2014-06-16 12:41

View differences:

src/input/mpegts/iptv/iptv_udp.c
178 178
  return -1;
179 179
}
180 180

  
181
static void
182
iptv_udp_stop ( iptv_mux_t *im)
183
{
184
  int solip, ipv6 = 0;
185
  struct ifreq ifr;
186
  struct in_addr saddr;
187
  struct in6_addr s6addr;
188
  char name[256], buf[256];
189
  url_t url;
190

  
191
  im->mm_display_name((mpegts_mux_t*)im, name, sizeof(name));
192

  
193
 /* Parse URL */
194
  im->mm_display_name((mpegts_mux_t*)im, buf, sizeof(buf));
195
  if (urlparse(im->mm_iptv_url ?: "", &url)) {
196
    tvherror("iptv", "%s - invalid URL [%s]", buf, im->mm_iptv_url);
197
    return;
198
  }
199

  
200
  /* Determine if this is IPv6 */
201
  if (!inet_pton(AF_INET, url.host, &saddr)) {
202
    ipv6 = 1;
203
    if (!inet_pton(AF_INET6, url.host, &s6addr)) {
204
      tvherror("iptv", "%s - failed to stop (invalid addr)", name);
205
      return;
206
    }
207
  }
208

  
209
  if (im->mm_iptv_fd < 0) {
210
    tvherror("iptv", "%s - failed to stop (invalid fd)", name);
211
    return;
212
  }
213

  
214
  /* Bind to interface */
215
  memset(&ifr, 0, sizeof(ifr));
216
  if (im->mm_iptv_interface && *im->mm_iptv_interface) {
217
    snprintf(ifr.ifr_name, IFNAMSIZ, "%s", im->mm_iptv_interface);
218
    if (ioctl(im->mm_iptv_fd, SIOCGIFINDEX, &ifr)) {
219
      tvherror("iptv", "%s - could not find interface %s",
220
               name, im->mm_iptv_interface);
221
      return;
222
    }
223
  }
224

  
225
  /* IPv4 */
226
  if (!ipv6) {
227
    struct ip_mreqn      m;
228
    struct sockaddr_in sin;
229
    memset(&m,   0, sizeof(m));
230
    memset(&sin, 0, sizeof(sin));
231

  
232
    /* Prepare */
233
    sin.sin_family = AF_INET;
234
    sin.sin_port   = htons(url.port);
235
    sin.sin_addr   = saddr;
236

  
237
    /* Leave group */
238
    m.imr_multiaddr      = sin.sin_addr;
239
    m.imr_address.s_addr = 0;
240
#if defined(PLATFORM_LINUX)
241
    m.imr_ifindex        = ifr.ifr_ifindex;
242
#elif defined(PLATFORM_FREEBSD)
243
    m.imr_ifindex        = ifr.ifr_index;
244
#endif
245
#ifdef SOL_IP
246
    solip = SOL_IP;
247
#else
248
    {
249
      struct protoent *pent;
250
      pent = getprotobyname("ip");
251
      solip = (pent != NULL) ? pent->p_proto : 0;
252
    }
253
#endif
254
    tvhlog(LOG_INFO, "iptv_udp" , "now leaving group");
255
    if (setsockopt(im->mm_iptv_fd, solip, IP_DROP_MEMBERSHIP, &m, sizeof(m))) {
256
      inet_ntop(AF_INET, &m.imr_multiaddr, buf, sizeof(buf));
257
      tvhwarn("iptv", "%s - cannot drop membership %s [%s]",
258
              name, buf, strerror(errno));
259
    }
260

  
261
  /* Bind to IPv6 group */
262
  } else {
263
    struct ipv6_mreq m;
264
    struct sockaddr_in6 sin;
265
    memset(&m,   0, sizeof(m));
266
    memset(&sin, 0, sizeof(sin));
267

  
268
    /* Prepare */
269
    sin.sin6_family = AF_INET6;
270
    sin.sin6_port   = htons(url.port);
271
    sin.sin6_addr   = s6addr;
272

  
273
    /* Leave group */
274
    m.ipv6mr_multiaddr = sin.sin6_addr;
275
#if defined(PLATFORM_LINUX)
276
    m.ipv6mr_interface = ifr.ifr_ifindex;
277
#elif defined(PLATFORM_FREEBSD)
278
    m.ipv6mr_interface = ifr.ifr_index;
279
#endif
280
#ifdef SOL_IPV6
281
    if (setsockopt(im->mm_iptv_fd, SOL_IPV6, IPV6_DROP_MEMBERSHIP, &m, sizeof(m))) {
282
      inet_ntop(AF_INET, &m.ipv6mr_multiaddr, buf, sizeof(buf));
283
      tvhwarn("iptv", "%s - cannot join drop membership %s [%s]",
284
              name, buf, strerror(errno));
285
    }
286
#else
287
    tvherror("iptv", "IPv6 multicast not supported");
288
#endif
289
  }
290

  
291
  /* Done */
292
  // close(im->mm_iptv_fd);
293
}
294

  
181 295
static ssize_t
182 296
iptv_udp_read ( iptv_mux_t *im, size_t *off )
183 297
{
......
242 356
    {
243 357
      .scheme = "udp",
244 358
      .start  = iptv_udp_start,
359
      .stop   = iptv_udp_stop,
245 360
      .read   = iptv_udp_read,
246 361
    },
247 362
    {
248 363
      .scheme = "rtp",
249 364
      .start  = iptv_udp_start,
365
      .stop   = iptv_udp_stop,
250 366
      .read   = iptv_rtp_read,
251 367
    }
252 368
  };
253
- 
(2-2/2)