]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
SAT>IP Server: fix the pid subscriptions (stack overflow, duplicate pids)
authorJaroslav Kysela <perex@perex.cz>
Mon, 23 Mar 2015 11:50:05 +0000 (12:50 +0100)
committerJaroslav Kysela <perex@perex.cz>
Mon, 23 Mar 2015 11:50:05 +0000 (12:50 +0100)
src/input/mpegts/mpegts_input.c
src/input/mpegts/mpegts_pid.c
src/input/mpegts/satip/satip_frontend.c
src/satip/rtp.c
src/satip/rtsp.c

index 0f84225a48fa8ba3f1ac900fb6169c005c8d5452..36e6b1042ffa91ac91aceea95dddf6edcfd16dcd 100644 (file)
@@ -565,8 +565,7 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags,
     /* Ensure that filtered PIDs are not send in ts_recv_raw */
     TAILQ_FOREACH(st, &s->s_filt_components, es_filt_link)
       if (st->es_type != SCT_CA && st->es_pid >= 0 && st->es_pid < 8192)
-        if (!mpegts_pid_exists(pids, st->es_pid))
-          mpegts_pid_add(pids, st->es_pid);
+        mpegts_pid_add(pids, st->es_pid);
 
     LIST_FOREACH(s2, &s->s_masters, s_masters_link) {
       pthread_mutex_lock(&s2->s_stream_mutex);
index 99f1084033750b51851fe543b431b765b22fa3d1..cf691b2aa6b89a8af3f182acc38422f5bb94ad82 100644 (file)
@@ -65,6 +65,8 @@ mpegts_pid_add(mpegts_apids_t *pids, mpegts_apid_t pid)
   mpegts_apid_t *p;
   int i;
 
+  if (mpegts_pid_exists(pids, pid))
+    return 0;
   assert(pids);
   assert(pid >= 0 && pid <= 8191);
   if (pids->alloc == pids->count) {
@@ -190,9 +192,14 @@ mpegts_pid_dump(mpegts_apids_t *pids, char *buf, int len)
 {
   int i, l = 0;
 
+  if (len < 1) {
+    if (len)
+      *buf = '\0';
+    return len;
+  }
   if (pids->all)
     return snprintf(buf, len, "all");
-  for (i = 0; i < pids->count; i++)
+  for (i = 0; i < pids->count && l + 1 < len; i++)
     l += snprintf(buf + l, len - l, "%s%i",
                   i > 0 ? "," : "", pids->pids[i]);
   return l;
index 0ca098702dca9668ce238509d74e1b69ef241a21..89a32c56bee737718743c30baeadb5fa214d6c71 100644 (file)
@@ -538,7 +538,7 @@ satip_frontend_add_pid( satip_frontend_t *lfe, int pid)
     return 0;
 
   tr = lfe->sf_req;
-  if (tr && !mpegts_pid_exists(&tr->sf_pids, pid)) {
+  if (tr) {
     mpegts_pid_add(&tr->sf_pids, pid);
     return 1;
   }
index a942cc55f7f5a98d4a5d0881ed9b7b74f35949cb..bdc3961c56fb150288a8c08762fdb9354ec3cf82 100644 (file)
@@ -373,7 +373,7 @@ satip_status_build(satip_rtp_session_t *rtp, char *buf, int len)
   char pids[1400];
   const char *delsys, *msys, *pilot, *rolloff;
   const char *bw, *tmode, *gi, *plp, *t2id, *sm, *c2tft, *ds, *specinv;
-  int i, j, r, level = 0, lock = 0, quality = 0;
+  int r, level = 0, lock = 0, quality = 0;
 
   lock = rtp->sig_lock;
   switch (rtp->sig.signal_scale) {
@@ -399,11 +399,7 @@ satip_status_build(satip_rtp_session_t *rtp, char *buf, int len)
     break;
   }
 
-  pids[0] = 0;
-  for (i = j = 0; i < rtp->pids.count; i++)
-    j += snprintf(pids + j, sizeof(pids) - j, "%d,", rtp->pids.pids[i]);
-  if (j && pids[j-1] == ',')
-    pids[j-1] = '\0';
+  mpegts_pid_dump(&rtp->pids, pids, sizeof(pids));
 
   switch (rtp->dmc.dmc_fe_delsys) {
   case DVB_SYS_DVBS:
index 110ba1ccfa7e7c2421582250fa12b92b86da88b1..d9addef02d880091bfcd57dae37c5465a84d49d0 100644 (file)
@@ -377,7 +377,7 @@ rtsp_clean(session_t *rs)
  *
  */
 static int
-rtsp_validate_service(mpegts_service_t *s)
+rtsp_validate_service(mpegts_service_t *s, mpegts_apids_t *pids)
 {
   int av = 0, enc = 0;
   elementary_stream_t *st;
@@ -390,10 +390,11 @@ rtsp_validate_service(mpegts_service_t *s)
   TAILQ_FOREACH(st, &s->s_components, es_link) {
     if (st->es_type == SCT_CA)
       enc = 1;
-    if (st->es_pid > 0 &&
-        (SCT_ISVIDEO(st->es_type) || SCT_ISAUDIO(st->es_type)))
-      av = 1;
-    }
+    if (st->es_pid > 0)
+      if (pids == NULL || mpegts_pid_exists(pids, st->es_pid))
+        if ((SCT_ISVIDEO(st->es_type) || SCT_ISAUDIO(st->es_type)))
+          av = 1;
+  }
   pthread_mutex_unlock(&s->s_stream_mutex);
   return enc && av;
 }
@@ -420,12 +421,12 @@ rtsp_manage_descramble(session_t *rs)
 
   if (rs->pids.all) {
     LIST_FOREACH(s, &rs->mux->mm_services, s_dvb_mux_link)
-      if (rtsp_validate_service(s))
+      if (rtsp_validate_service(s, NULL))
         idnode_set_add(found, &s->s_id, NULL);
   } else {
     for (i = 0; i < rs->pids.count; i++) {
       s = mpegts_service_find_by_pid((mpegts_mux_t *)rs->mux, rs->pids.pids[i]);
-      if (s != NULL && rtsp_validate_service(s))
+      if (s != NULL && rtsp_validate_service(s, &rs->pids))
         if (!idnode_set_exists(found, &s->s_id))
           idnode_set_add(found, &s->s_id, NULL);
     }
@@ -1035,10 +1036,12 @@ play:
     mpegts_pid_add_group(&rs->pids, &addpids);
 
   dvb_mux_conf_str(dmc, buf, sizeof(buf));
-  s = buf + strlen(buf);
-  s += snprintf(s, sizeof(buf) - (s - buf), " pids ");
-  if (mpegts_pid_dump(&rs->pids, s, sizeof(buf) - (s - buf)) == 0)
-    snprintf(s, sizeof(buf) - (s - buf), "<none>");
+  r = strlen(buf);
+  if (r + 1 < sizeof(buf))
+    r += snprintf(buf + r, sizeof(buf) - r, " pids ");
+  if (r + 1 < sizeof(buf) &&
+      mpegts_pid_dump(&rs->pids, buf + r, sizeof(buf) - r) == 0)
+    snprintf(buf + r, sizeof(buf) - r, "<none>");
 
   tvhdebug("satips", "%i/%s/%d: %s from %s:%d %s",
            rs->frontend, rs->session, rs->stream,
@@ -1451,6 +1454,7 @@ rtsp_close_session(session_t *rs)
   udp_close(rs->udp_rtcp);
   rs->udp_rtcp = NULL;
   pthread_mutex_lock(&global_lock);
+  mpegts_pid_reset(&rs->pids);
   rtsp_clean(rs);
   gtimer_disarm(&rs->timer);
   pthread_mutex_unlock(&global_lock);