/* Overide ratelimit priority for dvbapi request */ static int32_t dvbapi_override_prio(struct s_reader *reader, ECM_REQUEST *er, int32_t maxecms, struct timeb *actualtime) { if (!module_dvbapi_enabled() || !is_dvbapi_usr(er->client->account->usr)) return -1; int32_t foundspace = -1; int64_t gone = 0; if (reader->lastdvbapirateoverride.time == 0) // fixup for first run! gone = comp_timeb(actualtime, &reader->lastdvbapirateoverride); if (gone > reader->ratelimittime) { int32_t h; struct timeb minecmtime = *actualtime; for (h = 0; h < MAXECMRATELIMIT; h++) { gone = comp_timeb(&minecmtime, &reader->rlecmh[h].last); if (gone > 0) { minecmtime = reader->rlecmh[h].last; foundspace = h; } } reader->lastdvbapirateoverride = *actualtime; cs_log_dbg(D_CLIENT, "prioritizing DVBAPI user %s over other watching client", er->client->account->usr); cs_log_dbg(D_CLIENT, "ratelimiter forcing srvid %04X into slot %d/%d of reader %s", er->srvid, foundspace + 1, maxecms, reader->label); } else { cs_log_dbg(D_CLIENT, "DVBAPI User %s is switching too fast for ratelimit and can't be prioritized!", er->client->account->usr); } return foundspace; }
void cacheex_timeout(ECM_REQUEST *er) { if(er->cacheex_wait_time_expired) return; er->cacheex_wait_time_expired = 1; if(er->rc >= E_UNHANDLED) { cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} cacheex timeout! ", (check_client(er->client) ? er->client->account->usr : "******"), er->caid, er->prid, er->srvid); // if check_cw mode=0, first try to get cw from cache without check counter! CWCHECK check_cw = get_cwcheck(er); if(!check_cw.mode) { struct ecm_request_t *ecm = NULL; ecm = check_cache(er, er->client); if(ecm) // found in cache { struct s_write_from_cache *wfc = NULL; if(!cs_malloc(&wfc, sizeof(struct s_write_from_cache))) { NULLFREE(ecm); return; } wfc->er_new = er; wfc->er_cache = ecm; if(!add_job(er->client, ACTION_ECM_ANSWER_CACHE, wfc, sizeof(struct s_write_from_cache))) // write_ecm_answer_fromcache { NULLFREE(ecm); } return; } } // check if "normal" readers selected, if not send NOT FOUND! // cacheex1-client (having always no "normal" reader), // or not-cacheex-1 client with no normal readers available (or filtered by LB) if((er->reader_count + er->fallback_reader_count - er->cacheex_reader_count) <= 0) { if(!cfg.wait_until_ctimeout) { er->rc = E_NOTFOUND; er->selected_reader = NULL; er->rcEx = 0; cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} cacheex timeout: NO \"normal\" readers... not_found! ", (check_client(er->client) ? er->client->account->usr : "******"), er->caid, er->prid, er->srvid); send_dcw(er->client, er); return; } } else { if(er->stage < 2) { debug_ecm(D_TRACE, "request for %s %s", username(er->client), buf); request_cw_from_readers(er, 0); } } } }
int32_t stapi_remove_filter(int32_t demux_id, int32_t num, char *pmtfile) { int32_t i, ret = 0; struct s_dvbapi_priority *p; if(!pmtfile) { return 0; } for(p = dvbapi_priority; p != NULL; p = p->next) { if(p->type != 's') { continue; } if(strcmp(pmtfile, p->pmtfile) != 0) { continue; } for(i = 0; i < PTINUM; i++) { if(strcmp(dev_list[i].name, p->devname) == 0 && p->disablefilter == 0) { ret = stapi_do_remove_filter(demux_id, &dev_list[i].demux_fd[demux_id][num], i); } } } if(ret == 1) { cs_log_dbg(D_DVBAPI, "filter %d removed", num); } else { cs_log_dbg(D_DVBAPI, "Error: filter %d was not removed!", num); } return ret; }
/* Starts a thread named nameroutine with the start function startroutine. */ int32_t start_thread(char *nameroutine, void *startroutine, void *arg, pthread_t *pthread, int8_t detach, int8_t modify_stacksize) { pthread_t temp; pthread_attr_t attr; cs_log_dbg(D_TRACE, "starting thread %s", nameroutine); SAFE_ATTR_INIT(&attr); if(modify_stacksize) { SAFE_ATTR_SETSTACKSIZE(&attr, oscam_stacksize); } int32_t ret = pthread_create(pthread == NULL ? &temp : pthread, &attr, startroutine, arg); if(ret) { cs_log("ERROR: can't create %s thread (errno=%d %s)", nameroutine, ret, strerror(ret)); } else { cs_log_dbg(D_TRACE, "%s thread started", nameroutine); if(detach) { pthread_detach(pthread == NULL ? temp : *pthread); } } pthread_attr_destroy(&attr); return ret; }
static void coolapi_read_data(dmx_t *dmx, dmx_callback_data_t *data) { if(!dmx) { cs_log_dbg(D_DVBAPI, "handle is NULL!"); return; } int32_t ret; uchar buffer[4096]; SAFE_SETSPECIFIC(getclient, dvbapi_client); SAFE_MUTEX_LOCK(&dmx->mutex); memset(buffer, 0, sizeof(buffer)); ret = coolapi_read(dmx, data, buffer); SAFE_MUTEX_UNLOCK(&dmx->mutex); if(ret > -1) { uint16_t filters = data->num; uint16_t flt; for (flt = 0; flt < filters; flt++) { uint32_t n = (uint32_t)data->tags[flt]; S_COOL_FILTER *filter = find_filter_by_channel(data->channel, n); if (!filter || data->filters[flt] != filter->filter) { cs_log_dbg(D_DVBAPI, "filter not found in notification!!!!"); continue; } dvbapi_process_input(dmx->demux_id, n, buffer, data->len); } } }
/* write cw to all demuxes in mask with passed index */ int32_t coolapi_write_cw(int32_t mask, uint16_t *STREAMpids, int32_t count, ca_descr_t *ca_descr) { int32_t i, idx = ca_descr->index; int32_t result; void *channel; cs_log_dbg(D_DVBAPI, "cw%d: mask %d index %d pid count %d", ca_descr->parity, mask, idx, count); for(i = 0; i < count; i++) { int32_t pid = STREAMpids[i]; int32_t j; for(j = 0; j < MAX_COOL_DMX; j++) { if(mask & (1 << j)) { result = cnxt_dmx_get_channel_from_pid(dmx_handles[j].handle, pid, &channel); if(result == 0) { cs_log_dbg(D_DVBAPI, "Found demux %d channel %x for pid %04x", j, (int32_t) channel, pid); result = cnxt_dmx_set_channel_key(channel, 0, ca_descr->parity, ca_descr->cw, 8); coolapi_check_error("cnxt_dmx_set_channel_key", result); if(result != 0) { cs_log("set_channel_key failed for demux %d pid %04x", j, pid); } } } } } return 0; }
static int32_t cc_cacheex_push_chk(struct s_client *cl, struct ecm_request_t *er) { struct cc_data *cc = cl->cc; if(chk_is_null_nodeid(cc->peer_node_id,8)) { cs_log_dbg(D_CACHEEX, "cacheex: NO peer_node_id got yet, skip!"); return 0; } if(ll_count(er->csp_lastnodes) >= cacheex_maxhop(cl)) //check max 10 nodes to push: { cs_log_dbg(D_CACHEEX, "cacheex: nodelist reached %d nodes, no push", cacheex_maxhop(cl)); return 0; } uint8_t *remote_node = cc->peer_node_id; //search existing peer nodes: LL_LOCKITER *li = ll_li_create(er->csp_lastnodes, 0); uint8_t *node; while((node = ll_li_next(li))) { cs_log_dbg(D_CACHEEX, "cacheex: check node %" PRIu64 "X == %" PRIu64 "X ?", cacheex_node_id(node), cacheex_node_id(remote_node)); if(memcmp(node, remote_node, 8) == 0) { break; } } ll_li_destroy(li); //node found, so we got it from there, do not push: if(node) { cs_log_dbg(D_CACHEEX, "cacheex: node %" PRIu64 "X found in list => skip push!", cacheex_node_id(node)); return 0; } if(!cl->cc) { if(cl->reader && !cl->reader->tcp_connected) { cc_cli_connect(cl); } } if(!cc || !cl->udp_fd) { cs_log_dbg(D_CACHEEX, "cacheex: not connected %s -> no push", username(cl)); return 0; } //check if cw is already pushed if(check_is_pushed(er->cw_cache, cl)) { return 0; } return 1; }
/** * send own id */ void camd35_cacheex_push_send_own_id(struct s_client *cl, uint8_t *mbuf) { uint8_t rbuf[32]; //minimal size if(!cl->crypted) { return; } cs_log_dbg(D_CACHEEX, "cacheex: received id request from node %" PRIu64 "X %s", cacheex_node_id(mbuf + 20), username(cl)); memset(rbuf, 0, sizeof(rbuf)); rbuf[0] = 0x3e; rbuf[1] = 12; rbuf[2] = 0; memcpy(rbuf + 20, camd35_node_id, 8); cs_log_dbg(D_CACHEEX, "cacheex: sending own id %" PRIu64 "X request %s", cacheex_node_id(camd35_node_id), username(cl)); camd35_send(cl, rbuf, 12); //send adds +20 }
void cs_exit(int32_t sig) { if(cs_dump_stack && (sig == SIGSEGV || sig == SIGBUS || sig == SIGQUIT)) { cs_dumpstack(sig); } set_signal_handler(SIGHUP , 1, SIG_IGN); set_signal_handler(SIGPIPE, 1, SIG_IGN); struct s_client *cl = cur_client(); if(!cl) { return; } // this is very important - do not remove if(cl->typ != 's') { cs_log_dbg(D_TRACE, "thread %8lX ended!", (unsigned long)pthread_self()); free_client(cl); //Restore signals before exiting thread set_signal_handler(SIGPIPE , 0, cs_sigpipe); set_signal_handler(SIGHUP , 1, cs_reload_config); pthread_exit(NULL); return; } if(!exit_oscam) { exit_oscam = sig ? sig : 1; } }
/** * store received remote id */ static void camd35_cacheex_push_receive_remote_id(struct s_client *cl, uint8_t *buf) { memcpy(cl->ncd_skey, buf + 20, 8); cl->ncd_skey[8] = 1; cs_log_dbg(D_CACHEEX, "cacheex: received id answer from %s: %" PRIu64 "X", username(cl), cacheex_node_id(cl->ncd_skey)); }
static void coolapi_dmx_open(void) { int32_t result = 0; device_open_arg_t devarg; if(!dmx_opened) { int32_t i; cs_log_dbg(D_DVBAPI, "Open Coolstream DMX API"); memset(&devarg, 0, sizeof(device_open_arg_t)); devarg.unknown1 = 1; devarg.unknown3 = 3; devarg.unknown6 = 1; for(i = 0; i < MAX_COOL_DMX; i++) { devarg.number = i; result = cnxt_dmx_open(&dmx_handles[i].handle, &devarg, NULL, NULL); coolapi_check_error("cnxt_dmx_open", result); } dmx_opened = 1; } }
int32_t stapi_set_pid(int32_t demux_id, int32_t UNUSED(num), int32_t idx, uint16_t pid, char *UNUSED(pmtfile)) { if(idx == -1) { if (tkd_desc_info[demux[demux_id].dev_index].path_hndl != 0) { cs_log_dbg(D_DVBAPI, "stop descrambling of PID %d on %s", pid, dev_list[demux[demux_id].dev_index].name); uint32_t ErrorCode = oscam_sttkd_Disassociate(dev_list[demux[demux_id].dev_index].name, pid); if (ErrorCode != 0) cs_log("oscam_sttkd_Disassociate faild! ErrorCode: %d", ErrorCode); int i; for (i = 0; i < MAX_STREAMPIDS; i++) { if (tkd_desc_info[demux[demux_id].dev_index].STREAMPIDs[i] == pid) { tkd_desc_info[demux[demux_id].dev_index].STREAMPIDs[i] = 0; break; } } } } return 1; }
static int32_t ac_dw_weight(ECM_REQUEST *er) { struct s_cpmap *cpmap; for(cpmap = cfg.cpmap; (cpmap) ; cpmap = cpmap->next) if((cpmap->caid == 0 || cpmap->caid == er->caid) && (cpmap->provid == 0 || cpmap->provid == er->prid) && (cpmap->sid == 0 || cpmap->sid == er->srvid) && (cpmap->chid == 0 || cpmap->chid == er->chid)) { return (cpmap->dwtime * 100 / 60); } cs_log_dbg(D_CLIENT, "acasc: WARNING: CAID %04X, PROVID %06X, SID %04X, CHID %04X not found in oscam.ac", er->caid, er->prid, er->srvid, er->chid); cs_log_dbg(D_CLIENT, "acasc: set DW lifetime 10 sec"); return 16; // 10*100/60 }
static dmx_t *find_demux(int32_t fd, int32_t dmx_dev_num) { if(dmx_dev_num < 0 || dmx_dev_num >= MAX_COOL_DMX) { cs_log("Invalid demux %d", dmx_dev_num); return NULL; } dmx_t *dmx; int32_t i; if(fd == 0) // DEMUX FILTER ALLOCATE { for(i = 0; i < MAX_FILTER; i++) { dmx = &cdemuxes[dmx_dev_num][i]; if(!dmx->opened) { dmx->fd = COOLDEMUX_FD(dmx_dev_num, i); cs_log_dbg(D_DVBAPI, "opening new fd: %08x", dmx->fd); return dmx; } } cs_log_dbg(D_DVBAPI, "ERROR: no free demux found"); return NULL; } if (!COOLDEMUX_IS_VALID_FD(fd)) { cs_log_dbg(D_DVBAPI, "ERROR: invalid FD"); return NULL; } dmx_dev_num = COOLDEMUX_DMX_DEV(fd); for(i = 0; i < MAX_FILTER; i++) { dmx = &cdemuxes[dmx_dev_num][i]; if(dmx->fd == fd) { return dmx; } } cs_log_dbg(D_DVBAPI, "ERROR: CANT FIND Demux %08x", fd); return NULL; }
int32_t coolapi_close_device(int32_t fd) { dmx_t *dmx = find_demux(fd, 0); if(!dmx) { cs_log_dbg(D_DVBAPI, "dmx is NULL!"); SAFE_MUTEX_UNLOCK(&demux_lock); return -1; } cs_log_dbg(D_DVBAPI, "closing fd=%08x", fd); dmx->opened = 0; pthread_mutex_destroy(&dmx->mutex); memset(dmx, 0, sizeof(dmx_t)); return 0; }
static void ParsePMTData(emu_stream_client_data *cdata) { uint8_t* data = cdata->pmt_data; uint16_t section_length = SCT_LEN(data); int32_t i; uint16_t program_info_length = 0, es_info_length = 0; uint8_t descriptor_tag = 0, descriptor_length = 0; uint8_t stream_type; uint16_t stream_pid, caid; cdata->pcr_pid = b2i(2, data+8) &0x1FFF; if(cdata->pcr_pid != 0x1FFF) { cs_log_dbg(D_READER, "stream %i found pcr pid : 0x%04X (%i)",cdata->connid, cdata->pcr_pid, cdata->pcr_pid); } program_info_length = b2i(2, data+10) &0xFFF; if(12+program_info_length >= section_length) { return; } for(i=12; i+1 < 12+program_info_length; i+=descriptor_length+2) { descriptor_tag = data[i]; descriptor_length = data[i+1]; if(descriptor_length < 1) { break; } if(i+1+descriptor_length >= 12+program_info_length) { break; } if(descriptor_tag == 0x09 && descriptor_length >= 4) { caid = b2i(2, data+i+2); if(caid>>8 == 0x0E) { cdata->ecm_pid = b2i(2, data+i+4) &0x1FFF; cs_log_dbg(D_READER, "stream %i found ecm pid : 0x%04X (%i)", cdata->connid, cdata->ecm_pid, cdata->ecm_pid); break; } } }
int32_t check_sct_len(const uchar *data, int32_t off) { int32_t len = SCT_LEN(data); if(len + off > MAX_LEN) { cs_log_dbg(D_TRACE | D_READER, "check_sct_len(): smartcard section too long %d > %d", len, MAX_LEN - off); len = -1; } return len; }
int32_t coolapi_get_filter_num(int32_t fd) { if (!COOLDEMUX_IS_VALID_FD(fd)) { cs_log_dbg(D_DVBAPI, "ERROR: invalid FD"); return -1; } return cdemuxes[COOLDEMUX_DMX_DEV(fd)][COOLDEMUX_FLT_IDX(fd)].filter_num; }
void ac_chk(struct s_client *cl, ECM_REQUEST *er, int32_t level) { if(!cl->ac_limit || !cfg.ac_enabled) { return; } struct s_acasc_shm *acasc = &cl->acasc; if(level == 1) { if(er->rc == E_FAKE) { acasc->ac_count++; } if(er->rc >= E_NOTFOUND) { return; } // not found if(memcmp(ac_ecmd5, er->ecmd5, CS_ECMSTORESIZE) != 0) { acasc->ac_count += ac_dw_weight(er); memcpy(ac_ecmd5, er->ecmd5, CS_ECMSTORESIZE); } return; } if(acasc->ac_deny) { if(cl->ac_penalty) { if(cl->ac_penalty == 3) { if(cl->ac_fakedelay > 0) { cs_log_dbg(D_CLIENT, "acasc: fake delay %d ms", cl->ac_fakedelay); } } else { cs_log_dbg(D_CLIENT, "acasc: send fake dw"); er->rc = E_FAKE; // fake er->rcEx = 0; } if(cl->ac_fakedelay > 0) { cs_sleepms(cl->ac_fakedelay); } } } }
/** * request remote id */ void camd35_cacheex_push_request_remote_id(struct s_client *cl) { uint8_t rbuf[32];//minimal size memset(rbuf, 0, sizeof(rbuf)); rbuf[0] = 0x3d; rbuf[1] = 12; rbuf[2] = 0; memcpy(rbuf + 20, camd35_node_id, 8); cs_log_dbg(D_CACHEEX, "cacheex: sending id request to %s", username(cl)); camd35_send(cl, rbuf, 12); //send adds +20 }
void cacheex_mode1_delay(ECM_REQUEST *er) { if(!er->cacheex_wait_time_expired && er->cacheex_mode1_delay && er->cacheex_reader_count > 0 && !er->stage && er->rc >= E_UNHANDLED) { cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} cacheex_mode1_delay timeout! ", (check_client(er->client) ? er->client->account->usr : "******"), er->caid, er->prid, er->srvid); request_cw_from_readers(er, 1); // setting stop_stage=1, we request only cacheex mode 1 readers. Others are requested at cacheex timeout! } }
static void log_cacheex_cw(ECM_REQUEST *er, char *reason) { uint8_t *data; uchar remotenodeid[16]; data = ll_last_element(er->csp_lastnodes); if(data) memcpy(remotenodeid, data, 8); char buf_ecm[109]; format_ecm(er, buf_ecm, 109); cs_log_dbg(D_CACHEEX,"got pushed ecm [%s]: %s - odd/even 0x%x - CSP cw: %s - pushed from %s, at hop %d, origin node-id %" PRIu64 "X", reason, buf_ecm, er->ecm[0], (checkECMD5(er)?"NO":"YES"), er->from_csp ? "csp" : username((er->cacheex_src?er->cacheex_src:er->client)), ll_count(er->csp_lastnodes), er->csp_lastnodes ? cacheex_node_id(remotenodeid): 0); }
int32_t stapi_activate_section_filter(int32_t fd, uchar *filter, uchar *mask) { uint32_t ErrorCode; ErrorCode = oscam_stapi5_FilterSet(fd, filter, mask); if(ErrorCode != 0) { cs_log_dbg(D_DVBAPI, "Error: oscam_stapi5_FilterSet; %d", ErrorCode); return -1; } return ErrorCode; }
static int32_t radegast_recv_chk(struct s_client *client, uchar *dcw, int32_t *rc, uchar *buf, int32_t UNUSED(n)) { if((buf[0] == 2) && (buf[1] == 0x12)) { char tmp_dbg[33]; memcpy(dcw, buf + 4, 16); cs_log_dbg(D_CLIENT, "radegast: recv chk - %s", cs_hexdump(0, dcw, 16, tmp_dbg, sizeof(tmp_dbg))); *rc = 1; return (client->reader->msg_idx); } return (-1); }
bool cacheex_check_queue_length(struct s_client *cl) { // Avoid full running queues: if(ll_count(cl->joblist) <= 2000) return 0; cs_log_dbg(D_TRACE, "WARNING: job queue %s %s has more than 2000 jobs! count=%d, dropped!", cl->typ == 'c' ? "client" : "reader", username(cl), ll_count(cl->joblist)); // Thread down??? SAFE_MUTEX_LOCK(&cl->thread_lock); if(cl && !cl->kill && cl->thread && cl->thread_active) { // Just test for invalid thread id: if(pthread_detach(cl->thread) == ESRCH) { cl->thread_active = 0; cs_log_dbg(D_TRACE, "WARNING: %s %s thread died!", cl->typ == 'c' ? "client" : "reader", username(cl)); } } SAFE_MUTEX_UNLOCK(&cl->thread_lock); return 1; }
void camd35_cacheex_recv_ce1_cwc_info(struct s_client *cl, uchar *buf, int32_t idx) { if(!(buf[0] == 0x01 && buf[18] < 0xFF && buf[18] > 0x00)) // cwc info ; normal camd3 ecms send 0xFF but we need no cycletime of 255 ;) return; ECM_REQUEST *er = NULL; int32_t i; for(i = 0; i < cfg.max_pending; i++) { if (cl->ecmtask[i].idx == idx) { er = &cl->ecmtask[i]; break; } } if(!er) { return; } int8_t rc = buf[3]; if(rc != E_FOUND) { return; } if(buf[18]) { if(buf[18] & (0x01 << 7)) { er->cwc_cycletime = (buf[18] & 0x7F); // remove bit 8 to get cycletime er->parent->cwc_cycletime = er->cwc_cycletime; er->cwc_next_cw_cycle = 1; er->parent->cwc_next_cw_cycle = er->cwc_next_cw_cycle; } else { er->cwc_cycletime = buf[18]; er->parent->cwc_cycletime = er->cwc_cycletime; er->cwc_next_cw_cycle = 0; er->parent->cwc_next_cw_cycle = er->cwc_next_cw_cycle; } } if(cl->typ == 'c' && cl->account && cl->account->cacheex.mode) { cl->account->cwc_info++; } else if((cl->typ == 'p' || cl->typ == 'r') && (cl->reader && cl->reader->cacheex.mode)) { cl->cwc_info++; } cs_log_dbg(D_CWC, "CWC (CE1) received from %s cycletime: %isek - nextcwcycle: CW%i for %04X@%06X:%04X", username(cl), er->cwc_cycletime, er->cwc_next_cw_cycle, er->caid, er->prid, er->srvid); }
static void dmx_callback(void *channel, dmx_t *dmx, int32_t type, dmx_callback_data_t *data) { if(!dmx) { cs_log_dbg(D_DVBAPI, "wrong dmx pointer !!!"); return; } if(data == NULL) return; if (channel != data->channel) return; switch(type) { #ifdef WITH_COOLAPI2 case 0x11: #else case 0x0E: #endif if(data->type == COOLDEMUX_DATA_RECEIVED && data->len > 0) { coolapi_read_data(dmx, data); } else if(data->type == COOLDEMUX_CRC_ERROR && data->len > 0) { cs_log_dbg(D_DVBAPI, "CRC error !!!"); cnxt_cbuf_removed_data(data->buf, data->len); } else if(data->type == COOLDEMUX_BUFF_OVERFLOW) { cs_log_dbg(D_DVBAPI, "OVERFLOW !!!"); } else { cs_log_dbg(D_DVBAPI, "unknown callback data %d len %d", data->type, data->len); } break; default: break; } }
void ac_init_client(struct s_client *client, struct s_auth *account) { client->ac_limit = 0; client->ac_penalty = account->ac_penalty == -1 ? cfg.ac_penalty : account->ac_penalty; client->ac_fakedelay = account->ac_fakedelay == -1 ? cfg.ac_fakedelay : account->ac_fakedelay; if(cfg.ac_enabled) { int32_t numusers = account->ac_users; if(numusers == -1) { numusers = cfg.ac_users; } if(numusers) { client->ac_limit = (numusers * 100 + 80) * cfg.ac_stime; cs_log_dbg(D_CLIENT, "acasc: user '%s', users=%d, stime=%d min, dwlimit=%d per min, penalty=%d", account->usr, numusers, cfg.ac_stime, numusers * 100 + 80, client->ac_penalty); } else { cs_log_dbg(D_CLIENT, "acasc: anti-cascading not used for user '%s'", account->usr); } } }
static int32_t camd35_cacheex_push_chk(struct s_client *cl, ECM_REQUEST *er) { if(ll_count(er->csp_lastnodes) >= cacheex_maxhop(cl)) //check max 10 nodes to push: { cs_log_dbg(D_CACHEEX, "cacheex: nodelist reached %d nodes, no push", cacheex_maxhop(cl)); return 0; } if(cl->reader) { if(!cl->reader->tcp_connected) { cs_log_dbg(D_CACHEEX, "cacheex: not connected %s -> no push", username(cl)); return 0; } } //if(chk_is_null_nodeid(remote_node,8)){ if(!cl->ncd_skey[8]) { cs_log_dbg(D_CACHEEX, "cacheex: NO peer_node_id got yet, skip!"); return 0; } uint8_t *remote_node = cl->ncd_skey; //it is sended by reader(mode 2) or client (mode 3) each 30s using keepalive msgs //search existing peer nodes: LL_LOCKITER *li = ll_li_create(er->csp_lastnodes, 0); uint8_t *node; while((node = ll_li_next(li))) { cs_log_dbg(D_CACHEEX, "cacheex: check node %" PRIu64 "X == %" PRIu64 "X ?", cacheex_node_id(node), cacheex_node_id(remote_node)); if(memcmp(node, remote_node, 8) == 0) { break; } } ll_li_destroy(li); //node found, so we got it from there, do not push: if(node) { cs_log_dbg(D_CACHEEX, "cacheex: node %" PRIu64 "X found in list => skip push!", cacheex_node_id(node)); return 0; } //check if cw is already pushed if(check_is_pushed(er->cw_cache, cl)) { return 0; } cs_log_dbg(D_CACHEEX, "cacheex: push ok %" PRIu64 "X to %" PRIu64 "X %s", cacheex_node_id(camd35_node_id), cacheex_node_id(remote_node), username(cl)); return 1; }
int32_t stapi_set_filter(int32_t demux_id, uint16_t pid, uchar *filter, uchar *mask, int32_t num, char *pmtfile) { int32_t i; int32_t ret = -1; char dest[1024]; uint16_t pids[1] = { pid }; struct s_dvbapi_priority *p; if(!pmtfile) { cs_log_dbg(D_DVBAPI, "No valid pmtfile!"); return -1; } cs_log_dbg(D_DVBAPI, "pmt file %s demux_id %d", pmtfile, demux_id); for(p = dvbapi_priority; p != NULL; p = p->next) { if(p->type != 's') { continue; // stapi rule? } if(strcmp(pmtfile, p->pmtfile) != 0) { continue; // same file? } for(i = 0; i < PTINUM; i++) { if(strcmp(dev_list[i].name, p->devname) == 0 && p->disablefilter == 0) // check device name and if filtering is enabled! { cs_log_dbg(D_DVBAPI, "set stapi filter on %s for pid %04X", dev_list[i].name, pids[0]); ret = stapi_do_set_filter(demux_id, &dev_list[i].demux_fd[demux_id][num], pids, 1, filter, mask, i); if(ret > 0) // success { demux[demux_id].dev_index = i; cs_log_dbg(D_DVBAPI, "%s filter %d set (pid %04X)", dev_list[i].name, num, pid); return ret; // return filternumber } else // failure { cs_log_dbg(D_DVBAPI, "Error setting new filter for pid %04X on %s!", pid, dev_list[i].name); return -1; // set return to error } } } } if(p == NULL) { cs_log_dbg(D_DVBAPI, "No matching S: line in oscam.dvbapi for pmtfile %s -> stop descrambling!", pmtfile); snprintf(dest, sizeof(dest), "%s%s", TMPDIR, demux[demux_id].pmt_file); unlink(dest); // remove obsolete pmt file dvbapi_stop_descrambling(demux_id); } return ret; }