From 30f5c44d2c5da6616eccfc8707de2486e57d88a2 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 23 Mar 2015 12:50:05 +0100 Subject: [PATCH] SAT>IP Server: fix the pid subscriptions (stack overflow, duplicate pids) --- src/input/mpegts/mpegts_input.c | 3 +-- src/input/mpegts/mpegts_pid.c | 9 ++++++++- src/input/mpegts/satip/satip_frontend.c | 2 +- src/satip/rtp.c | 8 ++------ src/satip/rtsp.c | 26 ++++++++++++++----------- 5 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index 0f84225a..36e6b104 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -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); diff --git a/src/input/mpegts/mpegts_pid.c b/src/input/mpegts/mpegts_pid.c index 99f10840..cf691b2a 100644 --- a/src/input/mpegts/mpegts_pid.c +++ b/src/input/mpegts/mpegts_pid.c @@ -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; diff --git a/src/input/mpegts/satip/satip_frontend.c b/src/input/mpegts/satip/satip_frontend.c index 0ca09870..89a32c56 100644 --- a/src/input/mpegts/satip/satip_frontend.c +++ b/src/input/mpegts/satip/satip_frontend.c @@ -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; } diff --git a/src/satip/rtp.c b/src/satip/rtp.c index a942cc55..bdc3961c 100644 --- a/src/satip/rtp.c +++ b/src/satip/rtp.c @@ -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: diff --git a/src/satip/rtsp.c b/src/satip/rtsp.c index 110ba1cc..d9addef0 100644 --- a/src/satip/rtsp.c +++ b/src/satip/rtsp.c @@ -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), ""); + 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, ""); 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);