/**** INCOMING FILTER CHECK ***/ uint8_t check_cacheex_filter(struct s_client *cl, ECM_REQUEST *er) { if(check_client(cl) && cl->typ == 'p' && cl->reader && cl->reader->cacheex.mode==2 && (!cl->reader->cacheex.drop_csp || checkECMD5(er)) //cacheex_drop_csp-check && chk_ctab(er->caid, &cl->reader->ctab) //Caid-check && (!checkECMD5(er) || chk_ident_filter(er->caid, er->prid, &cl->reader->ftab)) //Ident-check (not for csp: prid=0 always!) && chk_srvid(cl, er) //Service-check && chk_csp_ctab(er, &cl->reader->cacheex.filter_caidtab) //cacheex_ecm_filter -> for compatibility with old oscam ) { return 1; } if(check_client(cl) && cl->typ == 'c' && cl->account && cl->account->cacheex.mode==3 && (!cl->account->cacheex.drop_csp || checkECMD5(er)) //cacheex_drop_csp-check && chk_ctab(er->caid, &cl->ctab) //Caid-check && (!checkECMD5(er) || chk_ident_filter(er->caid, er->prid, &cl->ftab)) //Ident-check (not for csp: prid=0 always!) && chk_srvid(cl, er) //Service-check && chk_csp_ctab(er, &cl->account->cacheex.filter_caidtab) //cacheex_ecm_filter -> for compatibility with old oscam ) { return 1; } NULLFREE(er); return 0; }
/** * cacheex modes: * * cacheex=1 CACHE PULL: * Situation: oscam A reader1 has cacheex=1, oscam B account1 has cacheex=1 * oscam A gets a ECM request, reader1 send this request to oscam B, oscam B checks his cache * a. not found in cache: return NOK * a. found in cache: return OK+CW * b. not found in cache, but found pending request: wait max cacheexwaittime and check again * oscam B never requests new ECMs * * CW-flow: B->A * * cacheex=2 CACHE PUSH: * Situation: oscam A reader1 has cacheex=2, oscam B account1 has cacheex=2 * if oscam B gets a CW, its pushed to oscam A * reader has normal functionality and can request ECMs * * Problem: oscam B can only push if oscam A is connected * Problem or feature?: oscam A reader can request ecms from oscam B * * CW-flow: B->A * */ void cacheex_cache_push(ECM_REQUEST *er) { if(er->rc >= E_NOTFOUND) { return; } //cacheex=2 mode: push (server->remote) struct s_client *cl; cs_readlock(&clientlist_lock); for(cl = first_client->next; cl; cl = cl->next) { if(check_client(cl) && er->cacheex_src != cl) { if(get_module(cl)->num == R_CSP) // always send to csp cl { if(!er->cacheex_src || cfg.csp.allow_reforward) { cacheex_cache_push_to_client(cl, er); } // but not if the origin was cacheex (might loop) } else if(cl->typ == 'c' && !cl->dup && cl->account && cl->account->cacheex.mode == 2) //send cache over user { if(get_module(cl)->c_cache_push // cache-push able && (!er->grp || (cl->grp & er->grp)) //Group-check /**** OUTGOING FILTER CHECK ***/ && (!er->selected_reader || !cacheex_reader(er->selected_reader) || !cfg.block_same_name || strcmp(username(cl), er->selected_reader->label)) //check reader mode-1 loopback by same name && (!er->selected_reader || !cacheex_reader(er->selected_reader) || !cfg.block_same_ip || (check_client(er->selected_reader->client) && !IP_EQUAL(cl->ip, er->selected_reader->client->ip))) //check reader mode-1 loopback by same ip && (!cl->account->cacheex.drop_csp || checkECMD5(er)) //cacheex_drop_csp-check && chk_ctab(er->caid, &cl->ctab) //Caid-check && (!checkECMD5(er) || chk_ident_filter(er->caid, er->prid, &cl->ftab)) //Ident-check (not for csp: prid=0 always!) && chk_srvid(cl, er) //Service-check && chk_csp_ctab(er, &cl->account->cacheex.filter_caidtab) //cacheex_ecm_filter ) { cacheex_cache_push_to_client(cl, er); } } } } cs_readunlock(&clientlist_lock); //cacheex=3 mode: reverse push (reader->server) cs_readlock(&readerlist_lock); cs_readlock(&clientlist_lock); struct s_reader *rdr; for(rdr = first_active_reader; rdr; rdr = rdr->next) { cl = rdr->client; if(check_client(cl) && er->cacheex_src != cl && rdr->cacheex.mode == 3) //send cache over reader { if(rdr->ph.c_cache_push // cache-push able && (!er->grp || (rdr->grp & er->grp)) //Group-check /**** OUTGOING FILTER CHECK ***/ && (!er->selected_reader || !cacheex_reader(er->selected_reader) || !cfg.block_same_name || strcmp(username(cl), er->selected_reader->label)) //check reader mode-1 loopback by same name && (!er->selected_reader || !cacheex_reader(er->selected_reader) || !cfg.block_same_ip || (check_client(er->selected_reader->client) && !IP_EQUAL(cl->ip, er->selected_reader->client->ip))) //check reader mode-1 loopback by same ip && (!rdr->cacheex.drop_csp || checkECMD5(er)) //cacheex_drop_csp-check && chk_ctab(er->caid, &rdr->ctab) //Caid-check && (!checkECMD5(er) || chk_ident_filter(er->caid, er->prid, &rdr->ftab)) //Ident-check (not for csp: prid=0 always!) && chk_srvid(cl, er) //Service-check && chk_csp_ctab(er, &rdr->cacheex.filter_caidtab) //cacheex_ecm_filter ) { cacheex_cache_push_to_client(cl, er); } } } cs_readunlock(&clientlist_lock); cs_readunlock(&readerlist_lock); }