source: trunk/oscam-ecm.c

Last change on this file was 11703, checked in by nautilus7, 2 years ago

Whitespace cleanup

Note to devs: Please configure your editor to "trim trailing whitespace". Thanks.

File size: 90.3 KB
Line 
1#define MODULE_LOG_PREFIX "ecm"
2
3#include "globals.h"
4#include "cscrypt/md5.h"
5#include "module-anticasc.h"
6#include "module-cacheex.h"
7#include "module-led.h"
8#include "module-stat.h"
9#include "module-webif.h"
10#include "module-ird-guess.h"
11#include "module-cw-cycle-check.h"
12#include "module-gbox.h"
13#include "oscam-cache.h"
14#include "oscam-chk.h"
15#include "oscam-client.h"
16#include "oscam-config.h"
17#include "oscam-ecm.h"
18#include "oscam-garbage.h"
19#include "oscam-failban.h"
20#include "oscam-net.h"
21#include "oscam-time.h"
22#include "oscam-lock.h"
23#include "oscam-string.h"
24#include "oscam-work.h"
25#include "reader-common.h"
26#include "module-cccam-data.h"
27#ifdef CS_CACHEEX_AIO
28#include "oscam-hashtable.h"
29#endif
30
31extern CS_MUTEX_LOCK ecmcache_lock;
32extern struct ecm_request_t *ecmcwcache;
33extern uint16_t len4caid[256];
34extern uint32_t ecmcwcache_size;
35extern int32_t exit_oscam;
36
37extern CS_MUTEX_LOCK ecm_pushed_deleted_lock;
38extern struct ecm_request_t *ecm_pushed_deleted;
39
40static pthread_mutex_t cw_process_sleep_cond_mutex;
41static pthread_cond_t cw_process_sleep_cond;
42static int cw_process_wakeups;
43int64_t ecmc_next, cache_next, msec_wait = 3000;
44
45#ifdef CS_CACHEEX_AIO
46// ecm-cache
47typedef struct ecm_cache
48{
49 struct timeb first_recv_time;// time of first cw received
50 struct timeb upd_time; // updated time. Update time at each cw got
51 uint32_t csp_hash;
52 node ht_node;
53 node ll_node;
54} ECM_CACHE;
55
56static pthread_rwlock_t ecm_cache_lock;
57static hash_table ht_ecm_cache;
58static list ll_ecm_cache;
59static int8_t ecm_cache_init_done = 0;
60
61void free_ecm_cache(void)
62{
63 deinitialize_hash_table(&ht_ecm_cache);
64 pthread_rwlock_destroy(&ecm_cache_lock);
65}
66
67void init_ecm_cache(void)
68{
69#ifdef CS_CACHEEX
70 if(cfg.cw_cache_size > 0 || cfg.cw_cache_memory > 0)
71 {
72 init_hash_table(&ht_ecm_cache, &ll_ecm_cache);
73 if (pthread_rwlock_init(&ecm_cache_lock,NULL) != 0)
74 { cs_log("Error creating lock ecm_cache_lock!"); }
75 else
76 { ecm_cache_init_done = 1; }
77 }
78#endif
79}
80
81static uint8_t time_sort(ECM_CACHE *a, ECM_CACHE *b)
82{
83 if (((int64_t)(a->upd_time.time) * 1000ull + (int64_t) a->upd_time.millitm) == ((int64_t)(b->upd_time.time) * 1000ull + (int64_t) b->upd_time.millitm)) return 0;
84 return (((int64_t)(a->upd_time.time) * 1000ull + (int64_t) a->upd_time.millitm) > ((int64_t)(b->upd_time.time) * 1000ull + (int64_t) b->upd_time.millitm)) ? -1 : 1;
85}
86
87static int compare_csp_hash_ecmcache(const void *arg, const void *obj)
88{
89 uint32_t h = ((const ECM_CACHE*)obj)->csp_hash;
90 return memcmp(arg, &h, 4);
91}
92
93void ecm_cache_cleanup(bool force)
94{
95 if(!ecm_cache_init_done)
96 { return; }
97
98 SAFE_RWLOCK_WRLOCK(&ecm_cache_lock);
99
100 ECM_CACHE *ecm_cache;
101 node *i, *i_next;
102 uint32_t ll_c = 0;
103 uint32_t ll_ten_percent = (uint)tommy_list_count(&ll_ecm_cache)*0.1; // 10 percent of cache
104
105 if(!force)
106 sort_list(&ll_ecm_cache, time_sort);
107
108 i = get_first_node_list(&ll_ecm_cache);
109 while(i)
110 {
111 i_next = i->next;
112
113 ecm_cache = get_data_from_node(i);
114
115 if(!ecm_cache)
116 {
117 i = i_next;
118 continue;
119 }
120 if(!force)
121 {
122 ++ll_c;
123
124 if(ll_c < ll_ten_percent)
125 {
126 remove_elem_list(&ll_ecm_cache, &ecm_cache->ll_node);
127 remove_elem_hash_table(&ht_ecm_cache, &ecm_cache->ht_node);
128 NULLFREE(ecm_cache);
129 }
130 else{
131 break;
132 }
133 }
134 else{
135 remove_elem_list(&ll_ecm_cache, &ecm_cache->ll_node);
136 remove_elem_hash_table(&ht_ecm_cache, &ecm_cache->ht_node);
137 NULLFREE(ecm_cache);
138 }
139 i = i_next;
140 }
141
142 SAFE_RWLOCK_UNLOCK(&ecm_cache_lock);
143}
144#endif
145
146void fallback_timeout(ECM_REQUEST *er)
147{
148 if(er->rc >= E_UNHANDLED && er->stage < 4)
149 {
150 cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} fallback timeout! (stage: %d)", (check_client(er->client) ? er->client->account->usr : "-"), er->caid, er->prid, er->srvid, er->stage);
151 debug_ecm(D_TRACE, "fallback for %s %s", username(er->client), buf);
152 while(er->stage < 4) // if preferlocalcards=1 and no answer from locals, initial stage will be 2! We need to reach stage=4 to call fallback's.
153 {
154 request_cw_from_readers(er, 0);
155 }
156 }
157}
158
159void ecm_timeout(ECM_REQUEST *er)
160{
161 if(!er->readers_timeout_check)
162 {
163 er->readers_timeout_check = 1;
164
165 if(check_client(er->client) && er->rc >= E_UNHANDLED)
166 {
167 debug_ecm(D_TRACE, "timeout for %s %s", username(er->client), buf);
168
169 // set timeout for readers not answering
170 struct s_ecm_answer *ea_list;
171 for(ea_list = er->matching_rdr; ea_list; ea_list = ea_list->next)
172 {
173 if((ea_list->status & (REQUEST_SENT | REQUEST_ANSWERED)) == REQUEST_SENT) // Request sent, but no answer!
174 {
175 write_ecm_answer(ea_list->reader, er, E_TIMEOUT, 0, NULL, NULL, 0, NULL); // set timeout for readers not answered!
176 }
177 }
178
179 // send timeout to client!
180 cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} client timeout! ", (check_client(er->client) ? er->client->account->usr : "-"), er->caid, er->prid, er->srvid);
181 er->rc = E_TIMEOUT;
182 er->rcEx = 0;
183 send_dcw(er->client, er);
184 }
185 }
186}
187
188void increment_n_request(struct s_client *cl)
189{
190 if(check_client(cl))
191 {
192 cl->n_request[1]++;
193 first_client->n_request[1]++;
194 }
195}
196
197uint8_t checkCWpart(uint8_t *cw, int8_t part)
198{
199 uint8_t eo = part ? 8 : 0;
200 int8_t i;
201 for(i = 0; i < 8; i++)
202 if(cw[i + eo]) { return 1; }
203 return 0;
204}
205
206void update_n_request(void)
207{
208 struct s_client *cl;
209
210 cs_readlock(__func__, &clientlist_lock);
211 for(cl = first_client->next; cl; cl = cl->next)
212 {
213#ifdef CS_CACHEEX
214 if(check_client(cl) && get_module(cl)->num != R_CSP && cl->typ == 'c' && !cl->dup && cl->account && cl->account->cacheex.mode<=1) //no cacheex 2/3 client
215#else
216 if(check_client(cl) && get_module(cl)->num != R_CSP && cl->typ == 'c' && !cl->dup)
217#endif
218 {
219 cl->n_request[0] = cl->n_request[1];
220 cl->n_request[1] = 0;
221 }
222 else
223 {
224 cl->n_request[0] = 0;
225 cl->n_request[1] = 0;
226 }
227 }
228
229 first_client->n_request[0] = first_client->n_request[1];
230 first_client->n_request[1] = 0;
231
232 cs_readunlock(__func__, &clientlist_lock);
233}
234
235static void *cw_process(void)
236{
237 set_thread_name(__func__);
238 int64_t time_to_check_fbtimeout, time_to_check_ctimeout, next_check, n_request_next;
239 struct timeb t_now, tbc, ecmc_time, cache_time, n_request_time;
240 ECM_REQUEST *er = NULL;
241 time_t ecm_maxcachetime;
242
243#ifdef CS_CACHEEX
244 int64_t time_to_check_cacheex_wait_time;
245 int64_t time_to_check_cacheex_mode1_delay;
246#endif
247
248 cs_pthread_cond_init(__func__, &cw_process_sleep_cond_mutex, &cw_process_sleep_cond);
249
250#ifdef CS_ANTICASC
251 int32_t ac_next;
252 struct timeb ac_time;
253 cs_ftime(&ac_time);
254 add_ms_to_timeb(&ac_time, cfg.ac_stime * 60 * 1000);
255#endif
256
257 cs_ftime(&ecmc_time);
258 add_ms_to_timeb(&ecmc_time, 1000);
259 cs_ftime(&cache_time);
260 add_ms_to_timeb(&cache_time, 3000);
261 cs_ftime(&n_request_time);
262 add_ms_to_timeb(&n_request_time, 60 * 1000);
263
264 while(!exit_oscam)
265 {
266 if(cw_process_wakeups == 0) // No waiting wakeups, proceed to sleep
267 {
268 sleepms_on_cond(__func__, &cw_process_sleep_cond_mutex, &cw_process_sleep_cond, msec_wait);
269 }
270 cw_process_wakeups = 0; // We've been woken up, reset the counter
271 if(exit_oscam)
272 { break; }
273
274 next_check = 0;
275#ifdef CS_ANTICASC
276 ac_next = 0;
277#endif
278 ecmc_next = 0;
279 cache_next = 0;
280 msec_wait = 0;
281
282 cs_ftime(&t_now);
283 cs_readlock(__func__, &ecmcache_lock);
284 for(er = ecmcwcache; er; er = er->next)
285 {
286
287 if((er->from_cacheex || er->from_csp) // ignore ecms from cacheex/csp
288 || er->readers_timeout_check // ignore already checked
289 || !check_client(er->client)) // ignore ecm of killed clients
290 {
291 continue;
292 }
293
294 if(er->rc >= E_UNHANDLED)
295 {
296#ifdef CS_CACHEEX
297 // cacheex_wait_time
298 if(er->cacheex_wait_time && !er->cacheex_wait_time_expired)
299 {
300 tbc = er->tps;
301 time_to_check_cacheex_mode1_delay = 0;
302 time_to_check_cacheex_wait_time = add_ms_to_timeb_diff(&tbc, lb_auto_timeout(er, er->cacheex_wait_time));
303
304 if(comp_timeb(&t_now, &tbc) >= 0)
305 {
306 add_job(er->client, ACTION_CACHEEX_TIMEOUT, (void *)er, 0);
307 time_to_check_cacheex_wait_time = 0;
308
309 }
310 else if(er->cacheex_mode1_delay && !er->stage && er->cacheex_reader_count>0)
311 {
312 // check for cacheex_mode1_delay
313 tbc = er->tps;
314 time_to_check_cacheex_mode1_delay = add_ms_to_timeb_diff(&tbc, lb_auto_timeout(er, er->cacheex_mode1_delay));
315
316 if(comp_timeb(&t_now, &tbc) >= 0)
317 {
318 add_job(er->client, ACTION_CACHEEX1_DELAY, (void *)er, 0);
319 time_to_check_cacheex_mode1_delay = 0;
320 }
321 }
322
323 if(!next_check || (time_to_check_cacheex_wait_time > 0 && time_to_check_cacheex_wait_time < next_check))
324 { next_check = time_to_check_cacheex_wait_time; }
325
326 if(!next_check || (time_to_check_cacheex_mode1_delay > 0 && time_to_check_cacheex_mode1_delay < next_check))
327 { next_check = time_to_check_cacheex_mode1_delay; }
328 }
329#endif
330 if(er->stage < 4)
331 {
332 // fbtimeout
333 tbc = er->tps;
334 time_to_check_fbtimeout = add_ms_to_timeb_diff(&tbc, lb_auto_timeout(er, get_fallbacktimeout(er->caid)));
335
336 if(comp_timeb(&t_now, &tbc) >= 0)
337 {
338 add_job(er->client, ACTION_FALLBACK_TIMEOUT, (void *)er, 0);
339 time_to_check_fbtimeout = 0;
340 }
341
342 if(!next_check || (time_to_check_fbtimeout > 0 && time_to_check_fbtimeout < next_check))
343 { next_check = time_to_check_fbtimeout; }
344 }
345 }
346
347 // clienttimeout
348 if(!er->readers_timeout_check) // ecm stays in cache at least ctimeout+2seconds!
349 {
350 tbc = er->tps;
351 time_to_check_ctimeout = add_ms_to_timeb_diff(&tbc, lb_auto_timeout(er, cfg.ctimeout));
352
353 if(comp_timeb(&t_now, &tbc) >= 0)
354 {
355 add_job(er->client, ACTION_CLIENT_TIMEOUT, (void *)er, 0);
356 time_to_check_ctimeout = 0;
357 }
358
359 if(!next_check || (time_to_check_ctimeout > 0 && time_to_check_ctimeout < next_check))
360 { next_check = time_to_check_ctimeout; }
361 }
362 }
363 cs_readunlock(__func__, &ecmcache_lock);
364#ifdef CS_ANTICASC
365 if(cfg.ac_enabled && (ac_next = comp_timeb(&ac_time, &t_now)) <= 10)
366 {
367 ac_do_stat();
368 cs_ftime(&ac_time);
369 ac_next = add_ms_to_timeb_diff(&ac_time, cfg.ac_stime * 60 * 1000);
370 }
371#endif
372 if((ecmc_next = comp_timeb(&ecmc_time, &t_now)) <= 10)
373 {
374 uint32_t count = 0;
375 struct ecm_request_t *ecm, *ecmt = NULL, *prv;
376
377 cs_readlock(__func__, &ecmcache_lock);
378 for(ecm = ecmcwcache, prv = NULL; ecm; prv = ecm, ecm = ecm->next, count++)
379 {
380 ecm_maxcachetime = t_now.time - ((cfg.ctimeout + 500) / 1000 + 3); // to be sure no more access er!
381
382 if(ecm->tps.time < ecm_maxcachetime)
383 {
384 cs_readunlock(__func__, &ecmcache_lock);
385 cs_writelock(__func__, &ecmcache_lock);
386 ecmt = ecm;
387 if(prv)
388 { prv->next = NULL; }
389 else
390 { ecmcwcache = NULL; }
391 cs_writeunlock(__func__, &ecmcache_lock);
392 break;
393 }
394 }
395 if(!ecmt)
396 { cs_readunlock(__func__, &ecmcache_lock); }
397 ecmcwcache_size = count;
398
399 while(ecmt)
400 {
401 ecm = ecmt->next;
402 free_ecm(ecmt);
403 ecmt = ecm;
404 }
405
406#ifdef CS_CACHEEX
407 ecmt=NULL;
408 cs_readlock(__func__, &ecm_pushed_deleted_lock);
409 for(ecm = ecm_pushed_deleted, prv = NULL; ecm; prv = ecm, ecm = ecm->next)
410 {
411 ecm_maxcachetime = t_now.time - ((cfg.ctimeout + 500) / 1000 + 3);
412 if(ecm->tps.time < ecm_maxcachetime)
413 {
414 cs_readunlock(__func__, &ecm_pushed_deleted_lock);
415 cs_writelock(__func__, &ecm_pushed_deleted_lock);
416 ecmt = ecm;
417 if(prv)
418 { prv->next = NULL; }
419 else
420 { ecm_pushed_deleted = NULL; }
421 cs_writeunlock(__func__, &ecm_pushed_deleted_lock);
422 break;
423 }
424 }
425 if(!ecmt)
426 { cs_readunlock(__func__, &ecm_pushed_deleted_lock); }
427
428 while(ecmt)
429 {
430 ecm = ecmt->next;
431 free_push_in_ecm(ecmt);
432 ecmt = ecm;
433 }
434#endif
435
436 cs_ftime(&ecmc_time);
437 ecmc_next = add_ms_to_timeb_diff(&ecmc_time, 1000);
438 }
439
440 if((cache_next = comp_timeb(&cache_time, &t_now)) <= 10)
441 {
442 cleanup_cache(false);
443 cacheex_cleanup_hitcache(false);
444
445 cs_ftime(&cache_time);
446 cache_next = add_ms_to_timeb_diff(&cache_time, 3000);
447 }
448
449 if((n_request_next = comp_timeb(&n_request_time, &t_now)) <= 10)
450 {
451 update_n_request();
452 cs_ftime(&n_request_time);
453 n_request_next = add_ms_to_timeb_diff(&n_request_time, 60 * 1000);
454 }
455
456 msec_wait = next_check;
457#ifdef CS_ANTICASC
458 if(!msec_wait || (ac_next > 0 && ac_next < msec_wait))
459 { msec_wait = ac_next; }
460#endif
461 if(!msec_wait || (ecmc_next > 0 && ecmc_next < msec_wait))
462 { msec_wait = ecmc_next; }
463
464 if(!msec_wait || (cache_next > 0 && cache_next < msec_wait))
465 { msec_wait = cache_next; }
466
467 if(!msec_wait || (n_request_next > 0 && n_request_next < msec_wait))
468 { msec_wait = n_request_next; }
469
470 if(!msec_wait)
471 { msec_wait = 3000; }
472
473 cleanupcwcycle();
474 }
475
476 return NULL;
477}
478
479void cw_process_thread_start(void)
480{
481 start_thread("cw_process", (void *) &cw_process, NULL, NULL, 1, 1);
482}
483
484void cw_process_thread_wakeup(void)
485{
486 cw_process_wakeups++; // Do not sleep...
487 SAFE_COND_SIGNAL(&cw_process_sleep_cond);
488}
489
490void convert_to_beta(struct s_client *cl, ECM_REQUEST *er, uint16_t caidto)
491{
492 static uint8_t headerN3[10] = { 0xc7, 0x00, 0x00, 0x00, 0x01, 0x10, 0x10, 0x00, 0x87, 0x12 };
493 static uint8_t headerN2[10] = { 0xc9, 0x00, 0x00, 0x00, 0x01, 0x10, 0x10, 0x00, 0x48, 0x12 };
494
495 er->ocaid = er->caid;
496 er->caid = caidto;
497 er->prid = 0;
498 er->ecmlen = er->ecm[2] + 3;
499
500 memmove(er->ecm + 13, er->ecm + 3, er->ecmlen - 3);
501
502 if(er->ecmlen > 0x88)
503 {
504 memcpy(er->ecm + 3, headerN3, 10);
505 if(er->ecm[0] == 0x81)
506 { er->ecm[12] += 1; }
507 er->ecm[1] = 0x70;
508 }
509 else
510 {
511 memcpy(er->ecm + 3, headerN2, 10);
512 }
513
514 er->ecmlen += 10;
515 er->ecm[2] = er->ecmlen - 3;
516 er->btun = 1;
517
518 cl->cwtun++;
519 cl->account->cwtun++;
520 first_client->cwtun++;
521
522 cs_log_dbg(D_TRACE, "ECM converted ocaid from 0x%04X to BetaCrypt caid 0x%04X for service id 0x%04X",
523 er->ocaid, caidto, er->srvid);
524}
525
526void convert_to_nagra(struct s_client *cl, ECM_REQUEST *er, uint16_t caidto)
527{
528 cs_log_dbg(D_TRACE, "convert_to_nagra");
529 er->ocaid = er->caid;
530 er->caid = caidto;
531 er->prid = 0;
532 er->ecmlen = er->ecm[2] + 3;
533
534 // not sure
535 if(er->ecmlen < 0x52)
536 { er->ecm[1] = 0x30; }
537
538 memmove(er->ecm + 3, er->ecm + 13, er->ecmlen - 3);
539
540 er->ecmlen -= 10;
541 er->ecm[2] = er->ecmlen - 3;
542 er->btun = 1;
543
544 cl->cwtun++;
545 cl->account->cwtun++;
546 first_client->cwtun++;
547
548 cs_log_dbg(D_TRACE, "ECM converted ocaid from: 0x%04X to Nagra: 0x04%X for service id:0x04%X",
549 er->ocaid, caidto, er->srvid);
550}
551
552void cs_betatunnel(ECM_REQUEST *er)
553{
554 int32_t i;
555 struct s_client *cl = cur_client();
556 uint32_t mask_all = 0xFFFF;
557 TUNTAB *ttab = &cl->ttab;
558
559 for(i = 0; i < ttab->ttnum; i++)
560 {
561 if((er->caid == ttab->ttdata[i].bt_caidfrom) && ((er->srvid == ttab->ttdata[i].bt_srvid) || (ttab->ttdata[i].bt_srvid) == mask_all))
562 {
563 if(chk_is_betatunnel_caid(er->caid) == 1 && er->ocaid == 0x0000)
564 {
565 convert_to_nagra(cl, er, ttab->ttdata[i].bt_caidto);
566 }
567 else if(er->ocaid == 0x0000)
568 {
569 convert_to_beta(cl, er, ttab->ttdata[i].bt_caidto);
570 }
571 return;
572 }
573 }
574}
575
576static void remove_ecm_from_reader(ECM_REQUEST *ecm)
577{
578 int32_t i;
579 struct s_ecm_answer *ea = ecm->matching_rdr;
580 while(ea)
581 {
582 if((ea->status & REQUEST_SENT) && !(ea->status & REQUEST_ANSWERED))
583 {
584 // we found a outstanding reader, clean it:
585 struct s_reader *rdr = ea->reader;
586 if(rdr)
587 {
588 struct s_client *cl = rdr->client;
589 if(check_client(cl))
590 {
591 ECM_REQUEST *ecmtask = cl->ecmtask;
592 if(ecmtask)
593 {
594 for(i = 0; i < cfg.max_pending; ++i)
595 {
596 if(ecmtask[i].parent == ecm)
597 {
598 ecmtask[i].client = NULL;
599 cacheex_set_csp_lastnode(&ecmtask[i]);
600 }
601 }
602 }
603 }
604 }
605 }
606 ea = ea->next;
607 }
608}
609
610void free_ecm(ECM_REQUEST *ecm)
611{
612 struct s_ecm_answer *ea, *nxt;
613 cacheex_free_csp_lastnodes(ecm);
614 gbox_free_cards_pending(ecm);
615 // remove this ecm from reader queue to avoid segfault on very late answers (when ecm is already disposed)
616 // first check for outstanding answers:
617 remove_ecm_from_reader(ecm);
618 // free matching_rdr list:
619 ea = ecm->matching_rdr;
620 ecm->matching_rdr = NULL;
621 while(ea)
622 {
623 nxt = ea->next;
624 cs_lock_destroy(__func__, &ea->ecmanswer_lock);
625 add_garbage(ea);
626 ea = nxt;
627 }
628 if(ecm->src_data)
629 { add_garbage(ecm->src_data); }
630 add_garbage(ecm);
631}
632
633
634void free_push_in_ecm(ECM_REQUEST *ecm)
635{
636 cacheex_free_csp_lastnodes(ecm);
637 gbox_free_cards_pending(ecm);
638 if(ecm->src_data)
639 { NULLFREE(ecm->src_data); }
640 NULLFREE(ecm);
641}
642
643ECM_REQUEST *get_ecmtask(void)
644{
645 ECM_REQUEST *er = NULL;
646 struct s_client *cl = cur_client();
647 if(!cl)
648 { return NULL; }
649 if(!cs_malloc(&er, sizeof(ECM_REQUEST)))
650 { return NULL; }
651 cs_ftime(&er->tps);
652 er->rc = E_UNHANDLED;
653 er->client = cl;
654 er->grp = 0; // no readers/cacheex-clients answers yet
655 //cs_log("client %s ECMTASK %d module %s", username(cl), n, get_module(cl)->desc);
656 return er;
657}
658
659void cleanup_ecmtasks(struct s_client *cl)
660{
661 if(!cl) { return; }
662
663 ECM_REQUEST *ecm;
664
665 // remove this clients ecm from queue. because of cache, just null the client:
666 cs_readlock(__func__, &ecmcache_lock);
667 for(ecm = ecmcwcache; ecm && cl; ecm = ecm->next)
668 {
669 if(ecm->client == cl)
670 {
671 ecm->client = NULL;
672 }
673 }
674 cs_readunlock(__func__, &ecmcache_lock);
675
676 // remove client from rdr ecm-queue:
677 cs_readlock(__func__, &readerlist_lock);
678 struct s_reader *rdr = first_active_reader;
679 while(rdr)
680 {
681 if(check_client(rdr->client) && rdr->client->ecmtask)
682 {
683 int i;
684 for(i = 0; (i < cfg.max_pending) && cl; i++)
685 {
686 ecm = &rdr->client->ecmtask[i];
687 if(ecm->client == cl)
688 {
689 ecm->client = NULL;
690 }
691 }
692 }
693 rdr = rdr->next;
694 }
695 cs_readunlock(__func__, &readerlist_lock);
696
697}
698
699static void add_cascade_data(struct s_client *client, ECM_REQUEST *er)
700{
701 if(!client->cascadeusers)
702 { client->cascadeusers = ll_create("cascade_data"); }
703 LLIST *l = client->cascadeusers;
704 LL_ITER it = ll_iter_create(l);
705 time_t now = time(NULL);
706 struct s_cascadeuser *cu;
707 int8_t found = 0;
708 while((cu = ll_iter_next(&it)))
709 {
710 if(er->caid == cu->caid && er->prid == cu->prid && er->srvid == cu->srvid) // found it
711 {
712 if(cu->time < now)
713 { cu->cwrate = now - cu->time; }
714 cu->time = now;
715 found = 1;
716 }
717 else if(cu->time + 60 < now) // old
718 { ll_iter_remove_data(&it); }
719 }
720
721 if(!found) // add it if not found
722 {
723 if(!cs_malloc(&cu, sizeof(struct s_cascadeuser)))
724 { return; }
725 cu->caid = er->caid;
726 cu->prid = er->prid;
727 cu->srvid = er->srvid;
728 cu->time = now;
729 ll_append(l, cu);
730 }
731}
732
733static int32_t is_double_check_caid(ECM_REQUEST *er, FTAB *double_check_caid)
734{
735 if(!double_check_caid->nfilts) { return 1; }
736
737 int32_t i, k;
738 for(i = 0; i < double_check_caid->nfilts; i++)
739 {
740 uint16_t tcaid = double_check_caid->filts[i].caid;
741 if(tcaid && (tcaid == er->caid || (tcaid < 0x0100 && (er->caid >> 8) == tcaid))) // caid match
742 {
743 int32_t nprids = double_check_caid->filts[i].nprids;
744 if(!nprids) // No Provider ->Ok
745 { return 1; }
746
747 for(k = 0; k < nprids; k++)
748 {
749 uint32_t prid = double_check_caid->filts[i].prids[k];
750 if(prid == er->prid) // Provider matches
751 { return 1; }
752 }
753 }
754 }
755
756 return 0;
757}
758
759struct s_ecm_answer *get_ecm_answer(struct s_reader *reader, ECM_REQUEST *er)
760{
761 if(!er || !reader) { return NULL; }
762
763 struct s_ecm_answer *ea;
764
765 for(ea = er->matching_rdr; ea; ea = ea->next)
766 {
767 if(ea->reader == reader)
768 {
769 return ea;
770 }
771 }
772 return NULL;
773}
774
775void distribute_ea(struct s_ecm_answer *ea)
776{
777 struct s_ecm_answer *ea_temp;
778
779 for(ea_temp = ea->pending; ea_temp; ea_temp = ea_temp->pending_next)
780 {
781 cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} [distribute_ea] send ea (%s) by reader %s answering for client %s", (check_client(ea_temp->er->client) ? ea_temp->er->client->account->usr : "-"), ea_temp->er->caid, ea_temp->er->prid, ea_temp->er->srvid, ea->rc==E_FOUND?"OK":"NOK", ea_temp->reader->label, (check_client(ea->er->client) ? ea->er->client->account->usr : "-"));
782#ifdef CS_CACHEEX_AIO
783 if(ea->rc==E_FOUND && ea->er->localgenerated)
784 ea_temp->er->localgenerated = 1;
785#endif
786 // e.g. we cannot send timeout, because "ea_temp->er->client" could wait/ask other readers! Simply set not_found if different from E_FOUND!
787 write_ecm_answer(ea_temp->reader, ea_temp->er, (ea->rc==E_FOUND? E_FOUND : E_NOTFOUND), ea->rcEx, ea->cw, NULL, ea->tier, &ea->cw_ex);
788 }
789}
790
791int32_t send_dcw(struct s_client *client, ECM_REQUEST *er)
792{
793 if(!check_client(client) || client->typ != 'c')
794 { return 0; }
795
796 cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} [send_dcw] rc %d from reader %s", (check_client(er->client) ? er->client->account->usr : "-"), er->caid, er->prid, er->srvid, er->rc, er->selected_reader ? er->selected_reader->label : "-");
797
798 static const char stageTxt[] = { '0', 'C', 'L', 'P', 'F', 'X' };
799 static const char *stxt[] = { "found", "cache1", "cache2", "cache3", "not found", "timeout", "sleeping",
800 "fake", "invalid", "corrupt", "no card", "expdate", "disabled", "stopped" };
801
802 static const char *stxtEx[16] = {"", "group", "caid", "ident", "class", "chid", "queue", "peer", "sid", "", "", "", "", "", "", ""};
803 static const char *stxtWh[16] = {"", "user ", "reader ", "server ", "lserver ", "", "", "", "", "", "", "", "" , "" , "", ""};
804#ifdef CS_CACHEEX_AIO
805 char sby[100] = "", sreason[35] = "", scwcinfo[32] = "", schaninfo[CS_SERVICENAME_SIZE] = "", srealecmtime[50]="";
806#else
807 char sby[100] = "", sreason[32] = "", scwcinfo[32] = "", schaninfo[CS_SERVICENAME_SIZE] = "", srealecmtime[50]="";
808#endif
809 char erEx[32] = "";
810 char usrname[38] = "";
811 char channame[28];
812 struct timeb tpe;
813
814 snprintf(usrname, sizeof(usrname) - 1, "%s", username(client));
815
816#ifdef WITH_DEBUG
817 if(cs_dblevel & D_CLIENTECM)
818 {
819 char buf[ECM_FMT_LEN];
820 char ecmd5[17 * 3];
821 char cwstr[17 * 3];
822 format_ecm(er, buf, ECM_FMT_LEN);
823 cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5));
824 cs_hexdump(0, er->cw, 16, cwstr, sizeof(cwstr));
825#ifdef CS_CACHEEX
826 char csphash[5 * 3];
827 cs_hexdump(0, (void *)&er->csp_hash, 4, csphash, sizeof(csphash));
828 cs_log_dbg(D_CLIENTECM, "Client %s csphash %s cw %s rc %d %s", username(client), csphash, cwstr, er->rc, buf);
829#else
830 cs_log_dbg(D_CLIENTECM, "Client %s cw %s rc %d %s", username(client), cwstr, er->rc, buf);
831#endif
832 }
833#endif
834
835 struct s_reader *er_reader = er->selected_reader; // responding reader
836 struct s_ecm_answer *ea_orig = get_ecm_answer(er_reader, er);
837
838
839 // check if ecm_answer from pending's
840 if(ea_orig && ea_orig->is_pending && er->rc == E_FOUND)
841 { er->rc = E_CACHE2; }
842
843
844 // check if answer from cacheex-1 reader
845 if(er->rc == E_FOUND && er_reader && cacheex_reader(er_reader)) // so add hit to cacheex mode 1 readers
846 {
847 er->rc = E_CACHEEX;
848 }
849
850 // real ecm time
851 if(ea_orig && !ea_orig->is_pending && er->rc == E_FOUND
852 && (
853#ifdef CS_CACHEEX
854 er->cacheex_wait_time ||
855#endif
856 (ea_orig->status & READER_FALLBACK)))
857 {
858 snprintf(srealecmtime, sizeof(srealecmtime) - 1, " (real %d ms)", ea_orig->ecm_time);
859 }
860
861
862 if(er->rc == E_TIMEOUT)
863 {
864#ifdef CS_CACHEEX
865 if(!er->from_cacheex1_client) // cosmetic: show "by" readers only for "normal" clients
866 {
867#endif
868 struct s_ecm_answer *ea_list;
869 int32_t ofs = 0;
870
871 for(ea_list = er->matching_rdr; ea_list; ea_list = ea_list->next)
872 {
873 if(ea_list->reader && ofs < (int32_t)sizeof(sby) && ((ea_list->status & REQUEST_SENT) && (ea_list->rc == E_TIMEOUT || ea_list->rc >= E_99))) //Request send, but no cw answered!
874 {
875 ofs += snprintf(sby + ofs, sizeof(sby) - ofs - 1, "%s%s", ofs ? "," : " by ", ea_list->reader->label);
876 }
877 }
878
879 if(er->ocaid && ofs < (int32_t)sizeof(sby))
880 { snprintf(sby + ofs, sizeof(sby) - ofs - 1, "(btun %04X)", er->ocaid); }
881
882#ifdef CS_CACHEEX
883 }
884#endif
885 }
886 else if(er_reader)
887 {
888 // add marker to reader if ECM_REQUEST was betatunneled
889 if(er->ocaid)
890 { snprintf(sby, sizeof(sby) - 1, " by %s(btun %04X)", er_reader->label, er->ocaid); }
891 else
892 { snprintf(sby, sizeof(sby) - 1, " by %s", er_reader->label); }
893 }
894#ifdef CS_CACHEEX
895 else if(er->cacheex_src) // only for cacheex mode-3 clients (no mode-1 or mode-2 because reader is set!) and csp
896 {
897 char *cex_name = "-";
898 if(check_client(er->cacheex_src) && er->cacheex_src->account)
899 {
900 if(er->cacheex_src->account->usr[0] != '\0')
901 cex_name = er->cacheex_src->account->usr;
902 else
903 cex_name = "csp";
904 }
905
906 if(er->ocaid)
907 {
908 snprintf(sby, sizeof(sby) - 1, " by %s(btun %04X)", cex_name, er->ocaid);
909 }
910 else
911 {
912 snprintf(sby, sizeof(sby) - 1, " by %s", cex_name);
913 }
914 }
915#endif
916
917 if(er->rc < E_NOTFOUND)
918 {
919 er->rcEx = 0;
920 memset(er->msglog, 0, MSGLOGSIZE); // remove reader msglog from previous requests that failed, founds never give back msglog!
921 }
922
923 if(er->rcEx)
924 { snprintf(erEx, sizeof(erEx) - 1, "rejected %s%s", stxtWh[er->rcEx >> 4], stxtEx[er->rcEx & 0xf]); }
925
926 get_servicename_or_null(client, er->srvid, er->prid, er->caid, channame, sizeof(channame));
927 if(!channame[0])
928 {
929 schaninfo[0] = '\0';
930 }
931 else
932 {
933 snprintf(schaninfo, sizeof(schaninfo) - 1, " - %s", channame);
934 }
935
936 if(er->msglog[0])
937 { snprintf(sreason, sizeof(sreason) - 1, " (%.26s)", er->msglog); }
938#ifdef CW_CYCLE_CHECK
939 if(er->cwc_msg_log[0])
940 { snprintf(scwcinfo, sizeof(scwcinfo) - 1, " (%.26s)", er->cwc_msg_log); }
941#endif
942
943 cs_ftime(&tpe);
944
945#ifdef CS_CACHEEX
946 int cx = 0;
947 if(er->rc >= E_CACHEEX && er->cacheex_wait_time && er->cacheex_wait_time_expired)
948 {
949 cx = snprintf ( sreason, sizeof sreason, " (wait_time over)");
950 }
951
952 if(er->cw_count>1)
953 {
954#ifdef CS_CACHEEX_AIO
955 if(er->cw_count > 0x0F000000 || er->localgenerated)
956 {
957 uint32_t cw_count_cleaned = er->cw_count ^ 0x0F000000;
958 if(cw_count_cleaned > 1)
959 snprintf(sreason+cx, (sizeof sreason)-cx, " (cw count %d) (lg)", cw_count_cleaned);
960 else
961 snprintf(sreason+cx, (sizeof sreason)-cx, " (lg)");
962 }
963 else
964 {
965#endif
966
967 snprintf (sreason+cx, (sizeof sreason)-cx, " (cw count %d)", er->cw_count);
968
969#ifdef CS_CACHEEX_AIO
970 }
971
972 }
973 else
974 {
975 if(er->localgenerated)
976 snprintf(sreason+cx, (sizeof sreason)-cx, " (lg)");
977#endif
978 }
979
980#endif
981
982 client->cwlastresptime = comp_timeb(&tpe, &er->tps);
983
984 time_t now = time(NULL);
985 webif_client_add_lastresponsetime(client, client->cwlastresptime, now, er->rc); // add to ringbuffer
986
987 if(er_reader)
988 {
989 struct s_client *er_cl = er_reader->client;
990 if(check_client(er_cl))
991 {
992 er_cl->cwlastresptime = client->cwlastresptime;
993 webif_client_add_lastresponsetime(er_cl, client->cwlastresptime, now, er->rc);
994 er_cl->last_providptr = client->last_providptr;
995 er_cl->last_srvidptr = client->last_srvidptr;
996 }
997 }
998
999 webif_client_init_lastreader(client, er, er_reader, stxt);
1000
1001 client->last = now;
1002
1003 //cs_log_dbg(D_TRACE, "CHECK rc=%d er->cacheex_src=%s", er->rc, username(er->cacheex_src));
1004 switch(er->rc)
1005 {
1006 case E_FOUND:
1007 {
1008 client->cwfound++;
1009 client->account->cwfound++;
1010 first_client->cwfound++;
1011 break;
1012 }
1013 case E_CACHE1:
1014 case E_CACHE2:
1015 case E_CACHEEX:
1016 {
1017 client->cwcache++;
1018 client->account->cwcache++;
1019 first_client->cwcache++;
1020#ifdef CS_CACHEEX
1021 if(check_client(er->cacheex_src))
1022 {
1023 first_client->cwcacheexhit++;
1024 er->cacheex_src->cwcacheexhit++;
1025 if(er->cacheex_src->account)
1026 { er->cacheex_src->account->cwcacheexhit++; }
1027 }
1028#endif
1029 break;
1030 }
1031 case E_NOTFOUND:
1032 case E_CORRUPT:
1033 case E_NOCARD:
1034 {
1035 if(er->rcEx)
1036 {
1037 client->cwignored++;
1038 client->account->cwignored++;
1039 first_client->cwignored++;
1040 }
1041 else
1042 {
1043 client->cwnot++;
1044 client->account->cwnot++;
1045 first_client->cwnot++;
1046 }
1047 break;
1048 }
1049 case E_TIMEOUT:
1050 {
1051 client->cwtout++;
1052 client->account->cwtout++;
1053 first_client->cwtout++;
1054 break;
1055 }
1056 default:
1057 {
1058 client->cwignored++;
1059 client->account->cwignored++;
1060 first_client->cwignored++;
1061 }
1062 }
1063
1064#ifdef CS_ANTICASC
1065// [zaplist] ACoSC anticascading
1066 if(cfg.acosc_enabled)
1067 {
1068 int8_t max_active_sids = 0;
1069 int8_t zap_limit = 0;
1070 int8_t penalty = 0;
1071 int32_t penalty_duration = 0;
1072 int32_t delay = 0;
1073 int8_t max_ecms_per_minute = 0;
1074 char *info1 = NULL;
1075 char *info2 = NULL;
1076 char *info3 = NULL;
1077 char *info4 = NULL;
1078 char *info5 = NULL;
1079 char *info6 = NULL;
1080
1081 // **global or user value?
1082 cs_writelock(__func__, &clientlist_lock);
1083
1084 max_active_sids = client->account->acosc_max_active_sids == -1 ? cfg.acosc_max_active_sids : client->account->acosc_max_active_sids;
1085 info1 = client->account->acosc_max_active_sids == -1 ? "Globalvalue" : "Uservalue";
1086
1087 zap_limit = client->account->acosc_zap_limit == -1 ? cfg.acosc_zap_limit : client->account->acosc_zap_limit;
1088 info5 = client->account->acosc_zap_limit == -1 ? "Globalvalue" : "Uservalue";
1089
1090 penalty = client->account->acosc_penalty == -1 ? cfg.acosc_penalty : client->account->acosc_penalty;
1091 info2 = client->account->acosc_penalty == -1 ? "Globalvalue" : "Uservalue";
1092
1093 penalty_duration = client->account->acosc_penalty_duration == -1 ? cfg.acosc_penalty_duration : client->account->acosc_penalty_duration;
1094 info3 = client->account->acosc_penalty_duration == -1 ? "Globalvalue" : "Uservalue";
1095
1096 delay = client->account->acosc_delay == -1 ? cfg.acosc_delay : client->account->acosc_delay;
1097 info4 = client->account->acosc_delay == -1 ? "Globalvalue" : "Uservalue";
1098
1099 max_ecms_per_minute = client->account->acosc_max_ecms_per_minute == -1 ? cfg.acosc_max_ecms_per_minute : client->account->acosc_max_ecms_per_minute;
1100 info6 = client->account->acosc_max_ecms_per_minute == -1 ? "Globalvalue" : "Uservalue";
1101
1102 //**
1103
1104 if((er->rc < E_NOTFOUND && max_active_sids > 0) || zap_limit > 0 || max_ecms_per_minute > 0)
1105 {
1106 int8_t k = 0;
1107 int8_t active_sid_count = 0;
1108 time_t zaptime = time(NULL);
1109
1110 if(client->account->acosc_penalty_active == 4 && client->account->acosc_penalty_until <= zaptime) // reset penalty_active
1111 {
1112 client->account->acosc_penalty_active = 0;
1113 client->account->acosc_penalty_until = 0;
1114 }
1115
1116 if(client->account->acosc_penalty_active == 0 && max_active_sids > 0)
1117 {
1118 for(k=0; k<15 ; k++)
1119 {
1120 if(zaptime-30 < client->client_zap_list[k].lasttime && client->client_zap_list[k].request_stage == 10)
1121 {
1122 cs_log_dbg(D_TRACE, "[zaplist] ACoSC for Client: %s more then 10 ECM's for %04X@%06X/%04X/%04X", username(client), client->client_zap_list[k].caid, client->client_zap_list[k].provid, client->client_zap_list[k].chid, client->client_zap_list[k].sid);
1123 active_sid_count ++;
1124 }
1125 }
1126 cs_log_dbg(D_TRACE, "[zaplist] ACoSC for Client: %s active_sid_count= %i with more than 10 followed ECM's (mas:%i (%s))", username(client), active_sid_count, max_active_sids, info1);
1127 }
1128
1129 if(client->account->acosc_penalty_active == 0 && max_active_sids > 0 && active_sid_count > max_active_sids) //max_active_sids reached
1130 {
1131 client->account->acosc_penalty_active = 1;
1132 client->account->acosc_penalty_until = zaptime + penalty_duration;
1133 }
1134
1135 if(client->account->acosc_penalty_active == 0 && zap_limit > 0 && client->account->acosc_user_zap_count > zap_limit) // zap_limit reached
1136 {
1137 client->account->acosc_penalty_active = 2;
1138 client->account->acosc_penalty_until = zaptime + penalty_duration;
1139 }
1140
1141 if(client->account->acosc_penalty_active == 0 && max_ecms_per_minute > 0 && client->n_request[1] >= max_ecms_per_minute && penalty != 4) // max ecms per minute reached
1142 {
1143 client->account->acosc_penalty_active = 3;
1144 client->account->acosc_penalty_until = zaptime + penalty_duration;
1145 }
1146
1147 if(client->account->acosc_penalty_active == 0 && max_ecms_per_minute > 0 && client->n_request[1] > 0 && penalty == 4) // max ecms per minute with hidecards penalty
1148 {
1149 client->account->acosc_penalty_active = 3;
1150 client->account->acosc_penalty_until = zaptime + penalty_duration;
1151 }
1152
1153 if(client->account->acosc_penalty_active > 0)
1154 {
1155 if(client->account->acosc_penalty_active == 4)
1156 { cs_log_dbg(D_TRACE, "[zaplist] ACoSC for Client: %s penalty_duration: %ld seconds left(%s)", username(client), client->account->acosc_penalty_until - zaptime, info3); }
1157
1158 int16_t lt = get_module(client)->listenertype;
1159 switch(penalty)
1160 {
1161 case 1: // NULL CW
1162 er->rc = E_FAKE; // E_FAKE give only a status fake not a NULL cw
1163 er->rcEx = E2_WRONG_CHKSUM;
1164 if(client->account->acosc_penalty_active == 1)
1165 { cs_log("[zaplist] ACoSC for Client: %s max_activ_sids reached: %i:%i(%s) penalty: 1(%s) send null CW", username(client), active_sid_count, max_active_sids, info1, info2); }
1166 if(client->account->acosc_penalty_active == 2)
1167 { cs_log("[zaplist] ACoSC for Client: %s zap_limit reached: %i:%i(%s) penalty: 1(%s) send null CW", username(client), client->account->acosc_user_zap_count, zap_limit, info5, info2); }
1168 if(client->account->acosc_penalty_active == 3)
1169 { cs_log("[maxecms] ACoSC for Client: %s max_ecms_per_minute reached: ecms_last_minute=%i ecms_now=%i max=%i(%s) penalty: 1(%s) send null CW", username(client), client->n_request[0], client->n_request[1], max_ecms_per_minute, info6, info2); }
1170 break;
1171
1172 case 2: // ban
1173 if(lt != LIS_DVBAPI)
1174 {
1175 if(client->account->acosc_penalty_active == 1)
1176 { cs_log("[zaplist] ACoSC for Client: %s max_activ_sids reached: %i:%i(%s) penalty: 2(%s) BAN Client - Kill and set Client to failban list for %i sec.", username(client), active_sid_count, max_active_sids, info1, info2, penalty_duration); }
1177 if(client->account->acosc_penalty_active == 2)
1178 { cs_log("[zaplist] ACoSC for Client: %s zap_limit reached: %i:%i(%s) penalty: 2(%s) BAN Client - Kill and set Client to failban list for %i sec.", username(client), client->account->acosc_user_zap_count, zap_limit, info5, info2, penalty_duration); }
1179 if(client->account->acosc_penalty_active == 3)
1180 { cs_log("[maxecms] ACoSC for Client: %s max_ecms_per_minute reached: ecms_last_minute=%i ecms_now=%i max=%i(%s) penalty: 2(%s) BAN Client - Kill and set Client to failban list for %i sec.", username(client), client->n_request[0], client->n_request[1], max_ecms_per_minute, info6, info2, penalty_duration); }
1181 cs_add_violation_acosc(client, client->account->usr, penalty_duration);
1182 add_job(client, ACTION_CLIENT_KILL, NULL, 0);
1183 }
1184 else
1185 {
1186 cs_log("[zaplist] ACoSC for Client: %s %i:%i(%s) penalty: 2(%s) BAN Client - don't Ban dvbapi user only stop decoding", username(client), active_sid_count, max_active_sids, info1, info2);
1187 }
1188 er->rc = E_DISABLED;
1189 break;
1190
1191 case 3: // delay
1192 if(client->account->acosc_penalty_active == 1)
1193 { cs_log("[zaplist] ACoSC for Client: %s max_activ_sids reached: %i:%i(%s) penalty: 3(%s) delay CW: %ims(%s)", username(client), active_sid_count, max_active_sids, info1, info2, delay, info4); }
1194 if(client->account->acosc_penalty_active == 2)
1195 { cs_log("[zaplist] ACoSC for Client: %s zap_limit reached: %i:%i(%s) penalty: 3(%s) delay CW: %ims(%s)", username(client), client->account->acosc_user_zap_count, zap_limit, info5, info2, delay, info4); }
1196 if(client->account->acosc_penalty_active == 3)
1197 { cs_log("[maxecms] ACoSC for Client: %s max_ecms_per_minute reached: ecms_last_minute=%i ecms_now=%i max=%i(%s) penalty: 3(%s) delay CW: %ims(%s)", username(client), client->n_request[0], client->n_request[1], max_ecms_per_minute, info6, info2, delay, info4); }
1198 cs_writeunlock(__func__, &clientlist_lock);
1199 cs_sleepms(delay);
1200 cs_writelock(__func__, &clientlist_lock);
1201 client->cwlastresptime += delay;
1202 snprintf(sreason, sizeof(sreason)-1, " (%d ms penalty delay)", delay);
1203 break;
1204 case 4: // hidecards
1205 if(client->account->acosc_penalty_active == 3)
1206 {
1207 cs_log("[maxecms] ACoSC for Client: %s ecms_last_minute=%i ecms_now=%i max=%i(%s) penalty: 4(%s) hidecards - hidecards to the client for %i sec", username(client), client->n_request[0], client->n_request[1], max_ecms_per_minute, info6, info2, penalty_duration);
1208 client->start_hidecards = 1;
1209 }
1210 break;
1211 default: // logging
1212 if(client->account->acosc_penalty_active == 1)
1213 { cs_log("[zaplist] ACoSC for Client: %s max_activ_sids reached: %i:%i(%s) penalty: 0(%s) only logging", username(client), active_sid_count, max_active_sids, info1, info2); }
1214 if(client->account->acosc_penalty_active == 2)
1215 { cs_log("[zaplist] ACoSC for Client: %s zap_limit reached: %i:%i(%s) penalty: 0(%s) only logging", username(client), client->account->acosc_user_zap_count, zap_limit, info5, info2); }
1216 if(client->account->acosc_penalty_active == 3)
1217 { cs_log("[maxecms] ACoSC for Client: %s max_ecms_per_minute reached: ecms_last_minute=%i ecms_now=%i max=%i(%s) penalty: 0(%s) only logging", username(client), client->n_request[0], client->n_request[1], max_ecms_per_minute, info6, info2); }
1218 break;
1219 }
1220 client->account->acosc_user_zap_count = 0; // we got already a penalty
1221 client->account->acosc_penalty_active = 3;
1222 client->account->acosc_penalty_active = 4;
1223 }
1224 }
1225 cs_writeunlock(__func__, &clientlist_lock);
1226 }
1227#endif
1228
1229 if(cfg.double_check && er->rc <= E_CACHE2 && er->selected_reader && is_double_check_caid(er, &cfg.double_check_caid))
1230 {
1231 if(er->checked == 0) // First CW, save it and wait for next one
1232 {
1233 er->checked = 1;
1234 er->origin_reader = er->selected_reader;
1235 memcpy(er->cw_checked, er->cw, sizeof(er->cw));
1236 cs_log("DOUBLE CHECK FIRST CW by %s idx %d cpti %d", er->origin_reader->label, er->idx, er->msgid);
1237 }
1238 else if(er->origin_reader != er->selected_reader) // Second (or third and so on) cw. We have to compare
1239 {
1240 if(memcmp(er->cw_checked, er->cw, sizeof(er->cw)) == 0)
1241 {
1242 er->checked++;
1243 cs_log("DOUBLE CHECKED! %d. CW by %s idx %d cpti %d", er->checked, er->selected_reader->label, er->idx, er->msgid);
1244 }
1245 else
1246 {
1247 cs_log("DOUBLE CHECKED NONMATCHING! %d. CW by %s idx %d cpti %d", er->checked, er->selected_reader->label, er->idx, er->msgid);
1248 }
1249 }
1250 if(er->checked < 2) // less as two same cw? mark as pending!
1251 {
1252 er->rc = E_UNHANDLED;
1253 goto ESC;
1254 }
1255 }
1256
1257 ac_chk(client, er, 1);
1258 int32_t is_fake = 0;
1259 if(er->rc == E_FAKE)
1260 {
1261 is_fake = 1;
1262 er->rc = E_FOUND;
1263 }
1264
1265 get_module(client)->send_dcw(client, er);
1266
1267 add_cascade_data(client, er);
1268
1269 if(is_fake)
1270 { er->rc = E_FAKE; }
1271
1272#ifdef CS_ANTICASC
1273 cs_writelock(__func__, &clientlist_lock);
1274 if(client->start_hidecards)
1275 {
1276 client->start_hidecards = 0;
1277 add_job(client, ACTION_CLIENT_HIDECARDS, NULL, 0);
1278 }
1279 cs_writeunlock(__func__, &clientlist_lock);
1280#endif
1281
1282 if(!(er->rc == E_SLEEPING && client->cwlastresptime == 0))
1283 {
1284 char buf[ECM_FMT_LEN];
1285 format_ecm(er, buf, ECM_FMT_LEN);
1286 if(er->reader_avail == 1 || er->stage == 0)
1287 {
1288 cs_log("%s (%s): %s (%d ms)%s%s%s%s", usrname, buf, er->rcEx ? erEx : stxt[er->rc],
1289 client->cwlastresptime, sby, schaninfo, sreason, scwcinfo);
1290 }
1291 else
1292 {
1293 cs_log("%s (%s): %s (%d ms)%s (%c/%d/%d/%d)%s%s%s%s", usrname, buf, er->rcEx ? erEx : stxt[er->rc],
1294 client->cwlastresptime, sby, stageTxt[er->stage], er->reader_requested,
1295 (er->reader_count + er->fallback_reader_count), er->reader_avail, schaninfo,
1296 srealecmtime, sreason, scwcinfo);
1297 }
1298 }
1299
1300 cs_log_dump_dbg(D_ATR, er->cw, 16, "cw:");
1301 led_status_cw_not_found(er);
1302
1303ESC:
1304
1305 return 0;
1306}
1307
1308/*
1309 * write_ecm_request():
1310 */
1311static int32_t write_ecm_request(struct s_reader *rdr, ECM_REQUEST *er)
1312{
1313 add_job(rdr->client, ACTION_READER_ECM_REQUEST, (void *)er, 0);
1314 return 1;
1315}
1316
1317/**
1318 * sends the ecm request to the readers
1319 * ECM_REQUEST er : the ecm
1320 * er->stage: 0 = no reader asked yet
1321 * 2 = ask only local reader (skipped without preferlocalcards)
1322 * 3 = ask any non fallback reader
1323 * 4 = ask fallback reader
1324 **/
1325void request_cw_from_readers(ECM_REQUEST *er, uint8_t stop_stage)
1326{
1327 struct s_ecm_answer *ea;
1328 int8_t sent = 0;
1329
1330 if(er->stage >= 4) { return; }
1331
1332 while(1)
1333 {
1334 if(stop_stage && er->stage >= stop_stage) { return; }
1335
1336 er->stage++;
1337
1338#ifdef CS_CACHEEX
1339 if(er->stage == 1 && er->preferlocalcards==2)
1340 { er->stage++; }
1341#else
1342 if(er->stage == 1)
1343 { er->stage++; }
1344#endif
1345
1346 if(er->stage == 2 && !er->preferlocalcards)
1347 { er->stage++; }
1348
1349 for(ea = er->matching_rdr; ea; ea = ea->next)
1350 {
1351 switch(er->stage)
1352 {
1353#ifdef CS_CACHEEX
1354 case 1:
1355 {
1356 // Cache-Exchange
1357 if((ea->status & REQUEST_SENT) ||
1358 (ea->status & (READER_CACHEEX | READER_ACTIVE)) != (READER_CACHEEX | READER_ACTIVE))
1359 { continue; }
1360 break;
1361 }
1362#endif
1363 case 2:
1364 {
1365 // only local reader
1366 if((ea->status & REQUEST_SENT) ||
1367 (ea->status & (READER_ACTIVE | READER_FALLBACK | READER_LOCAL)) != (READER_ACTIVE | READER_LOCAL))
1368 { continue; }
1369 break;
1370 }
1371 case 3:
1372 {
1373 // any non fallback reader not asked yet
1374 if((ea->status & REQUEST_SENT) ||
1375 (ea->status & (READER_ACTIVE | READER_FALLBACK)) != READER_ACTIVE)
1376 { continue; }
1377 break;
1378 }
1379 default:
1380 {
1381 // only fallbacks
1382 if((ea->status & REQUEST_SENT) ||
1383 (ea->status & (READER_ACTIVE | READER_FALLBACK)) != (READER_ACTIVE | READER_FALLBACK))
1384 { continue; }
1385 break;
1386 }
1387 }
1388
1389 struct s_reader *rdr = ea->reader;
1390#ifdef WITH_DEBUG
1391 if (cs_dblevel & (D_TRACE | D_CSP))
1392 {
1393 char ecmd5[17 * 3];
1394 cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5));
1395 cs_log_dbg(D_TRACE | D_CSP, "request_cw stage=%d to reader %s ecm hash=%s", er->stage, rdr ? rdr->label : "", ecmd5);
1396 }
1397#endif
1398 ea->status |= REQUEST_SENT;
1399 cs_ftime(&ea->time_request_sent);
1400
1401 er->reader_requested++;
1402
1403 write_ecm_request(ea->reader, er);
1404
1405 // set sent=1 only if reader is active/connected. If not, switch to next stage!
1406 if(!sent && rdr)
1407 {
1408 struct s_client *rcl = rdr->client;
1409 if(check_client(rcl))
1410 {
1411 if(rcl->typ == 'r' && rdr->card_status == CARD_INSERTED)
1412 { sent = 1; }
1413 else if(rcl->typ == 'p' && (rdr->card_status == CARD_INSERTED || rdr->tcp_connected))
1414 { sent = 1; }
1415 }
1416 }
1417
1418 cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} [write_ecm_request] reader %s --> SENT %d", (check_client(er->client) ? er->client->account->usr : "-"), er->caid, er->prid, er->srvid, rdr ? ea->reader->label : "-", sent);
1419 }
1420
1421 if(sent || er->stage >= 4)
1422 { break; }
1423 }
1424}
1425
1426void add_cache_from_reader(ECM_REQUEST *er, struct s_reader *rdr, uint32_t csp_hash, uint8_t *ecmd5, uint8_t *cw, int16_t caid, int32_t prid, int16_t srvid
1427#ifdef CS_CACHEEX_AIO
1428 , int32_t ecm_time
1429#endif
1430)
1431{
1432 ECM_REQUEST *ecm;
1433 if (cs_malloc(&ecm, sizeof(ECM_REQUEST)))
1434 {
1435 cs_ftime(&ecm->tps);
1436
1437 ecm->cwc_cycletime = er->cwc_cycletime;
1438 ecm->cwc_next_cw_cycle = er->cwc_next_cw_cycle;
1439 memcpy(ecm->ecm, er->ecm, sizeof(ecm->ecm)); // ecm[0] is pushed to cacheexclients so we need a copy from it
1440 ecm->caid = caid;
1441 ecm->prid = prid;
1442 ecm->srvid = srvid;
1443 memcpy(ecm->ecmd5, ecmd5, CS_ECMSTORESIZE);
1444 ecm->csp_hash = csp_hash;
1445 ecm->rc = E_FOUND;
1446 memcpy(ecm->cw, cw, sizeof(ecm->cw));
1447 ecm->grp = rdr->grp;
1448 ecm->selected_reader = rdr;
1449#ifdef CS_CACHEEX_AIO
1450 ecm->ecm_time = ecm_time;
1451 ecm->localgenerated = er->localgenerated;
1452#endif
1453#ifdef CS_CACHEEX
1454 if(rdr && cacheex_reader(rdr))
1455 { ecm->cacheex_src = rdr->client; } //so adds hits to reader
1456#endif
1457
1458 add_cache(ecm); //add cw to cache
1459
1460#ifdef CS_CACHEEX
1461 cs_writelock(__func__, &ecm_pushed_deleted_lock);
1462 ecm->next = ecm_pushed_deleted;
1463 ecm_pushed_deleted = ecm;
1464 cs_writeunlock(__func__, &ecm_pushed_deleted_lock);
1465#else
1466 NULLFREE(ecm);
1467#endif
1468 }
1469}
1470
1471void chk_dcw(struct s_ecm_answer *ea)
1472{
1473 if(!ea || !ea->er)
1474 { return; }
1475
1476 ECM_REQUEST *ert = ea->er;
1477 struct s_ecm_answer *ea_list;
1478 struct s_reader *eardr = ea->reader;
1479 if(!ert || !eardr)
1480 { return; }
1481
1482 // ecm request already answered!
1483 if(ert->rc < E_99)
1484 {
1485#ifdef CS_CACHEEX
1486 if(ea && ert->rc < E_NOTFOUND && ea->rc < E_NOTFOUND && memcmp(ea->cw, ert->cw, sizeof(ert->cw)) != 0)
1487 {
1488 char cw1[16 * 3 + 2], cw2[16 * 3 + 2];
1489#ifdef WITH_DEBUG
1490 if(cs_dblevel & D_TRACE)
1491 {
1492 cs_hexdump(0, ea->cw, 16, cw1, sizeof(cw1));
1493 cs_hexdump(0, ert->cw, 16, cw2, sizeof(cw2));
1494 }
1495#endif
1496 char ip1[20] = "", ip2[20] = "";
1497 if(ea->reader && check_client(ea->reader->client)) { cs_strncpy(ip1, cs_inet_ntoa(ea->reader->client->ip), sizeof(ip1)); }
1498 if(ert->cacheex_src) { cs_strncpy(ip2, cs_inet_ntoa(ert->cacheex_src->ip), sizeof(ip2)); }
1499 else if(ert->selected_reader && check_client(ert->selected_reader->client)) { cs_strncpy(ip2, cs_inet_ntoa(ert->selected_reader->client->ip), sizeof(ip2)); }
1500
1501 ECM_REQUEST *er = ert;
1502 debug_ecm(D_TRACE, "WARNING2: Different CWs %s from %s(%s)<>%s(%s): %s<>%s", buf,
1503 username(ea->reader ? ea->reader->client : ert->client), ip1,
1504 er->cacheex_src ? username(er->cacheex_src) : (ert->selected_reader ? ert->selected_reader->label : "unknown/csp"), ip2,
1505 cw1, cw2);
1506 }
1507#endif
1508
1509 return;
1510 }
1511
1512#ifdef CS_CACHEEX
1513 /* if answer from cacheex-1 reader, not send answer to client!
1514 * thread check_cache will check counter and send answer to client!
1515 * Anyway, we should check if we have to go to oher stage (>1)
1516 */
1517
1518 if(eardr && cacheex_reader(eardr))
1519 {
1520 // if wait_time, and not wait_time expired and wait_time due to hitcache(or awtime>0),
1521 // we have to wait cacheex timeout before call other readers (stage>1)
1522 if(cacheex_reader(eardr) && !ert->cacheex_wait_time_expired && ert->cacheex_hitcache)
1523 { return; }
1524
1525 int8_t cacheex_left = 0;
1526 uint8_t has_cacheex = 0;
1527 if(ert->stage == 1)
1528 {
1529 for(ea_list = ert->matching_rdr; ea_list; ea_list = ea_list->next)
1530 {
1531 cs_readlock(__func__, &ea_list->ecmanswer_lock);
1532 if(((ea_list->status & (READER_CACHEEX | READER_FALLBACK | READER_ACTIVE))) == (READER_CACHEEX | READER_ACTIVE))
1533 { has_cacheex = 1; }
1534 if((!(ea_list->status & READER_FALLBACK) && ((ea_list->status & (REQUEST_SENT | REQUEST_ANSWERED | READER_CACHEEX | READER_ACTIVE)) == (REQUEST_SENT | READER_CACHEEX | READER_ACTIVE))) || ea_list->rc < E_NOTFOUND)
1535 { cacheex_left++; }
1536 cs_readunlock(__func__, &ea_list->ecmanswer_lock);
1537 }
1538
1539 if(has_cacheex && !cacheex_left) { request_cw_from_readers(ert, 0); }
1540 }
1541
1542 return;
1543 }
1544#endif
1545
1546 int32_t reader_left = 0, local_left = 0, reader_not_flb_left = 0, has_not_fallback = 0, has_local = 0;
1547 ert->selected_reader = eardr;
1548
1549 switch(ea->rc)
1550 {
1551 case E_FOUND:
1552 memcpy(ert->cw, ea->cw, 16);
1553 ert->cw_ex = ea->cw_ex;
1554 ert->rcEx = 0;
1555 ert->rc = ea->rc;
1556 ert->grp |= eardr->grp;
1557#ifdef HAVE_DVBAPI
1558 ert->adapter_index = ea->er->adapter_index;
1559#endif
1560 break;
1561
1562 case E_INVALID:
1563 case E_NOTFOUND:
1564 {
1565 // check if there are other readers to ask, and if not send NOT_FOUND to client
1566 ert->rcEx = ea->rcEx;
1567 cs_strncpy(ert->msglog, ea->msglog, sizeof(ert->msglog));
1568
1569 for(ea_list = ert->matching_rdr; ea_list; ea_list = ea_list->next)
1570 {
1571 cs_readlock(__func__, &ea_list->ecmanswer_lock);
1572
1573 if((!(ea_list->status & READER_FALLBACK) && ((ea_list->status & (REQUEST_SENT | REQUEST_ANSWERED | READER_LOCAL | READER_ACTIVE)) == (REQUEST_SENT | READER_LOCAL | READER_ACTIVE))) || ea_list->rc < E_NOTFOUND)
1574 { local_left++; }
1575
1576 if((!(ea_list->status & READER_FALLBACK) && ((ea_list->status & (REQUEST_SENT | REQUEST_ANSWERED | READER_ACTIVE)) == (REQUEST_SENT | READER_ACTIVE))) || ea_list->rc < E_NOTFOUND)
1577 { reader_not_flb_left++; }
1578
1579 if(((ea_list->status & (REQUEST_ANSWERED | READER_ACTIVE)) == (READER_ACTIVE)) || ea_list->rc < E_NOTFOUND)
1580 { reader_left++; }
1581
1582 if(((ea_list->status & (READER_FALLBACK | READER_ACTIVE))) == (READER_ACTIVE))
1583 { has_not_fallback = 1; }
1584 if(((ea_list->status & (READER_LOCAL | READER_FALLBACK | READER_ACTIVE))) == (READER_LOCAL | READER_ACTIVE))
1585 { has_local = 1; }
1586
1587 cs_readunlock(__func__, &ea_list->ecmanswer_lock);
1588 }
1589
1590 switch(ert->stage)
1591 {
1592 case 2: // only local reader (used only if preferlocalcards=1)
1593 {
1594 if(has_local && !local_left) { request_cw_from_readers(ert, 0); }
1595 break;
1596 }
1597 case 3:
1598 {
1599 // any fallback reader not asked yet
1600 if(has_not_fallback && !reader_not_flb_left) { request_cw_from_readers(ert, 0); }
1601 break;
1602 }
1603 }
1604
1605 if(!reader_left // no more matching reader
1606#ifdef CS_CACHEEX
1607 && !cfg.wait_until_ctimeout
1608#endif
1609 )
1610 { ert->rc = E_NOTFOUND; } // so we set the return code
1611
1612 break;
1613 }
1614
1615 case E_TIMEOUT: // if timeout, we have to send timeout to client: this is done by ecm_timeout callback
1616 return;
1617 break;
1618
1619 case E_UNHANDLED:
1620 return;
1621 break;
1622
1623 default:
1624 cs_log("unexpected ecm answer rc=%d.", ea->rc);
1625 return;
1626 break;
1627 }
1628
1629 if(ert->rc < E_99)
1630 send_dcw(ert->client, ert);
1631}
1632
1633uint32_t chk_provid(uint8_t *ecm, uint16_t caid)
1634{
1635 int32_t i, len, descriptor_length = 0;
1636 uint32_t provid = 0;
1637
1638 switch(caid >> 8)
1639 {
1640 case 0x01: // seca
1641 provid = b2i(2, ecm + 3);
1642 break;
1643
1644 case 0x05: // viaccess
1645 i = (ecm[4] == 0xD2) ? ecm[5] + 2 : 0; // skip d2 nano
1646 if((ecm[5 + i] == 3) && ((ecm[4 + i] == 0x90) || (ecm[4 + i] == 0x40)))
1647 { provid = (b2i(3, ecm + 6 + i) & 0xFFFFF0); }
1648
1649 i = (ecm[6] == 0xD2) ? ecm[7] + 2 : 0; // skip d2 nano long ecm
1650 if((ecm[7 + i] == 7) && ((ecm[6 + i] == 0x90) || (ecm[6 + i] == 0x40)))
1651 { provid = (b2i(3, ecm + 8 + i) & 0xFFFFF0); }
1652 break;
1653
1654 case 0x0D: // cryptoworks
1655 len = (((ecm[1] & 0xf) << 8) | ecm[2]) + 3;
1656 for(i = 8; i < len; i += descriptor_length + 2)
1657 {
1658 descriptor_length = ecm[i + 1];
1659 if(ecm[i] == 0x83)
1660 {
1661 provid = (uint32_t)ecm[i + 2] & 0xFE;
1662 break;
1663 }
1664 }
1665 break;
1666
1667 case 0x18: // nagra2
1668 if (caid == 0x1801) // more safety
1669 provid = b2i(2, ecm + 5);
1670 break;
1671 }
1672
1673 return provid;
1674}
1675
1676void update_chid(ECM_REQUEST *er)
1677{
1678 er->chid = get_subid(er);
1679}
1680
1681/*
1682 * This function writes the current CW from ECM struct to a cwl file.
1683 * The filename is re-calculated and file re-opened every time.
1684 * This will consume a bit cpu time, but nothing has to be stored between
1685 * each call. If not file exists, a header is prepended
1686 */
1687static void logCWtoFile(ECM_REQUEST *er, uint8_t *cw)
1688{
1689 FILE *pfCWL;
1690 char srvname[CS_SERVICENAME_SIZE];
1691 /* %s / %s _I %04X _ %s .cwl */
1692 char buf[256 + sizeof(srvname)];
1693 char date[9];
1694 uint8_t i, parity, writeheader = 0;
1695 struct tm timeinfo;
1696
1697 /*
1698 * search service name for that id and change characters
1699 * causing problems in file name
1700 */
1701
1702 get_servicename(cur_client(), er->srvid, er->prid, er->caid, srvname, sizeof(srvname));
1703
1704 for(i = 0; srvname[i]; i++)
1705 if(srvname[i] == ' ') { srvname[i] = '_'; }
1706
1707 /* calc log file name */
1708 time_t walltime = cs_time();
1709 localtime_r(&walltime, &timeinfo);
1710 strftime(date, sizeof(date), "%Y%m%d", &timeinfo);
1711 snprintf(buf, sizeof(buf), "%s/%s_I%04X_%s.cwl", cfg.cwlogdir, date, er->srvid, srvname);
1712
1713 /* open failed, assuming file does not exist, yet */
1714 if((pfCWL = fopen(buf, "r")) == NULL)
1715 {
1716 writeheader = 1;
1717 }
1718 else
1719 {
1720 /* we need to close the file if it was opened correctly */
1721 fclose(pfCWL);
1722 }
1723
1724 if((pfCWL = fopen(buf, "a+")) == NULL)
1725 {
1726 /* maybe this fails because the subdir does not exist. Is there a common function to create it?
1727 for the moment do not print32_t to log on every ecm
1728 cs_log(""error opening cw logfile for writing: %s (errno=%d %s)", buf, errno, strerror(errno)); */
1729 return;
1730 }
1731 if(writeheader)
1732 {
1733 /* no global macro for cardserver name :( */
1734 fprintf(pfCWL, "# OSCam cardserver v%s - https://trac.streamboard.tv/oscam/\n", CS_VERSION);
1735 fprintf(pfCWL, "# control word log file for use with tsdec offline decrypter\n");
1736 strftime(buf, sizeof(buf), "DATE %Y-%m-%d, TIME %H:%M:%S, TZ %Z\n", &timeinfo);
1737 fprintf(pfCWL, "# %s", buf);
1738 fprintf(pfCWL, "# CAID 0x%04X, SID 0x%04X, SERVICE \"%s\"\n", er->caid, er->srvid, srvname);
1739 }
1740
1741 parity = er->ecm[0] & 1;
1742 fprintf(pfCWL, "%d ", parity);
1743 for(i = parity * 8; i < 8 + parity * 8; i++)
1744 { fprintf(pfCWL, "%02X ", cw[i]); }
1745 /* better use incoming time er->tps rather than current time? */
1746 strftime(buf, sizeof(buf), "%H:%M:%S\n", &timeinfo);
1747 fprintf(pfCWL, "# %s", buf);
1748 fflush(pfCWL);
1749 fclose(pfCWL);
1750}
1751
1752int32_t write_ecm_answer(struct s_reader *reader, ECM_REQUEST *er, int8_t rc, uint8_t rcEx, uint8_t *cw, char *msglog, uint16_t used_cardtier, EXTENDED_CW* cw_ex)
1753{
1754 if(!reader || !er || !er->tps.time) { return 0; }
1755
1756 // drop too late answers, to avoid seg fault --> only answer until tps.time+((cfg.ctimeout+500)/1000+1) is accepted
1757 time_t timeout = time(NULL) - ((cfg.ctimeout + 500) / 1000 + 1);
1758 if(er->tps.time < timeout) // < and NOT <=
1759 { return 0; }
1760
1761 struct timeb now;
1762 cs_ftime(&now);
1763
1764#ifdef CS_CACHEEX_AIO
1765 uint8_t dontsetAnswered = 0;
1766#endif
1767 uint8_t dontwriteStats = 0;
1768
1769 if(er && er->parent)
1770 {
1771 // parent is only set on reader->client->ecmtask[], but we want original er
1772 ECM_REQUEST *er_reader_cp = er;
1773 er = er->parent; // Now er is "original" ecm, before it was the reader-copy
1774 er_reader_cp->rc = rc;
1775 er_reader_cp->idx = 0;
1776#ifdef CS_CACHEEX_AIO
1777 er->localgenerated = er_reader_cp->localgenerated;
1778#endif
1779
1780 timeout = time(NULL) - ((cfg.ctimeout + 500) / 1000 + 1);
1781 if(er->tps.time < timeout)
1782 { return 0; }
1783 }
1784
1785#ifdef CS_CACHEEX_AIO
1786 if(rc < E_NOTFOUND && !er->localgenerated && (reader->cacheex.localgenerated_only_in || chk_lg_only(er, &reader->cacheex.lg_only_in_tab)) && !chk_srvid_localgenerated_only_exception(er))
1787 {
1788 cs_log_dbg(D_CACHEEX, "reader: %s !er->localgenerated - rc: E_NOTFOUND set, no stats written for reader", reader ? reader->label : "-");
1789 rc = E_NOTFOUND;
1790 dontsetAnswered = 1;
1791 dontwriteStats = 1;
1792 }
1793#endif
1794
1795 struct s_ecm_answer *ea = get_ecm_answer(reader, er);
1796 if(!ea) { return 0; }
1797
1798 cs_writelock(__func__, &ea->ecmanswer_lock);
1799
1800 if((ea->status & REQUEST_ANSWERED))
1801 {
1802 cs_log_dbg(D_READER, "Reader %s already answer, skip this ecm answer!", reader ? reader->label : "-");
1803 cs_writeunlock(__func__, &ea->ecmanswer_lock);
1804 return 0;
1805 }
1806
1807 // Special checks for rc
1808 // Skip check for BISS1 - cw could be zero but still catch cw=0 by anticascading
1809 // Skip check for BISS2 - we use the extended cw, so the "simple" cw is always zero
1810
1811 // bad/wrong chksum/ecm
1812 if(rc == E_NOTFOUND && rcEx == E2_WRONG_CHKSUM)
1813 {
1814 cs_log_dbg(D_READER, "ECM for reader %s was bad/has a wrong chksum!", reader ? reader->label : "-");
1815 rc = E_INVALID;
1816 rcEx = E2_WRONG_CHKSUM;
1817 er->stage = 5;
1818
1819 // dont write stats for bad/wrong chksum/ecm
1820 dontwriteStats = 1;
1821
1822 // set all other matching_readers => inactive to skip them and dont spread the bad ecm
1823 struct s_ecm_answer *ea_list;
1824 for(ea_list = er->matching_rdr; ea_list; ea_list = ea_list->next)
1825 {
1826 ea_list->status &= ~(READER_ACTIVE | READER_FALLBACK);
1827 }
1828 }
1829
1830 if(rc < E_NOTFOUND && cw && chk_is_null_CW(cw) && !caid_is_biss(er->caid))
1831 {
1832 rc = E_NOTFOUND;
1833 cs_log_dbg(D_TRACE | D_LB, "WARNING: reader %s send fake cw, set rc=E_NOTFOUND!", reader ? reader->label : "-");
1834 }
1835
1836 if(rc < E_NOTFOUND && cw && !chk_halfCW(er,cw))
1837 {
1838 rc = E_NOTFOUND;
1839 cs_log_dbg(D_TRACE | D_LB, "WARNING: reader %s send wrong swapped NDS cw, set rc=E_NOTFOUND!", reader ? reader->label : "-");
1840 }
1841
1842 if(reader && cw && rc < E_NOTFOUND)
1843 {
1844 if(!cfg.disablecrccws && !reader->disablecrccws)
1845 {
1846 if(!chk_if_ignore_checksum(er, &cfg.disablecrccws_only_for) && !chk_if_ignore_checksum(er, &reader->disablecrccws_only_for))
1847 {
1848 uint8_t i, c;
1849 for(i = 0; i < 16; i += 4)
1850 {
1851 c = ((cw[i] + cw[i + 1] + cw[i + 2]) & 0xff);
1852
1853 if(cw[i + 3] != c)
1854 {
1855 uint8_t nano = 0x00;
1856 if(er->caid == 0x100 && er->ecm[5] > 0x00)
1857 {
1858 nano = er->ecm[5]; // seca nano protection
1859 }
1860
1861 if(reader->dropbadcws && !nano) // only drop controlword if no cw encryption is applied
1862 {
1863 rc = E_NOTFOUND;
1864 rcEx = E2_WRONG_CHKSUM;
1865 break;
1866 }
1867 else
1868 {
1869 if(!nano) // only fix checksum if no cw encryption is applied (nano = 0)
1870 {
1871 cs_log_dbg(D_TRACE, "notice: changed dcw checksum byte cw[%i] from %02x to %02x", i + 3, cw[i + 3], c);
1872 cw[i + 3] = c;
1873 }
1874 else
1875 {
1876 if(i == 12) // there are servers delivering correct controlwords but with failing last cw checksum (on purpose?!)
1877 {
1878 cs_log_dbg(D_TRACE,"NANO%02d: BAD PEER DETECTED, oscam has fixed the last cw crc that wasn't matching!", nano);
1879 cw[i + 3] = c; // fix the last controlword
1880 }
1881 else
1882 {
1883 cs_log_dbg(D_TRACE,"NANO%02d: not fixing the crc of this cw since its still encrypted!", nano);
1884 break; // crc failed so stop!
1885 }
1886 }
1887 }
1888 }
1889 }
1890 }
1891 else
1892 {
1893 cs_log_dbg(D_TRACE, "notice: CW checksum check disabled for %04X:%06X", er->caid, er->prid);
1894 }
1895 }
1896 else
1897 {
1898 cs_log_dbg(D_TRACE, "notice: CW checksum check disabled");
1899 }
1900
1901 if(chk_if_ignore_checksum(er, &reader->disablecrccws_only_for) && caid_is_videoguard(er->caid)
1902#ifdef CS_CACHEEX_AIO
1903 && !chk_srvid_disablecrccws_only_for_exception(er)
1904#endif
1905 )
1906 {
1907 uint8_t k, csum;
1908 uint8_t hit = 0;
1909 uint8_t oe = checkCWpart(cw, 0) ? 0 : 8;
1910 for(k = 0; k < 8; k += 4)
1911 {
1912 csum = ((cw[k + oe] + cw[k + oe + 1] + cw[k + oe + 2]) & 0xff);
1913 if(cw[k + oe + 3] == csum)
1914 {
1915 hit++;
1916 }
1917 }
1918 if(hit > 1)
1919 {
1920 char ecmd5s[17 * 3];
1921 cs_hexdump(0, er->ecmd5, 16, ecmd5s, sizeof(ecmd5s));
1922 if(reader->dropbadcws)
1923 {
1924 rc = E_NOTFOUND;
1925 rcEx = E2_WRONG_CHKSUM;
1926 cs_log("Probably got bad CW from reader: %s, caid %04X, srvid %04X (%s) - dropping CW, lg: %i", reader->label, er->caid, er->srvid, ecmd5s
1927#ifdef CS_CACHEEX_AIO
1928 , er->localgenerated);
1929#else
1930 , 0);
1931#endif
1932 }
1933 else
1934 {
1935 cs_log("Probably got bad CW from reader: %s, caid %04X, srvid %04X (%s), lg: %i", reader->label, er->caid, er->srvid, ecmd5s
1936#ifdef CS_CACHEEX_AIO
1937 , er->localgenerated);
1938#else
1939 , 0);
1940#endif
1941 }
1942 }
1943 }
1944
1945 }
1946
1947#ifdef CW_CYCLE_CHECK
1948 uint8_t cwc_ct = er->cwc_cycletime > 0 ? er->cwc_cycletime : 0;
1949 uint8_t cwc_ncwc = er->cwc_next_cw_cycle < 2 ? er->cwc_next_cw_cycle : 2;
1950 if(!checkcwcycle(er->client, er, reader, cw, rc, cwc_ct, cwc_ncwc))
1951 {
1952#ifdef CS_CACHEEX_AIO
1953 if(!er->localgenerated)
1954 {
1955#endif
1956 rc = E_NOTFOUND;
1957 rcEx = E2_WRONG_CHKSUM;
1958 cs_log_dbg(D_CACHEEX | D_CWC | D_LB, "{client %s, caid %04X, srvid %04X} [write_ecm_answer] cyclecheck failed! Reader: %s set rc: %i", (er->client ? er->client->account->usr : "-"), er->caid, er->srvid, reader ? reader->label : "-", rc);
1959
1960#ifdef CS_CACHEEX_AIO
1961 }
1962 else
1963 {
1964 cs_log_dbg(D_CACHEEX | D_CWC | D_LB, "{client %s, caid %04X, srvid %04X} [write_ecm_answer] cyclecheck failed! Reader: %s set rc: %i -> lg-flagged CW -> do nothing", (er->client ? er->client->account->usr : "-"), er->caid, er->srvid, reader ? reader->label : "-", rc);
1965 }
1966#endif
1967 }
1968 else { cs_log_dbg(D_CACHEEX | D_CWC | D_LB, "{client %s, caid %04X, srvid %04X} [write_ecm_answer] cyclecheck passed! Reader: %s rc: %i", (er->client ? er->client->account->usr : "-"), er->caid, er->srvid, reader ? reader->label : "-", rc); }
1969#endif
1970 //END -- SPECIAL CHECKs for rc
1971
1972#ifdef CS_CACHEEX_AIO
1973 if(!dontsetAnswered)
1974 {
1975#endif
1976 ea->status |= REQUEST_ANSWERED;
1977#ifdef CS_CACHEEX_AIO
1978 }
1979#endif
1980 ea->rc = rc;
1981 ea->ecm_time = comp_timeb(&now, &ea->time_request_sent);
1982 if(ea->ecm_time < 1) { ea->ecm_time = 1; } // set ecm_time 1 if answer immediately
1983 ea->rcEx = rcEx;
1984 if(cw) { memcpy(ea->cw, cw, 16); }
1985 if(msglog) { memcpy(ea->msglog, msglog, MSGLOGSIZE); }
1986 ea->tier = used_cardtier;
1987 if(cw_ex)
1988 {
1989 ea->cw_ex = *cw_ex;
1990 }
1991
1992 cs_writeunlock(__func__, &ea->ecmanswer_lock);
1993
1994 struct timeb tpe;
1995 cs_ftime(&tpe);
1996 int32_t ntime = comp_timeb(&tpe, &er->tps);
1997 if(ntime < 1) { ntime = 1; }
1998 cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} [write_ecm_answer] reader %s rc %d, ecm time %d ms (%d ms)", (check_client(er->client) ? er->client->account->usr : "-"), er->caid, er->prid, er->srvid, reader ? reader->label : "-", rc, ea->ecm_time, ntime);
1999
2000 // send ea for ecm request
2001 int32_t res = 0;
2002 struct s_client *cl = er->client;
2003 if(check_client(cl))
2004 {
2005 res = 1;
2006 add_job(er->client, ACTION_ECM_ANSWER_READER, ea, 0); // chk_dcw
2007 }
2008
2009 // distribute ea for pendings
2010 if(ea->pending) // has pending ea
2011 { distribute_ea(ea); }
2012
2013
2014 if(!ea->is_pending) // not for pending ea - only once for ea
2015 {
2016 // cache update
2017 // Skip check for BISS1 - cw could be indeed zero
2018 // Skip check for BISS2 - we use the extended cw, so the "simple" cw is always zero
2019 if(ea && (ea->rc < E_NOTFOUND) && (!chk_is_null_CW(ea->cw) && !caid_is_biss(er->caid)))
2020 {
2021#ifdef CS_CACHEEX_AIO
2022 int32_t ecmtime = ea->ecm_time;
2023
2024 if(er->cacheex_wait_time_expired && er->cacheex_wait_time)
2025 ecmtime = ea->ecm_time + er->cacheex_wait_time;
2026#endif
2027 add_cache_from_reader(er, reader, er->csp_hash, er->ecmd5, ea->cw, er->caid, er->prid, er->srvid
2028#ifdef CS_CACHEEX_AIO
2029 , ecmtime);
2030#else
2031 );
2032#endif
2033 }
2034
2035 if(!dontwriteStats)
2036 {
2037 // readers stats for LB
2038 send_reader_stat(reader, er, ea, ea->rc);
2039 }
2040
2041 // reader checks
2042#ifdef WITH_DEBUG
2043 if(cs_dblevel & D_TRACE)
2044 {
2045 char ecmd5[17 * 3];
2046 cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5));
2047 rdr_log_dbg(reader, D_TRACE, "ecm answer for ecm hash %s rc=%d", ecmd5, ea->rc);
2048 }
2049#endif
2050 // Update reader stats:
2051 if(ea->rc == E_FOUND)
2052 {
2053 if(cfg.cwlogdir != NULL)
2054 { logCWtoFile(er, ea->cw); } // CWL logging only if cwlogdir is set in config
2055
2056 reader->ecmsok++;
2057#ifdef CS_CACHEEX_AIO
2058 if(er->localgenerated)
2059 reader->ecmsoklg++;
2060#endif
2061 reader->webif_ecmsok++;
2062#ifdef CS_CACHEEX
2063 struct s_client *eacl = reader->client;
2064 if(cacheex_reader(reader) && check_client(eacl))
2065 {
2066 eacl->cwcacheexgot++;
2067 cacheex_add_stats(eacl, ea->er->caid, ea->er->srvid, ea->er->prid, 1
2068#ifdef CS_CACHEEX_AIO
2069 , er->localgenerated);
2070#else
2071 );
2072#endif
2073 first_client->cwcacheexgot++;
2074#ifdef CS_CACHEEX_AIO
2075 if(er->localgenerated)
2076 {
2077 eacl->cwcacheexgotlg++;
2078 first_client->cwcacheexgotlg++;
2079 }
2080#endif
2081 }
2082#endif
2083 }
2084 else if(ea->rc == E_NOTFOUND)
2085 {
2086 reader->ecmsnok++;
2087 reader->webif_ecmsnok++;
2088 if(reader->ecmnotfoundlimit && reader->ecmsnok >= reader->ecmnotfoundlimit)
2089 {
2090 rdr_log(reader, "ECM not found limit reached %u. Restarting the reader.",
2091 reader->ecmsnok);
2092 reader->ecmsnok = 0; // Reset the variable
2093 reader->ecmshealthnok = 0; // Reset the variable
2094 add_job(reader->client, ACTION_READER_RESTART, NULL, 0);
2095 }
2096 }
2097
2098 // this fixes big oscam mistake
2099 // wrong reader status on web info aka not counted timeouts which dispalyed
2100 // reader info 100 percent OK but reader had a ton of unhandled timeouts!
2101 else if(ea->rc == E_TIMEOUT)
2102 {
2103#ifdef WITH_LB
2104 STAT_QUERY q;
2105 readerinfofix_get_stat_query(er, &q);
2106 READER_STAT *s;
2107 s = readerinfofix_get_add_stat(reader, &q);
2108 if (s)
2109 {
2110 cs_log_dbg(D_LB, "inc fail {client %s, caid %04X, prid %06X, srvid %04X} [write_ecm_answer] reader %s rc %d, ecm time %d ms (%d ms)", (check_client(er->client) ? er->client->account->usr : "-"), er->caid, er->prid, er->srvid, reader ? reader->label : "-", rc, ea->ecm_time, ntime);
2111 readerinfofix_inc_fail(s); // now increase fail factor for unhandled timeouts
2112 }
2113#endif
2114 reader->ecmstout++; // now append timeouts to the readerinfo timeout count
2115 reader->webif_ecmstout++;
2116 }
2117
2118 // Reader ECMs Health Try (by Pickser)
2119 if(reader->ecmsok != 0 || reader->ecmsnok != 0 || reader->ecmstout != 0)
2120 {
2121 reader->ecmshealthok = ((double) reader->ecmsok / (reader->ecmsok + reader->ecmsnok + reader->ecmstout)) * 100;
2122#ifdef CS_CACHEEX_AIO
2123 reader->ecmshealthoklg = ((double) reader->ecmsoklg / (reader->ecmsok + reader->ecmsnok + reader->ecmstout)) * 100;
2124#endif
2125 reader->ecmshealthnok = ((double) reader->ecmsnok / (reader->ecmsok + reader->ecmsnok + reader->ecmstout)) * 100;
2126 reader->ecmshealthtout = ((double) reader->ecmstout / (reader->ecmsok + reader->ecmsnok + reader->ecmstout)) * 100;
2127 }
2128
2129 if(rc == E_FOUND && reader->resetcycle > 0)
2130 {
2131 reader->resetcounter++;
2132 if(reader->resetcounter > reader->resetcycle)
2133 {
2134 reader->resetcounter = 0;
2135 rdr_log(reader, "Resetting reader, resetcyle of %d ecms reached", reader->resetcycle);
2136 reader->card_status = CARD_NEED_INIT;
2137 cardreader_reset(cl);
2138 }
2139 }
2140 }
2141
2142 return res;
2143}
2144
2145static void guess_cardsystem(ECM_REQUEST *er)
2146{
2147 uint16_t last_hope = 0;
2148
2149 // viaccess - check by provid-search
2150 if((er->prid = chk_provid(er->ecm, 0x500)))
2151 { er->caid = 0x500; }
2152
2153 // nagra
2154 // is ecm[1] always 0x30 ?
2155 // is ecm[3] always 0x07 ?
2156 if((er->ecm[6] == 1) && (er->ecm[4] == er->ecm[2] - 2))
2157 { er->caid = 0x1801; }
2158
2159 // seca2 - very poor
2160 if((er->ecm[8] == 0x10) && ((er->ecm[9] & 0xF1) == 1))
2161 { last_hope = 0x100; }
2162
2163 // is cryptoworks, but which caid ?
2164 if((er->ecm[3] == 0x81) && (er->ecm[4] == 0xFF) &&
2165 (!er->ecm[5]) && (!er->ecm[6]) && (er->ecm[7] == er->ecm[2] - 5))
2166 {
2167 last_hope = 0xd00;
2168 }
2169
2170 if(!er->caid && er->ecm[2] == 0x31 && er->ecm[0x0b] == 0x28)
2171 { guess_irdeto(er); }
2172
2173 if(!er->caid) // guess by len...
2174 { er->caid = len4caid[er->ecm[2] + 3]; }
2175
2176 if(!er->caid)
2177 { er->caid = last_hope; }
2178}
2179
2180// chid calculation from module stat to here
2181// to improve the quickfix concerning ecm chid info and extend it
2182// to all client requests wereby the chid is known in module stat
2183
2184uint32_t get_subid(ECM_REQUEST *er)
2185{
2186 if(!er->ecmlen)
2187 { return 0; }
2188
2189 uint32_t id = 0;
2190 switch(er->caid >> 8)
2191 {
2192 case 0x01: // seca
2193 id = b2i(2, er->ecm + 7);
2194 break;
2195
2196 case 0x05: // viaccess
2197 id = b2i(2, er->ecm + 8);
2198 break;
2199
2200 case 0x06: // irdeto
2201 id = b2i(2, er->ecm + 6);
2202 break;
2203
2204 case 0x09: // videoguard
2205 id = b2i(2, er->ecm + 11);
2206 break;
2207
2208 case 0x4A: // DRE-Crypt, Bulcrypt, Tongfang and others?
2209 if(!caid_is_bulcrypt(er->caid) && !caid_is_dre(er->caid))
2210 { id = b2i(2, er->ecm + 6); }
2211 break;
2212 }
2213 return id;
2214}
2215
2216static void set_readers_counter(ECM_REQUEST *er)
2217{
2218 struct s_ecm_answer *ea;
2219
2220 er->reader_count = 0;
2221 er->fallback_reader_count = 0;
2222 er->localreader_count = 0;
2223 er->cacheex_reader_count = 0;
2224
2225 for(ea = er->matching_rdr; ea; ea = ea->next)
2226 {
2227 if(ea->status & READER_ACTIVE)
2228 {
2229 if(!(ea->status & READER_FALLBACK))
2230 { er->reader_count++; }
2231 else
2232 { er->fallback_reader_count++; }
2233
2234 if(cacheex_reader(ea->reader))
2235 { er->cacheex_reader_count++; }
2236 else if(is_localreader(ea->reader, er))
2237 { er->localreader_count++; }
2238 }
2239 }
2240}
2241
2242void write_ecm_answer_fromcache(struct s_write_from_cache *wfc)
2243{
2244 ECM_REQUEST *er = NULL;
2245 ECM_REQUEST *ecm = NULL;
2246
2247 er = wfc->er_new;
2248 ecm = wfc->er_cache;
2249
2250#ifdef CS_CACHEEX_AIO
2251 if(ecm->localgenerated || (ecm->cw_count > 0x0F000000))
2252 er->localgenerated = 1;
2253#endif
2254
2255 int8_t rc_orig = er->rc;
2256
2257 er->grp |= ecm->grp; // update group
2258#ifdef CS_CACHEEX
2259 if(ecm->from_csp) { er->csp_answered = 1; } // update er as answered by csp (csp have no group)
2260#endif
2261
2262 if(er->rc >= E_NOTFOUND)
2263 {
2264#ifdef CS_CACHEEX
2265 if(ecm->cacheex_src) // from cacheex or csp
2266 {
2267 er->rc = E_CACHEEX;
2268 }
2269 else
2270#endif
2271 { er->rc=E_CACHE1; } // from normal readers
2272
2273 memcpy(er->cw, ecm->cw, 16);
2274 er->selected_reader = ecm->selected_reader;
2275 er->cw_count = ecm->cw_count;
2276
2277#ifdef CS_CACHEEX
2278 // here we should be sure cex client has not been freed!
2279 if(ecm->cacheex_src && is_valid_client(ecm->cacheex_src) && !ecm->cacheex_src->kill)
2280 {
2281 er->cacheex_src = ecm->cacheex_src;
2282 er->cwc_cycletime = ecm->cwc_cycletime;
2283 er->cwc_next_cw_cycle = ecm->cwc_next_cw_cycle;
2284 }
2285 else
2286 {
2287 er->cacheex_src = NULL;
2288 }
2289
2290 int8_t cacheex = check_client(er->client) && er->client->account ? er->client->account->cacheex.mode : 0;
2291 if(cacheex == 1 && check_client(er->client))
2292 {
2293 cacheex_add_stats(er->client, er->caid, er->srvid, er->prid, 0
2294#ifdef CS_CACHEEX_AIO
2295 , er->localgenerated);
2296#else
2297 );
2298#endif
2299 er->client->cwcacheexpush++;
2300 if(er->client->account)
2301 { er->client->account->cwcacheexpush++; }
2302 first_client->cwcacheexpush++;
2303
2304#ifdef CS_CACHEEX_AIO
2305 if(er->localgenerated)
2306 {
2307 er->client->cwcacheexpushlg++;
2308 first_client->cwcacheexpushlg++;
2309 }
2310#endif
2311
2312 }
2313#endif
2314
2315#ifdef CS_CACHEEX
2316 if(cfg.delay && cacheex!=1) // No delay on cacheexchange mode 1 client!
2317 { cs_sleepms(cfg.delay); }
2318#else
2319 if(cfg.delay)
2320 { cs_sleepms(cfg.delay); }
2321#endif
2322
2323 if(rc_orig == E_UNHANDLED)
2324 {
2325 cs_log_dbg(D_LB,"{client %s, caid %04X, prid %06X, srvid %04X} [write_ecm_answer_fromcache] found cw in CACHE (count %d)!", (check_client(er->client)?er->client->account->usr:"-"),er->caid, er->prid, er->srvid,
2326#ifdef CS_CACHEEX_AIO
2327 (er->cw_count > 0x0F000000) ? er->cw_count ^= 0x0F000000 : er->cw_count);
2328#else
2329 er->cw_count);
2330#endif
2331 send_dcw(er->client, er);
2332 }
2333 }
2334}
2335
2336#ifdef CS_CACHEEX_AIO
2337static bool ecm_cache_check(ECM_REQUEST *er)
2338{
2339 if(ecm_cache_init_done && cfg.ecm_cache_droptime > 0)
2340 {
2341 ECM_CACHE *ecm_cache = NULL;
2342 SAFE_RWLOCK_WRLOCK(&ecm_cache_lock);
2343 ecm_cache = find_hash_table(&ht_ecm_cache, &er->csp_hash, sizeof(uint32_t), &compare_csp_hash_ecmcache);
2344 if(!ecm_cache)
2345 {
2346 // ecm_cache-size(count/memory) pre-check
2347 if(
2348 (cfg.ecm_cache_size && (cfg.ecm_cache_size > tommy_hashlin_count(&ht_ecm_cache)))
2349 || (cfg.ecm_cache_memory && (cfg.ecm_cache_memory*1024*1024 > tommy_hashlin_memory_usage(&ht_ecm_cache)))
2350 )
2351 {
2352 if(cs_malloc(&ecm_cache, sizeof(ECM_CACHE)))
2353 {
2354 ecm_cache->csp_hash = er->csp_hash;
2355 cs_ftime(&ecm_cache->first_recv_time);
2356 cs_ftime(&ecm_cache->upd_time);
2357
2358 tommy_hashlin_insert(&ht_ecm_cache, &ecm_cache->ht_node, ecm_cache, tommy_hash_u32(0, &er->csp_hash, sizeof(er->csp_hash)));
2359 tommy_list_insert_tail(&ll_ecm_cache, &ecm_cache->ll_node, ecm_cache);
2360
2361 SAFE_RWLOCK_UNLOCK(&ecm_cache_lock);
2362 return true;
2363 }
2364 else{
2365 SAFE_RWLOCK_UNLOCK(&ecm_cache_lock);
2366 cs_log("[ecm_cache] ERROR: NO added HASH to ecm_cache!!");
2367 return false;
2368 }
2369 }
2370 else{
2371 // clean cache call;
2372 SAFE_RWLOCK_UNLOCK(&ecm_cache_lock);
2373 ecm_cache_cleanup(true);
2374 return false;
2375 }
2376 }
2377 // ecm found
2378 else{
2379 int64_t gone_diff = 0;
2380 gone_diff = comp_timeb(&er->tps, &ecm_cache->first_recv_time);
2381 cs_ftime(&ecm_cache->upd_time);
2382
2383 if(gone_diff >= cfg.ecm_cache_droptime * 1000)
2384 {
2385 cs_log_dbg(D_CW_CACHE, "[ecm_cache] ECM drop, current ecm_cache_size: %i - ecm_cache-mem-size: %i MiB", count_hash_table(&ht_ecm_cache), (int)(tommy_hashlin_memory_usage(&ht_ecm_cache)/1024/1024));
2386 SAFE_RWLOCK_UNLOCK(&ecm_cache_lock);
2387 return false;
2388 }
2389 }
2390
2391 SAFE_RWLOCK_UNLOCK(&ecm_cache_lock);
2392 return true;
2393 }
2394 else{
2395 cs_log_dbg(D_CW_CACHE,"[ecm_cache] ecm_cache_init_done %i cfg.ecm_cache_size: %"PRIu32" cfg.ecm_cache_memory %"PRIu32" MiB", ecm_cache_init_done, cfg.ecm_cache_size, cfg.ecm_cache_memory);
2396 return true;
2397 }
2398}
2399#endif
2400
2401void get_cw(struct s_client *client, ECM_REQUEST *er)
2402{
2403#ifdef CS_CACHEEX_AIO
2404 cacheex_update_hash(er);
2405 if(!ecm_cache_check(er))
2406 {
2407 er->rc = E_INVALID;
2408 send_dcw(client, er);
2409 free_ecm(er);
2410 return;
2411 }
2412#endif
2413 cs_log_dump_dbg(D_ATR, er->ecm, er->ecmlen, "get cw for ecm:");
2414 cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} [get_cw] NEW REQUEST!", (check_client(er->client) ? er->client->account->usr : "-"), er->caid, er->prid, er->srvid);
2415 increment_n_request(client);
2416
2417 int32_t i, j, m;
2418 time_t now = time((time_t *)0);
2419 uint32_t line = 0;
2420 uint16_t sct_len;
2421
2422 er->client = client;
2423 er->rc = E_UNHANDLED; // set default rc status to unhandled
2424 er->cwc_next_cw_cycle = 2; // set it to: we dont know
2425
2426 // user was on freetv or didn't request for some time
2427 // so we reset lastswitch to get correct stats/webif display
2428 if(now - client->lastecm > cfg.hideclient_to) { client->lastswitch = 0; }
2429 client->lastecm = now;
2430
2431 if(client == first_client || !client ->account || client->account == first_client->account)
2432 {
2433 // DVBApi+serial is allowed to request anonymous accounts:
2434 int16_t listenertype = get_module(client)->listenertype;
2435 if(listenertype != LIS_DVBAPI && listenertype != LIS_SERIAL)
2436 {
2437 er->rc = E_INVALID;
2438 er->rcEx = E2_GLOBAL;
2439 snprintf(er->msglog, sizeof(er->msglog), "invalid user account %s", username(client));
2440 }
2441 }
2442
2443 // ecmlen must be 0 (no ecm) or >2 (because SCT_LEN() needs at least 3 bytes)
2444 if(er->ecmlen < 0 || er->ecmlen == 1 || er->ecmlen == 2)
2445 {
2446 er->rc = E_INVALID;
2447 er->rcEx = E2_GLOBAL;
2448 snprintf(er->msglog, sizeof(er->msglog), "ECM size %d invalid, ignored! client %s", er->ecmlen, username(client));
2449 }
2450
2451 if(er->ecmlen > MAX_ECM_SIZE)
2452 {
2453 er->rc = E_INVALID;
2454 er->rcEx = E2_GLOBAL;
2455 snprintf(er->msglog, sizeof(er->msglog), "ECM size %d > Max ECM size %d, ignored! client %s", er->ecmlen, MAX_ECM_SIZE, username(client));
2456 }
2457
2458 if(er->ecmlen > 2)
2459 {
2460 sct_len = SCT_LEN(er->ecm);
2461 if(sct_len > er->ecmlen || sct_len < 4)
2462 {
2463 er->rc = E_INVALID;
2464 er->rcEx = E2_GLOBAL;
2465 snprintf(er->msglog, sizeof(er->msglog), "Real ECM size %d > ECM size %d, ignored! client %s", sct_len, er->ecmlen, username(client));
2466 }
2467 er->ecmlen = sct_len;
2468 }
2469
2470 if(!client->grp)
2471 {
2472 er->rc = E_INVALID;
2473 er->rcEx = E2_GROUP;
2474 snprintf(er->msglog, sizeof(er->msglog), "invalid user group %s", username(client));
2475 }
2476
2477 if(!er->caid)
2478 { guess_cardsystem(er); }
2479
2480 /* Quickfix Area */
2481
2482 // add chid for all client requests as in module stat
2483 update_chid(er);
2484
2485 // quickfix for 0100:000065
2486 if(er->caid == 0x100 && er->prid == 0x65 && er->srvid == 0)
2487 { er->srvid = 0x0642; }
2488
2489 // Quickfixes for Opticum/Globo HD9500
2490 // Quickfix for 0500:030300
2491 if(er->caid == 0x500 && er->prid == 0x030300)
2492 { er->prid = 0x030600; }
2493
2494 // Quickfix for 0500:D20200
2495 if(er->caid == 0x500 && er->prid == 0xD20200)
2496 { er->prid = 0x030600; }
2497
2498 // betacrypt ecm with nagra header
2499 if(chk_is_betatunnel_caid(er->caid) == 1 && (er->ecmlen == 0x89 || er->ecmlen == 0x4A) && er->ecm[3] == 0x07 && (er->ecm[4] == 0x84 || er->ecm[4] == 0x45))
2500 {
2501 if(er->caid == 0x1702)
2502 {
2503 er->caid = 0x1833;
2504 }
2505 else
2506 {
2507 check_lb_auto_betatunnel_mode(er);
2508 }
2509 cs_log_dbg(D_TRACE, "Quickfix remap beta->nagra: 0x%X, 0x%X, 0x%X, 0x%X", er->caid, er->ecmlen, er->ecm[3], er->ecm[4]);
2510 }
2511
2512 // nagra ecm with betacrypt header 1801, 1833, 1834, 1835
2513 if(chk_is_betatunnel_caid(er->caid) == 2 && (er->ecmlen == 0x93 || er->ecmlen == 0x54) && er->ecm[13] == 0x07 && (er->ecm[14] == 0x84 || er->ecm[14] == 0x45))
2514 {
2515 if(er->caid == 0x1833)
2516 {
2517 er->caid = 0x1702;
2518 }
2519 else
2520 {
2521 er->caid = 0x1722;
2522 }
2523 cs_log_dbg(D_TRACE, "Quickfix remap nagra->beta: 0x%X, 0x%X, 0x%X, 0x%X", er->caid, er->ecmlen, er->ecm[13], er->ecm[44]);
2524 }
2525
2526 // Ariva quickfix (invalid nagra provider)
2527 if(((er->caid & 0xFF00) == 0x1800) && er->prid > 0x00FFFF)
2528 { er->prid = 0; }
2529
2530 // Check for invalid provider, extract provider out of ecm:
2531 uint32_t prid = chk_provid(er->ecm, er->caid);
2532 if(!er->prid)
2533 {
2534 er->prid = prid;
2535 }
2536 else
2537 {
2538 if(prid && prid != er->prid)
2539 {
2540 cs_log_dbg(D_TRACE, "provider fixed: %04X@%06X to %04X@%06X", er->caid, er->prid, er->caid, prid);
2541 er->prid = prid;
2542 }
2543 }
2544
2545#ifdef MODULE_NEWCAMD
2546 // Set providerid for newcamd clients if none is given
2547 if(!er->prid && client->ncd_server)
2548 {
2549 int32_t pi = client->port_idx;
2550 if(pi >= 0 && cfg.ncd_ptab.nports && cfg.ncd_ptab.nports >= pi && cfg.ncd_ptab.ports[pi].ncd)
2551 { er->prid = cfg.ncd_ptab.ports[pi].ncd->ncd_ftab.filts[0].prids[0]; }
2552 }
2553#endif
2554
2555 // CAID not supported or found
2556 if(!er->caid)
2557 {
2558 er->rc = E_INVALID;
2559 er->rcEx = E2_CAID;
2560 snprintf(er->msglog, MSGLOGSIZE, "CAID not supported or found");
2561 }
2562
2563 // user expired
2564 if(client->expirationdate && client->expirationdate < client->lastecm)
2565 { er->rc = E_EXPDATE; }
2566
2567 // out of timeframe
2568 if(client->allowedtimeframe_set)
2569 {
2570 struct tm acttm;
2571 localtime_r(&now, &acttm);
2572 int32_t curday = acttm.tm_wday;
2573 char *dest = strstr(weekdstr,"ALL");
2574 int32_t all_idx = (dest - weekdstr) / 3;
2575 uint8_t allowed = 0;
2576
2577 // checkout if current time is allowed in the current day
2578 allowed = CHECK_BIT(client->allowedtimeframe[curday][acttm.tm_hour][acttm.tm_min / 30], (acttm.tm_min % 30));
2579
2580 // or checkout if current time is allowed for all days
2581 allowed |= CHECK_BIT(client->allowedtimeframe[all_idx][acttm.tm_hour][acttm.tm_min / 30], (acttm.tm_min % 30));
2582
2583 if(!(allowed))
2584 {
2585 er->rc = E_EXPDATE;
2586 }
2587 cs_log_dbg(D_TRACE, "Check Timeframe - result: %d, day:%s time: %02dH%02d, allowed: %s\n", er->rc, shortDay[curday], acttm.tm_hour, acttm.tm_min, allowed ? "true" : "false");
2588 }
2589
2590 // user disabled
2591 if(client->disabled != 0)
2592 {
2593 if(client->failban & BAN_DISABLED)
2594 {
2595 cs_add_violation(client, client->account->usr);
2596 cs_disconnect_client(client);
2597 }
2598 er->rc = E_DISABLED;
2599 }
2600
2601 if(!chk_global_whitelist(er, &line))
2602 {
2603 debug_ecm(D_TRACE, "whitelist filtered: %s (%s) line %d", username(client), buf, line);
2604 er->rc = E_INVALID;
2605 }
2606
2607#ifdef CS_CACHEEX
2608 if(client->account && client->account->cacheex.mode == 2 && !client->account->cacheex.allow_request)
2609 {
2610 er->rc = E_INVALID;
2611 snprintf(er->msglog, MSGLOGSIZE, "invalid request from cacheex-2 client");
2612 }
2613#endif
2614
2615 // rc < 100 -> ecm error
2616 if(er->rc >= E_UNHANDLED)
2617 {
2618 m = er->caid;
2619 i = er->srvid;
2620
2621 if(i != client->last_srvid || !client->lastswitch)
2622 {
2623 if(cfg.usrfileflag)
2624 { cs_statistics(client); }
2625 client->lastswitch = now;
2626 }
2627
2628 // user sleeping
2629 if(client->tosleep && (now - client->lastswitch > client->tosleep))
2630 {
2631 if(client->failban & BAN_SLEEPING)
2632 {
2633 cs_add_violation(client, client->account->usr);
2634 cs_disconnect_client(client);
2635 }
2636 if(client->c35_sleepsend != 0)
2637 {
2638 er->rc = E_STOPPED; // send sleep command CMD08 {00 255}
2639 }
2640 else
2641 {
2642 er->rc = E_SLEEPING;
2643 }
2644 }
2645
2646 client->last_srvid = i;
2647 client->last_caid = m;
2648 client->last_provid = er->prid;
2649
2650 int32_t ecm_len = (((er->ecm[1] & 0x0F) << 8) | er->ecm[2]) + 3;
2651
2652 for(j = 0; (j < 6) && (er->rc >= E_UNHANDLED); j++)
2653 {
2654 switch(j)
2655 {
2656 case 0:
2657 // fake (uniq)
2658 if(client->dup)
2659 { er->rc = E_FAKE; }
2660 break;
2661
2662 case 1:
2663 // invalid (caid)
2664 if(!chk_bcaid(er, &client->ctab))
2665 {
2666 er->rc = E_INVALID;
2667 er->rcEx = E2_CAID;
2668 snprintf(er->msglog, MSGLOGSIZE, "invalid caid 0x%04X", er->caid);
2669 }
2670 break;
2671
2672 case 2:
2673 // invalid (srvid)
2674 // matching srvids (or 0000) specified in betatunnel will bypass this filter
2675 if(!chk_srvid(client, er))
2676 {
2677 if(!chk_on_btun(SRVID_ZERO, client, er))
2678 {
2679 er->rc = E_INVALID;
2680 snprintf(er->msglog, MSGLOGSIZE, "invalid SID");
2681 }
2682 }
2683 break;
2684
2685 case 3:
2686 // invalid (ufilters)
2687 if(!chk_ufilters(er))
2688 { er->rc = E_INVALID; }
2689 break;
2690
2691 case 4:
2692 // invalid (sfilter)
2693 if(!chk_sfilter(er, &get_module(client)->ptab))
2694 { er->rc = E_INVALID; }
2695 break;
2696
2697 case 5:
2698 // corrupt
2699 if((i = er->ecmlen - ecm_len))
2700 {
2701 if(i > 0)
2702 {
2703 cs_log_dbg(D_TRACE, "warning: ecm size adjusted from %d to %d", er->ecmlen, ecm_len);
2704 er->ecmlen = ecm_len;
2705 }
2706 else
2707 { er->rc = E_CORRUPT; }
2708 }
2709 break;
2710 }
2711 }
2712 }
2713
2714 // Check for odd/even byte
2715 // Don't check for BISS1 and BISS2 mode 1/E or fake caid (ECM is fake for them)
2716 // Don't check for BISS2 mode CA (ECM table is always 0x80)
2717 if(!caid_is_biss(er->caid) && !caid_is_fake(er->caid) && get_odd_even(er) == 0)
2718 {
2719 cs_log_dbg(D_TRACE, "warning: ecm with null odd/even byte from %s", (check_client(er->client) ? er->client->account->usr : "-"));
2720 er->rc = E_INVALID;
2721 }
2722
2723 // not continue, send rc to client
2724 if(er->rc < E_UNHANDLED)
2725 {
2726 send_dcw(client, er);
2727 free_ecm(er);
2728 return;
2729 }
2730
2731
2732#ifdef CS_CACHEEX
2733 int8_t cacheex = client->account ? client->account->cacheex.mode : 0;
2734 er->from_cacheex1_client = 0;
2735 if(cacheex == 1) {er->from_cacheex1_client = 1;}
2736#endif
2737
2738
2739 // set preferlocalcards for this ecm request (actually, paramter
2740 // is per user based, maybe in fiture it will be caid based too)
2741 er->preferlocalcards = cfg.preferlocalcards;
2742 if(client->account && client->account->preferlocalcards > -1)
2743 {
2744 er->preferlocalcards = client->account->preferlocalcards;
2745 }
2746 if(er->preferlocalcards <0 || er->preferlocalcards >2) {er->preferlocalcards=0;}
2747
2748
2749 if(chk_is_betatunnel_caid(er->caid) && client->ttab.ttnum)
2750 {
2751 cs_log_dump_dbg(D_TRACE, er->ecm, 13, "betatunnel? ecmlen=%d", er->ecmlen);
2752 cs_betatunnel(er);
2753 }
2754
2755
2756 // ignore ecm...
2757 int32_t offset = 3;
2758
2759 // ...and betacrypt header for cache md5 calculation
2760 if(caid_is_betacrypt(er->caid))
2761 { offset = 13; }
2762
2763 uint8_t md5tmp[MD5_DIGEST_LENGTH];
2764
2765 // store ECM in cache
2766 memcpy(er->ecmd5, MD5(er->ecm + offset, er->ecmlen - offset, md5tmp), CS_ECMSTORESIZE);
2767 cacheex_update_hash(er);
2768 ac_chk(client, er, 0);
2769
2770
2771 //******** CHECK IF FOUND ECM IN CACHE
2772 struct ecm_request_t *ecm = NULL;
2773 ecm = check_cache(er, client);
2774 if(ecm) // found in cache
2775 {
2776 cs_log_dbg(D_LB,"{client %s, caid %04X, prid %06X, srvid %04X} [get_cw] cw found immediately in cache! ", (check_client(er->client)?er->client->account->usr:"-"),er->caid, er->prid, er->srvid);
2777
2778 struct s_write_from_cache *wfc = NULL;
2779 if(!cs_malloc(&wfc, sizeof(struct s_write_from_cache)))
2780 {
2781 NULLFREE(ecm);
2782 free_ecm(er);
2783 return;
2784 }
2785
2786 wfc->er_new = er;
2787 wfc->er_cache = ecm;
2788 write_ecm_answer_fromcache(wfc);
2789 NULLFREE(wfc);
2790 NULLFREE(ecm);
2791 free_ecm(er);
2792
2793 return;
2794 }
2795
2796// zaplist ACoSC
2797#ifdef CS_ANTICASC
2798 if(cfg.acosc_enabled)
2799 {
2800 cs_writelock(__func__, &clientlist_lock);
2801 insert_zaplist(er, client);
2802 cs_writeunlock(__func__, &clientlist_lock);
2803 }
2804#endif
2805
2806 er->reader_avail = 0;
2807 er->readers = 0;
2808
2809 struct s_ecm_answer *ea, *prv = NULL;
2810 struct s_reader *rdr;
2811
2812 cs_readlock(__func__, &readerlist_lock);
2813 cs_readlock(__func__, &clientlist_lock);
2814
2815 for(rdr = first_active_reader; rdr; rdr = rdr->next)
2816 {
2817 uint8_t is_fallback = chk_is_fixed_fallback(rdr, er);
2818 int8_t match = matching_reader(er, rdr);
2819
2820 if(!match) // if this reader does not match, check betatunnel for it
2821 match = lb_check_auto_betatunnel(er, rdr);
2822
2823 if(match)
2824 {
2825 er->reader_avail++;
2826
2827#ifdef CS_CACHEEX
2828 if(cacheex == 1 && !cacheex_reader(rdr)) // ex1-cl only ask ex1-rdr
2829 { continue; }
2830#endif
2831
2832 if(!cs_malloc(&ea, sizeof(struct s_ecm_answer)))
2833 { goto OUT; }
2834
2835#ifdef WITH_EXTENDED_CW
2836 // Correct CSA mode is CBC - default to that instead
2837 ea->cw_ex.algo_mode = CW_ALGO_MODE_CBC;
2838#endif
2839
2840 er->readers++;
2841
2842 ea->reader = rdr;
2843 ea->er = er;
2844 ea->rc = E_UNHANDLED;
2845 if(prv)
2846 { prv->next = ea; }
2847 else
2848 { er->matching_rdr = ea; }
2849 prv = ea;
2850
2851 ea->status = READER_ACTIVE;
2852 if(cacheex_reader(rdr))
2853 { ea->status |= READER_CACHEEX; }
2854 else if(is_localreader(rdr, er))
2855 { ea->status |= READER_LOCAL; }
2856
2857 if(is_fallback && (!is_localreader(rdr, er) || (is_localreader(rdr, er) && !er->preferlocalcards)))
2858 { ea->status |= READER_FALLBACK; }
2859
2860 ea->pending = NULL;
2861 ea->is_pending = false;
2862 cs_lock_create(__func__, &ea->ecmanswer_lock, "ecmanswer_lock", 5000);
2863 }
2864 }
2865
2866OUT:
2867 cs_readunlock(__func__, &clientlist_lock);
2868 cs_readunlock(__func__, &readerlist_lock);
2869
2870 lb_set_best_reader(er);
2871
2872 // set reader_count and fallback_reader_count
2873 set_readers_counter(er);
2874
2875 // if preferlocalcards > 0, check if we have local readers selected:
2876 // if not, switch to preferlocalcards = 0 for this ecm
2877 if(er->preferlocalcards > 0)
2878 {
2879 if(er->localreader_count == 0)
2880 {
2881 er->preferlocalcards = 0;
2882 cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} NO local readers, set preferlocalcards = %d",
2883 (check_client(er->client) ? er->client->account->usr : "-"), er->caid, er->prid, er->srvid, er->preferlocalcards);
2884 }
2885 }
2886
2887#ifdef CS_CACHEEX
2888 // WAIT_TIME
2889 uint32_t cacheex_wait_time = 0;
2890 uint32_t wait_time_no_hitcache = 0;
2891 uint32_t wait_time_hitcache = 0;
2892
2893 if(client->account && !client->account->no_wait_time
2894#ifdef CS_CACHEEX_AIO
2895 && !chk_srvid_no_wait_time(er)
2896#endif
2897 && er->preferlocalcards<2)
2898 {
2899 wait_time_no_hitcache = get_cacheex_wait_time(er,NULL); // NO check hitcache. Wait_time is dwtime, or, if 0, awtime.
2900 wait_time_hitcache = get_cacheex_wait_time(er,client); // check hitcache for calculating wait_time! If hitcache wait_time is biggest value between dwtime and awtime, else it's awtime.
2901
2902 if(
2903 // If "normal" client and ex1-rdr>0, we cannot use hitcache for calculating wait_time because we cannot know if cw is available or not on ex1 server!
2904 (cacheex != 1 && er->cacheex_reader_count)
2905 ||
2906 /* Cw for ex1-cl comes from: INT. cache by "normal" readers (normal clients that ask normal readers), ex1-rdr and ex2-rdr and ex3-rdr.
2907 * If readers, we have to wait cws generating by normal clients asking normal readers and answers by ex1-rdr (cannot use hitcache).
2908 * If no readers, use hitcache for calculating wait_time.
2909 */
2910 (cacheex == 1 && er->reader_avail)
2911 )
2912 { cacheex_wait_time = wait_time_no_hitcache; }
2913 else
2914 { cacheex_wait_time = wait_time_hitcache; }
2915 }
2916
2917 cs_log_dbg(D_TRACE | D_CACHEEX, "[GET_CW] wait_time %d caid %04X prov %06X srvid %04X rc %d cacheex cl mode %d ex1rdr %d", cacheex_wait_time, er->caid, er->prid, er->srvid, er->rc, cacheex, er->cacheex_reader_count);
2918 cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} [get_cw] wait_time %d - client cacheex mode %d, reader avail for ecm %d, hitcache %d, preferlocalcards %d", (check_client(er->client) ? er->client->account->usr : "-"), er->caid, er->prid, er->srvid, cacheex_wait_time, cacheex == 1 ? 1 : 0, er->reader_avail, wait_time_hitcache ? 1 : 0, er->preferlocalcards);
2919 // END WAIT_TIME calculation
2920
2921 if(!cacheex_wait_time && (er->reader_count + er->fallback_reader_count) == 0)
2922#else
2923 if((er->reader_count + er->fallback_reader_count) == 0)
2924#endif
2925 {
2926 er->rc = E_NOTFOUND;
2927 if(!er->rcEx)
2928 { er->rcEx = E2_GROUP; }
2929 snprintf(er->msglog, MSGLOGSIZE, "no matching reader");
2930 cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} [get_cw] NO Readers and NO wait_time... not_found! ", (check_client(er->client) ? er->client->account->usr : "-"), er->caid, er->prid, er->srvid);
2931 send_dcw(client, er);
2932 free_ecm(er);
2933 return;
2934 }
2935
2936 //insert it in ecmcwcache!
2937 cs_writelock(__func__, &ecmcache_lock);
2938 er->next = ecmcwcache;
2939 ecmcwcache = er;
2940 ecmcwcache_size++;
2941 cs_writeunlock(__func__, &ecmcache_lock);
2942
2943 er->rcEx = 0;
2944#ifdef CS_CACHEEX
2945 er->cacheex_wait_time = 0;
2946 er->cacheex_wait_time_expired = 1;
2947 er->cacheex_hitcache = 0;
2948 er->cacheex_mode1_delay = 0;
2949
2950 if(cacheex_wait_time) // wait time for cacheex
2951 {
2952 er->cacheex_wait_time = cacheex_wait_time;
2953 er->cacheex_wait_time_expired = 0;
2954 er->cacheex_hitcache = wait_time_hitcache ? 1 : 0; // usefull only when cacheex mode 1 readers answers before wait_time and we have to decide if we have to wait until wait_time expires.
2955 er->cacheex_mode1_delay = get_cacheex_mode1_delay(er);
2956
2957 if(!er->cacheex_mode1_delay && er->cacheex_reader_count > 0)
2958 {
2959 request_cw_from_readers(er, 1); // setting stop_stage=1, we request only cacheex mode 1 readers. Others are requested at cacheex timeout!
2960 }
2961 }
2962 else
2963#endif
2964 request_cw_from_readers(er, 0);
2965
2966#ifdef WITH_DEBUG
2967 if(D_CLIENTECM & cs_dblevel)
2968 {
2969 char buf[ECM_FMT_LEN];
2970 format_ecm(er, buf, ECM_FMT_LEN);
2971 cs_log_dump_dbg(D_CLIENTECM, er->ecm, er->ecmlen, "Client %s ECM dump %s", username(client), buf);
2972 }
2973#endif
2974
2975 cw_process_thread_wakeup();
2976}
2977
2978int32_t ecmfmt(char *result, size_t size, uint16_t caid, uint16_t onid, uint32_t prid, uint16_t chid, uint16_t pid,
2979 uint16_t srvid, uint16_t l, char *ecmd5hex, char *csphash, char *cw, uint16_t origin_peer, uint8_t distance, char *payload, char *tier)
2980{
2981 if(!cfg.ecmfmt)
2982 {
2983 if(tier && payload)
2984 {
2985 return snprintf(result, size, "%04X@%06X/%04X/%04X/%02X:%s:0F06%s:%s", caid, prid, chid, srvid, l, ecmd5hex, payload, tier);
2986 }
2987 else if(tier)
2988 {
2989 return snprintf(result, size, "%04X@%06X/%04X/%04X/%02X:%s:%s", caid, prid, chid, srvid, l, ecmd5hex, tier);
2990 }
2991 else if(payload)
2992 {
2993 return snprintf(result, size, "%04X@%06X/%04X/%04X/%02X:%s:0F06%s", caid, prid, chid, srvid, l, ecmd5hex, payload);
2994 }
2995 else
2996 {
2997 return snprintf(result, size, "%04X@%06X/%04X/%04X/%02X:%s", caid, prid, chid, srvid, l, ecmd5hex);
2998 }
2999 }
3000
3001#define ECMFMT_NUMBER 0
3002#define ECMFMT_STRING 1
3003#define ECMFMT_CHAR 2
3004
3005 uint8_t type = 0;
3006 uint32_t ivalue = 0;
3007 char *ifmt = NULL, *sfmt = NULL;
3008 char *svalue = NULL, cvalue = '\0';
3009 uint8_t hide_if_zero = 0;
3010 char *c;
3011 uint32_t s = 0;
3012
3013 for(c = cfg.ecmfmt; *c; c++)
3014 {
3015 if(*c == '0')
3016 {
3017 hide_if_zero = 1;
3018 continue;
3019 }
3020
3021 sfmt = NULL;
3022
3023 switch(*c)
3024 {
3025 case 't':
3026 type = ECMFMT_STRING;
3027 svalue = tier;
3028 if(tier == NULL && !hide_if_zero)
3029 {
3030 type = ECMFMT_NUMBER;
3031 ifmt = "%04X";
3032 ivalue = 0;
3033 }
3034 break;
3035
3036 case 'c':
3037 type = ECMFMT_NUMBER;
3038 ifmt = "%04X";
3039 ivalue = caid;
3040 break;
3041
3042 case 'o':
3043 type = ECMFMT_NUMBER;
3044 ifmt = "%04X";
3045 ivalue = onid;
3046 break;
3047
3048 case 'p':
3049 type = ECMFMT_NUMBER;
3050 ifmt = "%06X";
3051 ivalue = prid;
3052 break;
3053
3054 case 'i':
3055 type = ECMFMT_NUMBER;
3056 ifmt = "%04X";
3057 ivalue = chid;
3058 break;
3059
3060 case 'd':
3061 type = ECMFMT_NUMBER;
3062 ifmt = "%04X";
3063 ivalue = pid;
3064 break;
3065
3066 case 's':
3067 type = ECMFMT_NUMBER;
3068 ifmt = "%04X";
3069 ivalue = srvid;
3070 break;
3071
3072 case 'l':
3073 type = ECMFMT_NUMBER;
3074 ifmt = "%02X";
3075 ivalue = l;
3076 break;
3077
3078 case 'h':
3079 type = ECMFMT_STRING;
3080 svalue = ecmd5hex;
3081 break;
3082
3083 case 'e':
3084 type = ECMFMT_STRING;
3085 svalue = csphash;
3086 break;
3087
3088 case 'w':
3089 type = ECMFMT_STRING;
3090 svalue = cw;
3091 break;
3092
3093 case 'j':
3094 type = ECMFMT_NUMBER;
3095 ifmt = "%02X";
3096 ivalue = distance;
3097 break;
3098
3099 case 'g':
3100 type = ECMFMT_NUMBER;
3101 ifmt = "%04X";
3102 ivalue = origin_peer;
3103 break;
3104
3105 case '\\':
3106 c++;
3107 type = ECMFMT_CHAR;
3108 cvalue = *c;
3109
3110 if(cvalue == '\0')
3111 { return s; }
3112 break;
3113
3114 case 'y':
3115 type = ECMFMT_STRING;
3116 svalue = payload;
3117 sfmt = "0F06%.06s";
3118 if(payload == NULL && !hide_if_zero)
3119 {
3120 type = ECMFMT_NUMBER;
3121 ifmt = "0F06%06X";
3122 ivalue = 0;
3123 }
3124 break;
3125
3126 case 'Y':
3127 type = ECMFMT_STRING;
3128 svalue = payload;
3129 sfmt = "0F06%s";
3130 if(payload == NULL && !hide_if_zero)
3131 {
3132 type = ECMFMT_NUMBER;
3133 ifmt = "0F06%12X";
3134 ivalue = 0;
3135 }
3136 break;
3137
3138 default:
3139 type = ECMFMT_CHAR;
3140 cvalue = *c;
3141 break;
3142 }
3143
3144 if(hide_if_zero)
3145 {
3146 if(type == ECMFMT_NUMBER && ivalue == 0)
3147 {
3148 hide_if_zero = 0;
3149 continue;
3150 }
3151 else if(type == ECMFMT_STRING && svalue == NULL)
3152 {
3153 hide_if_zero = 0;
3154 continue;
3155 }
3156 }
3157
3158 switch(type)
3159 {
3160 case ECMFMT_NUMBER:
3161 s += snprintf(result + s, size - s, ifmt, ivalue);
3162 break;
3163
3164 case ECMFMT_STRING:
3165 s += snprintf(result + s, size - s , sfmt != NULL ? sfmt : "%s", svalue);
3166 break;
3167
3168 case ECMFMT_CHAR:
3169 if(size - s > 1)
3170 {
3171 result[s] = cvalue;
3172 result[s+1] = '\0';
3173 s++;
3174 }
3175 break;
3176
3177 default:
3178 break;
3179 }
3180 }
3181
3182 return s;
3183}
3184
3185int32_t format_ecm(ECM_REQUEST *ecm, char *result, size_t size)
3186{
3187 char ecmd5hex[(16*2)+1];
3188 char csphash[(4*2)+1] = { 0 };
3189 char cwhex[(16*2)+1];
3190 char *payload = NULL;
3191 char *tier = NULL;
3192#ifdef READER_VIDEOGUARD
3193 char payload_string[(6*2)+1];
3194 char tier_string[83];
3195 struct s_ecm_answer *ea;
3196
3197 if(ecm->selected_reader && caid_is_videoguard(ecm->selected_reader->caid) && !is_network_reader(ecm->selected_reader))
3198 {
3199 for(ea = ecm->matching_rdr; ea; ea = ea->next)
3200 {
3201 if(ea->tier && (ea->status & REQUEST_ANSWERED) && !is_network_reader(ea->reader))
3202 {
3203 get_tiername_defaultid(ea->tier, ecm->selected_reader->caid, tier_string);
3204 tier = tier_string;
3205 break;
3206 }
3207 }
3208
3209 cs_hexdump(0, ecm->selected_reader->VgLastPayload, 6, payload_string, sizeof(payload_string));
3210 payload = payload_string;
3211 }
3212#endif
3213 cs_hexdump(0, ecm->ecmd5, 16, ecmd5hex, sizeof(ecmd5hex));
3214#ifdef CS_CACHEEX
3215 cs_hexdump(0, (void *)&ecm->csp_hash, 4, csphash, sizeof(csphash));
3216#endif
3217 cs_hexdump(0, ecm->cw, 16, cwhex, sizeof(cwhex));
3218#ifdef MODULE_GBOX
3219 if(check_client(ecm->client) && get_module(ecm->client)->num == R_GBOX && ecm->gbox_ecm_dist)
3220 { return ecmfmt(result, size, ecm->caid, ecm->onid, ecm->prid, ecm->chid, ecm->pid, ecm->srvid, ecm->ecmlen, ecmd5hex, csphash, cwhex, ecm->gbox_ecm_src_peer, ecm->gbox_ecm_dist, payload, tier); }
3221 else if (ecm->selected_reader && ecm->selected_reader->typ == R_GBOX && !ecm->gbox_ecm_dist)
3222 { return ecmfmt(result, size, ecm->caid, ecm->onid, ecm->prid, ecm->chid, ecm->pid, ecm->srvid, ecm->ecmlen, ecmd5hex, csphash, cwhex, ecm->selected_reader->gbox_cw_src_peer, ecm->selected_reader->currenthops, payload, tier); }
3223 else
3224#endif
3225 return ecmfmt(result, size, ecm->caid, ecm->onid, ecm->prid, ecm->chid, ecm->pid, ecm->srvid, ecm->ecmlen, ecmd5hex, csphash, cwhex, 0,
3226 ((ecm->selected_reader && ecm->selected_reader->currenthops) ? ecm->selected_reader->currenthops : 0), payload, tier);
3227}
Note: See TracBrowser for help on using the repository browser.