Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/src/access.c b/src/access.c
- index 5d2930a..656c9dc 100644
- --- a/src/access.c
- +++ b/src/access.c
- @@ -365,7 +365,7 @@ access_dump_a(access_t *a)
- int first;
- tvh_strlcatf(buf, sizeof(buf), l,
- - "%s:%s [%c%c%c%c%c%c%c%c%c%c%c], conn=%u:s%u:r%u:l%u%s",
- + "%s:%s [%c%c%c%c%c%c%c%c%c%c%c], conn=%u:s%u:r%u:ms%u:mr%u:l%u%s",
- a->aa_representative ?: "<no-id>",
- a->aa_username ?: "<no-user>",
- a->aa_rights & ACCESS_STREAMING ? 'S' : ' ',
- @@ -382,6 +382,8 @@ access_dump_a(access_t *a)
- a->aa_conn_limit,
- a->aa_conn_limit_streaming,
- a->aa_conn_limit_dvr,
- + a->aa_muxes_limit_streaming,
- + a->aa_muxes_limit_dvr,
- a->aa_uilevel,
- a->aa_match ? ", matched" : "");
- @@ -488,6 +490,12 @@ access_update(access_t *a, access_entry_t *ae)
- break;
- }
- + if (a->aa_muxes_limit_streaming < ae->ae_muxes_limit_streaming)
- + a->aa_muxes_limit_streaming = ae->ae_muxes_limit_streaming;
- +
- + if (a->aa_muxes_limit_dvr < ae->ae_muxes_limit_dvr)
- + a->aa_muxes_limit_dvr = ae->ae_muxes_limit_dvr;
- +
- if(ae->ae_uilevel > a->aa_uilevel)
- a->aa_uilevel = ae->ae_uilevel;
- @@ -1530,6 +1538,24 @@ const idclass_t access_entry_class = {
- .opts = PO_EXPERT
- },
- {
- + .type = PT_U32,
- + .id = "muxes_limit_streaming",
- + .name = N_("Limit muxes for streaming"),
- + .desc = N_("The number of streaming muxes this user can "
- + "simulteanously use on the server."),
- + .off = offsetof(access_entry_t, ae_muxes_limit_streaming),
- + .opts = PO_EXPERT
- + },
- + {
- + .type = PT_U32,
- + .id = "muxes_limit_dvr",
- + .name = N_("Limit muxes for DVR"),
- + .desc = N_("The number of DVR muxes this user can "
- + "simulteanously use on the server."),
- + .off = offsetof(access_entry_t, ae_muxes_limit_dvr),
- + .opts = PO_EXPERT
- + },
- + {
- .type = PT_S64,
- .intextra = CHANNEL_SPLIT,
- .id = "channel_min",
- diff --git a/src/access.h b/src/access.h
- index 4aabc2a..14b885a 100644
- --- a/src/access.h
- +++ b/src/access.h
- @@ -115,6 +115,9 @@ typedef struct access_entry {
- int ae_conn_limit_type;
- uint32_t ae_conn_limit;
- + uint32_t ae_muxes_limit_streaming;
- + uint32_t ae_muxes_limit_dvr;
- +
- int ae_dvr;
- int ae_htsp_dvr;
- int ae_all_dvr;
- @@ -158,6 +161,8 @@ typedef struct access {
- uint32_t aa_conn_limit_dvr;
- uint32_t aa_conn_streaming;
- uint32_t aa_conn_dvr;
- + uint32_t aa_muxes_limit_streaming;
- + uint32_t aa_muxes_limit_dvr;
- int aa_uilevel;
- int aa_uilevel_nochange;
- char *aa_theme;
- diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c
- index 881b7b8..574939f 100644
- --- a/src/dvr/dvr_rec.c
- +++ b/src/dvr/dvr_rec.c
- @@ -70,6 +70,7 @@ dvr_rec_subscribe(dvr_entry_t *de)
- access_t *aa;
- uint32_t rec_count, net_count;
- int c1, c2;
- + idnode_list_mapping_t* ilm;
- assert(de->de_s == NULL);
- assert(de->de_chain == NULL);
- @@ -107,6 +108,30 @@ dvr_rec_subscribe(dvr_entry_t *de)
- return -EOVERFLOW;
- }
- }
- +
- + if (aa->aa_muxes_limit_dvr)
- + {
- + ilm = LIST_FIRST(&de->de_channel->ch_services);
- + if (ilm)
- + {
- + service_t* ch_first_service = (service_t* )ilm->ilm_in1;
- + if (ch_first_service)
- + {
- + source_info_t si;
- + int count;
- + ch_first_service->s_setsourceinfo(ch_first_service, &si);
- + count = subscription_get_user_count_on_other_muxes(de->de_creator, si.si_mux_uuid, 1);
- + if (count >= aa->aa_muxes_limit_dvr)
- + {
- + tvherror("htsp", "user [%s] is already using %d muxes for recording while the max is %d", de->de_creator?:"no-user", count, aa->aa_muxes_limit_dvr);
- + access_destroy(aa);
- + return -EINVAL;
- + }
- + service_source_info_free(&si);
- + }
- + }
- + }
- +
- access_destroy(aa);
- pro = de->de_config->dvr_profile;
- diff --git a/src/htsp_server.c b/src/htsp_server.c
- index bbad29c..1eaed9f 100644
- --- a/src/htsp_server.c
- +++ b/src/htsp_server.c
- @@ -2333,6 +2333,7 @@ htsp_method_subscribe(htsp_connection_t *htsp, htsmsg_t *in)
- channel_t *ch;
- htsp_subscription_t *hs;
- profile_t *pro;
- + idnode_list_mapping_t* ilm;
- if(htsmsg_get_u32(in, "subscriptionId", &sid))
- return htsp_error(htsp, N_("Invalid arguments"));
- @@ -2396,6 +2397,29 @@ htsp_method_subscribe(htsp_connection_t *htsp, htsmsg_t *in)
- if (pro->pro_prefersd)
- convert_channel_to_sd(ch, &ch);
- + if (htsp->htsp_granted_access && htsp->htsp_granted_access->aa_muxes_limit_streaming)
- + {
- + ilm = LIST_FIRST(&ch->ch_services);
- + if (ilm)
- + {
- + service_t* ch_first_service = (service_t* )ilm->ilm_in1;
- + if (ch_first_service)
- + {
- + source_info_t si;
- + int count;
- + ch_first_service->s_setsourceinfo(ch_first_service, &si);
- + count = subscription_get_user_count_on_other_muxes(htsp->htsp_username, si.si_mux_uuid, 0);
- + if (count >= htsp->htsp_granted_access->aa_muxes_limit_streaming)
- + {
- + tvherror("htsp", "user [%s] is already using %d muxes for streaming while the max is %d", htsp->htsp_username?:"no-user", count, htsp->htsp_granted_access->aa_muxes_limit_streaming);
- + free(hs);
- + return htsp_error(htsp, "Stream setup error, reach max allowed muxes for streaming");
- + }
- + service_source_info_free(&si);
- + }
- + }
- + }
- +
- profile_chain_init(&hs->hs_prch, pro, ch);
- if (profile_chain_work(&hs->hs_prch, &hs->hs_input, timeshiftPeriod, 0)) {
- tvhlog(LOG_ERR, "htsp", "unable to create profile chain '%s'", profile_get_name(pro));
- diff --git a/src/subscriptions.c b/src/subscriptions.c
- index 276cade..76eae6d 100644
- --- a/src/subscriptions.c
- +++ b/src/subscriptions.c
- @@ -1225,3 +1225,31 @@ void subscription_log(th_subscription_t *s, int on)
- }
- }
- +int subscription_get_user_count_on_other_muxes(char *username, tvh_uuid_t mux_uuid, int is_dvr)
- +{
- + th_subscription_t *s;
- + int count;
- +
- + count = 0;
- +
- + LIST_FOREACH(s, &subscriptions, ths_global_link) {
- + if (s->ths_service) {
- + source_info_t si;
- + s->ths_service->s_setsourceinfo(s->ths_service, &si);
- + if (s->ths_username && username && !strcmp(username, s->ths_username) && uuid_cmp(&si.si_mux_uuid, &mux_uuid)) {
- + if (is_dvr) {
- + if (strstr(s->ths_title, "DVR"))
- + count++;
- + }
- + else {
- + if (!strstr(s->ths_title, "DVR"))
- + count++;
- + }
- + }
- + service_source_info_free(&si);
- + }
- + }
- +
- + return count;
- +}
- +
- diff --git a/src/subscriptions.h b/src/subscriptions.h
- index 5fb5ecf..7209ec3 100644
- --- a/src/subscriptions.h
- +++ b/src/subscriptions.h
- @@ -231,4 +231,6 @@ static inline int subscriptions_active(void)
- struct htsmsg;
- struct htsmsg *subscription_create_msg(th_subscription_t *s, const char *lang);
- +int subscription_get_user_count_on_other_muxes(char *username, tvh_uuid_t mux_uuid, int is_dvr);
- +
- #endif /* SUBSCRIPTIONS_H */
- diff --git a/src/webui/static/app/acleditor.js b/src/webui/static/app/acleditor.js
- index 60757dc..a20946d 100644
- --- a/src/webui/static/app/acleditor.js
- +++ b/src/webui/static/app/acleditor.js
- @@ -7,7 +7,7 @@ tvheadend.acleditor = function(panel, index)
- var list = 'enabled,username,password,prefix,' +
- 'lang,webui,uilevel,uilevel_nochange,admin,' +
- 'streaming,adv_streaming,htsp_streaming,' +
- - 'profile,conn_limit_type,conn_limit,' +
- + 'profile,conn_limit_type,conn_limit,muxes_limit_streaming,muxes_limit_dvr,' +
- 'dvr,htsp_dvr,all_dvr,all_rw_dvr,' +
- 'dvr_config,channel_min,channel_max,' +
- 'channel_tag_exclude,channel_tag,comment';
- @@ -15,7 +15,7 @@ tvheadend.acleditor = function(panel, index)
- var list2 = 'enabled,username,password,prefix,' +
- 'lang,webui,themeui,langui,uilevel,uilevel_nochange,admin,' +
- 'streaming,adv_streaming,htsp_streaming,' +
- - 'profile,conn_limit_type,conn_limit,' +
- + 'profile,conn_limit_type,conn_limit,muxes_limit_streaming,muxes_limit_dvr,' +
- 'dvr,htsp_dvr,all_dvr,all_rw_dvr,' +
- 'failed_dvr,htsp_anonymize,dvr_config,' +
- 'channel_min,channel_max,channel_tag_exclude,' +
- @@ -43,6 +43,8 @@ tvheadend.acleditor = function(panel, index)
- admin: { width: 100 },
- conn_limit_type:{ width: 160 },
- conn_limit: { width: 160 },
- + muxes_limit_streaming:{ width: 160 },
- + muxes_limit_dvr:{ width: 160 },
- channel_min: { width: 160 },
- channel_max: { width: 160 }
- },
- diff --git a/src/webui/webui.c b/src/webui/webui.c
- index bca4d92..c70d583 100644
- --- a/src/webui/webui.c
- +++ b/src/webui/webui.c
- @@ -1211,6 +1211,8 @@ http_stream_channel(http_connection_t *hc, channel_t *ch, int weight)
- const char *name;
- void *tcp_id;
- int res = HTTP_STATUS_SERVICE;
- + idnode_list_mapping_t* ilm;
- + service_t* ch_first_service;
- if (http_access_verify_channel(hc, ACCESS_STREAMING, ch))
- return HTTP_STATUS_UNAUTHORIZED;
- @@ -1232,6 +1234,30 @@ http_stream_channel(http_connection_t *hc, channel_t *ch, int weight)
- else
- qsize = 1500000;
- + if (hc->hc_access && hc->hc_access->aa_muxes_limit_streaming)
- + {
- + ilm = LIST_FIRST(&ch->ch_services);
- + if (ilm)
- + {
- + ch_first_service = (service_t* )ilm->ilm_in1;
- + if (ch_first_service)
- + {
- + source_info_t si;
- + int count;
- + ch_first_service->s_setsourceinfo(ch_first_service, &si);
- + count = subscription_get_user_count_on_other_muxes(hc->hc_username?:(hc->hc_access?hc->hc_access->aa_username:NULL), si.si_mux_uuid, 0);
- + if (count >= hc->hc_access->aa_muxes_limit_streaming)
- + {
- + tvherror("webui", "user [%s] is already using %d muxes for streaming while the max is %d",
- + hc->hc_username?:(hc->hc_access?hc->hc_access->aa_username:"no-user"), count, hc->hc_access->aa_muxes_limit_streaming);
- + http_stream_postop(tcp_id);
- + return HTTP_STATUS_UNAUTHORIZED;;
- + }
- + service_source_info_free(&si);
- + }
- + }
- + }
- +
- profile_chain_init(&prch, pro, ch);
- if (!profile_chain_open(&prch, NULL, 0, qsize)) {
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement