source: trunk/oscam-ecm.c@ 9131

Last change on this file since 9131 was 9131, checked in by theparasol, 9 years ago
  • commit 9093 reverted partly changes to preferlocalcards -> fixed!
File size: 64.6 KB
Line 
1#include "globals.h"
2#include "cscrypt/md5.h"
3#include "module-anticasc.h"
4#include "module-cacheex.h"
5#include "module-led.h"
6#include "module-stat.h"
7#include "module-webif.h"
8#include "module-ird-guess.h"
9#include "module-cw-cycle-check.h"
10#include "oscam-cache.h"
11#include "oscam-chk.h"
12#include "oscam-client.h"
13#include "oscam-config.h"
14#include "oscam-ecm.h"
15#include "oscam-garbage.h"
16#include "oscam-failban.h"
17#include "oscam-net.h"
18#include "oscam-time.h"
19#include "oscam-lock.h"
20#include "oscam-string.h"
21#include "oscam-work.h"
22#include "reader-common.h"
23
24extern CS_MUTEX_LOCK ecmcache_lock;
25extern struct ecm_request_t *ecmcwcache;
26extern uint16_t len4caid[256];
27extern uint32_t ecmcwcache_size;
28extern int32_t exit_oscam;
29
30extern CS_MUTEX_LOCK ecm_pushed_deleted_lock;
31extern struct ecm_request_t *ecm_pushed_deleted;
32
33static pthread_mutex_t cw_process_sleep_cond_mutex;
34static pthread_cond_t cw_process_sleep_cond;
35static int cw_process_wakeups;
36
37static uint32_t auto_timeout(ECM_REQUEST *er, uint32_t timeout)
38{
39 (void)er; // Prevent warning about unused er, when WITH_LB is disabled
40#ifdef WITH_LB
41 if(cfg.lb_auto_timeout)
42 { return lb_auto_timeout(er, timeout); }
43#endif
44 return timeout;
45}
46
47#ifdef CS_CACHEEX
48void cacheex_timeout(ECM_REQUEST *er)
49{
50 er->cacheex_wait_time_expired = 1;
51
52 //if check_cw_count_mode=0, first try to get cw from cache
53 if(!cfg.check_cw_count_mode)
54 {
55 struct ecm_request_t *ecm=NULL;
56 ecm = check_cache(er, er->client);
57 if(ecm) //found in cache
58 {
59 struct s_write_from_cache *wfc=NULL;
60 if(!cs_malloc(&wfc, sizeof(struct s_write_from_cache)))
61 {
62 free(ecm);
63 return;
64 }
65 wfc->er_new=er;
66 wfc->er_cache=ecm;
67
68 if(!add_job(er->client, ACTION_ECM_ANSWER_CACHE, wfc, sizeof(struct s_write_from_cache))) //write_ecm_answer_fromcache
69 { free(ecm); }
70
71 return;
72 }
73 }
74
75
76 if(er->rc >= E_UNHANDLED && er->stage < 2 && er->cacheex_wait_time)
77 {
78 cs_debug_mask(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} cacheex timeout! ", (check_client(er->client) ? er->client->account->usr : "-"), er->caid, er->prid, er->srvid);
79
80 //check if "normal" readers selected, if not send NOT FOUND!
81 if((!er->from_cacheex1_client && (er->reader_count + er->fallback_reader_count - er->cacheex_reader_count) <= 0) //not-cacheex-1 client and no normal readers avilable (or filtered by LB)
82 ||
83 (er->from_cacheex1_client && !er->reader_nocacheex_avail) //cacheex1-client and no normal readers available for others clients
84 )
85 {
86 er->rc = E_NOTFOUND;
87 er->selected_reader = NULL;
88 if(er->reader_requested > 0)
89 { er->rcEx = 0; } //not found by reader
90 else
91 { er->rcEx = E2_GROUP; } //no matching reader
92
93 cs_debug_mask(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} NO Readers... not_found! ", (check_client(er->client) ? er->client->account->usr : "-"), er->caid, er->prid, er->srvid);
94 send_dcw(er->client, er);
95 return;
96
97 }
98 else
99 {
100 debug_ecm(D_TRACE, "request for %s %s", username(er->client), buf);
101 request_cw_from_readers(er, 0);
102 }
103 }
104}
105#endif
106
107void fallback_timeout(ECM_REQUEST *er)
108{
109 if(er->rc >= E_UNHANDLED && er->stage < 4)
110 {
111 cs_debug_mask(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);
112 debug_ecm(D_TRACE, "fallback for %s %s", username(er->client), buf);
113 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.
114 {
115 request_cw_from_readers(er, 0);
116 }
117 }
118}
119
120void ecm_timeout(ECM_REQUEST *er)
121{
122 if(!er->readers_timeout_check)
123 {
124 er->readers_timeout_check = 1;
125
126 if(check_client(er->client) && er->rc >= E_UNHANDLED)
127 {
128 cs_debug_mask(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);
129 debug_ecm(D_TRACE, "timeout for %s %s", username(er->client), buf);
130 }
131
132#ifdef CS_CACHEEX
133 bool send_timeout = false;
134#endif
135
136 struct s_ecm_answer *ea_list;
137 for(ea_list = er->matching_rdr; ea_list; ea_list = ea_list->next)
138 {
139 if((ea_list->status & (REQUEST_SENT | REQUEST_ANSWERED)) == REQUEST_SENT) //Request sent, but no answer!
140 {
141 write_ecm_answer(ea_list->reader, er, E_TIMEOUT, 0, NULL, NULL); //set timeout for readers not answered!
142#ifdef CS_CACHEEX
143 send_timeout = true;
144#endif
145 }
146 }
147
148#ifdef CS_CACHEEX
149 if(er->from_cacheex1_client && !send_timeout && er->rc == E_UNHANDLED) //cacheex 1 clients waiting for INT cache by "normal" readers
150 {
151 er->rc = E_NOTFOUND;
152 er->selected_reader = NULL;
153 if(er->reader_requested > 0)
154 { er->rcEx = 0; } //not found by reader
155 else
156 { er->rcEx = E2_GROUP; } //no matching reader
157
158 cs_debug_mask(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} NO cw found in cache for cacheex-1 client... send not found! ", (check_client(er->client) ? er->client->account->usr : "-"), er->caid, er->prid, er->srvid);
159 send_dcw(er->client, er);
160 }
161#endif
162
163 }
164}
165
166void increment_n_request(struct s_client *cl){
167 if(check_client(cl)){
168 cl->n_request[1]++;
169 first_client->n_request[1]++;
170 }
171}
172
173void update_n_request(void){
174 struct s_client *cl;
175
176 cs_readlock(&clientlist_lock);
177 for(cl = first_client->next; cl; cl = cl->next)
178 {
179#ifdef CS_CACHEEX
180 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
181#else
182 if(check_client(cl) && get_module(cl)->num != R_CSP && cl->typ == 'c' && !cl->dup)
183#endif
184 {
185 cl->n_request[0]=cl->n_request[1];
186 cl->n_request[1]=0;
187 }else{
188 cl->n_request[0]=0;
189 cl->n_request[1]=0;
190 }
191 }
192
193 first_client->n_request[0]=first_client->n_request[1];
194 first_client->n_request[1]=0;
195
196 cs_readunlock(&clientlist_lock);
197}
198
199static void *cw_process(void)
200{
201 set_thread_name(__func__);
202 int32_t time_to_check_fbtimeout, time_to_check_ctimeout, next_check, ecmc_next, cache_next, n_request_next, msec_wait = 3000;
203 struct timeb t_now, tbc, ecmc_time, cache_time, n_request_time;
204 ECM_REQUEST *er = NULL;
205 time_t ecm_maxcachetime;
206
207#ifdef CS_CACHEEX
208 int32_t time_to_check_cacheex_wait_time;
209#endif
210
211 pthread_mutex_init(&cw_process_sleep_cond_mutex, NULL);
212 pthread_cond_init(&cw_process_sleep_cond, NULL);
213
214#ifdef CS_ANTICASC
215 int32_t ac_next;
216 struct timeb ac_time;
217 cs_ftime(&ac_time);
218 add_ms_to_timeb(&ac_time, cfg.ac_stime * 60 * 1000);
219#endif
220
221 cs_ftime(&ecmc_time);
222 add_ms_to_timeb(&ecmc_time, 1000);
223 cs_ftime(&cache_time);
224 add_ms_to_timeb(&cache_time, 3000);
225 cs_ftime(&n_request_time);
226 add_ms_to_timeb(&n_request_time, 60 * 1000);
227
228 while(!exit_oscam)
229 {
230 if(cw_process_wakeups == 0) // No waiting wakeups, proceed to sleep
231 {
232 sleepms_on_cond(&cw_process_sleep_cond, &cw_process_sleep_cond_mutex, msec_wait);
233 }
234 cw_process_wakeups = 0; // We've been woken up, reset the counter
235 if(exit_oscam)
236 { break; }
237
238 next_check = 0;
239#ifdef CS_ANTICASC
240 ac_next = 0;
241#endif
242 ecmc_next = 0;
243 cache_next = 0;
244 msec_wait = 0;
245
246 cs_ftime(&t_now);
247 cs_readlock(&ecmcache_lock);
248 for(er = ecmcwcache; er; er = er->next)
249 {
250
251 if(
252 (er->from_cacheex || er->from_csp) //ignore ecms from cacheex/csp
253 ||
254 er->readers_timeout_check //ignore already checked
255 ||
256 !check_client(er->client) //ignore ecm of killed clients
257 )
258 { continue; }
259
260 if(er->rc >= E_UNHANDLED)
261 {
262
263#ifdef CS_CACHEEX
264 //cacheex_wait_time
265 if(er->stage < 2 && er->cacheex_wait_time)
266 {
267 tbc = er->tps;
268 time_to_check_cacheex_wait_time = add_ms_to_timeb(&tbc, auto_timeout(er, er->cacheex_wait_time));
269 if(comp_timeb(&t_now, &tbc) >= 0)
270 {
271 add_job(er->client, ACTION_CACHEEX_TIMEOUT, (void *)er, 0);
272 time_to_check_cacheex_wait_time = 0;
273 }
274 if(!next_check || (time_to_check_cacheex_wait_time > 0 && time_to_check_cacheex_wait_time < next_check))
275 { next_check = time_to_check_cacheex_wait_time; }
276 }
277#endif
278 if(er->stage < 4)
279 {
280 //fbtimeout
281 tbc = er->tps;
282 time_to_check_fbtimeout = add_ms_to_timeb(&tbc, auto_timeout(er, get_fallbacktimeout(er->caid)));
283 if(comp_timeb(&t_now, &tbc) >= 0)
284 {
285 add_job(er->client, ACTION_FALLBACK_TIMEOUT, (void *)er, 0);
286 time_to_check_fbtimeout = 0;
287 }
288 if(!next_check || (time_to_check_fbtimeout > 0 && time_to_check_fbtimeout < next_check))
289 { next_check = time_to_check_fbtimeout; }
290 }
291 }
292
293
294 //clienttimeout
295 if(!er->readers_timeout_check) //ecm stays in cache at least ctimeout+2seconds!
296 {
297 tbc = er->tps;
298 time_to_check_ctimeout = add_ms_to_timeb(&tbc, auto_timeout(er, cfg.ctimeout));
299 if(comp_timeb(&t_now, &tbc) >= 0)
300 {
301 add_job(er->client, ACTION_CLIENT_TIMEOUT, (void *)er, 0);
302 time_to_check_ctimeout = 0;
303 }
304 if(!next_check || (time_to_check_ctimeout > 0 && time_to_check_ctimeout < next_check))
305 { next_check = time_to_check_ctimeout; }
306 }
307 }
308 cs_readunlock(&ecmcache_lock);
309#ifdef CS_ANTICASC
310 if(cfg.ac_enabled && (ac_next = comp_timeb(&ac_time, &t_now)) <= 10)
311 {
312 ac_do_stat();
313 cs_ftime(&ac_time);
314 ac_next = add_ms_to_timeb(&ac_time, cfg.ac_stime * 60 * 1000);
315 }
316#endif
317 if((ecmc_next = comp_timeb(&ecmc_time, &t_now)) <= 10)
318 {
319 uint32_t count = 0;
320 struct ecm_request_t *ecm, *ecmt = NULL, *prv;
321
322 cs_readlock(&ecmcache_lock);
323 for(ecm = ecmcwcache, prv = NULL; ecm; prv = ecm, ecm = ecm->next, count++)
324 {
325 ecm_maxcachetime = t_now.time - ((cfg.ctimeout+500)/1000+3); //to be sure no more access er!
326
327 if(ecm->tps.time < ecm_maxcachetime)
328 {
329 cs_readunlock(&ecmcache_lock);
330 cs_writelock(&ecmcache_lock);
331 ecmt = ecm;
332 if(prv)
333 { prv->next = NULL; }
334 else
335 { ecmcwcache = NULL; }
336 cs_writeunlock(&ecmcache_lock);
337 break;
338 }
339 }
340 if(!ecmt)
341 { cs_readunlock(&ecmcache_lock); }
342 ecmcwcache_size = count;
343
344 while(ecmt)
345 {
346 ecm = ecmt->next;
347 free_ecm(ecmt);
348 ecmt = ecm;
349 }
350
351#ifdef CS_CACHEEX
352 ecmt=NULL;
353 cs_readlock(&ecm_pushed_deleted_lock);
354 for(ecm = ecm_pushed_deleted, prv = NULL; ecm; prv = ecm, ecm = ecm->next)
355 {
356 ecm_maxcachetime = t_now.time - ((cfg.ctimeout+500)/1000+3);
357 if(ecm->tps.time < ecm_maxcachetime)
358 {
359 cs_readunlock(&ecm_pushed_deleted_lock);
360 cs_writelock(&ecm_pushed_deleted_lock);
361 ecmt = ecm;
362 if(prv)
363 { prv->next = NULL; }
364 else
365 { ecm_pushed_deleted = NULL; }
366 cs_writeunlock(&ecm_pushed_deleted_lock);
367 break;
368 }
369 }
370 if(!ecmt)
371 { cs_readunlock(&ecm_pushed_deleted_lock); }
372
373 while(ecmt)
374 {
375 ecm = ecmt->next;
376 free_push_in_ecm(ecmt);
377 ecmt = ecm;
378 }
379#endif
380
381 cs_ftime(&ecmc_time);
382 ecmc_next = add_ms_to_timeb(&ecmc_time, 1000);
383 }
384
385
386 if((cache_next = comp_timeb(&cache_time, &t_now)) <= 10)
387 {
388
389
390 cleanup_cache();
391#ifdef CS_CACHEEX
392 cleanup_hitcache();
393#endif
394
395 cs_ftime(&cache_time);
396 cache_next = add_ms_to_timeb(&cache_time, 3000);
397 }
398
399 if((n_request_next = comp_timeb(&n_request_time, &t_now)) <= 10)
400 {
401 update_n_request();
402 cs_ftime(&n_request_time);
403 n_request_next = add_ms_to_timeb(&n_request_time, 60 * 1000);
404 }
405
406
407 msec_wait = next_check;
408#ifdef CS_ANTICASC
409 if(!msec_wait || (ac_next > 0 && ac_next < msec_wait))
410 { msec_wait = ac_next; }
411#endif
412 if(!msec_wait || (ecmc_next > 0 && ecmc_next < msec_wait))
413 { msec_wait = ecmc_next; }
414
415 if(!msec_wait || (cache_next > 0 && cache_next < msec_wait))
416 { msec_wait = cache_next; }
417
418 if(!msec_wait || (n_request_next > 0 && n_request_next < msec_wait))
419 { msec_wait = n_request_next; }
420
421 if(!msec_wait)
422 { msec_wait = 3000; }
423
424 cleanupcwcycle();
425 }
426
427 return NULL;
428}
429
430void cw_process_thread_start(void)
431{
432 start_thread((void *) &cw_process, "cw_process");
433}
434
435void cw_process_thread_wakeup(void)
436{
437 cw_process_wakeups++; // Do not sleep...
438 pthread_cond_signal(&cw_process_sleep_cond);
439}
440
441#ifdef WITH_LB
442/**
443 * search for same ecm hash with same readers
444 **/
445struct ecm_request_t *check_same_ecm(ECM_REQUEST *er)
446{
447 struct ecm_request_t *ecm;
448 time_t timeout;
449 struct s_ecm_answer *ea_ecm = NULL, *ea_er = NULL;
450 uint8_t rdrs = 0;
451
452
453 cs_readlock(&ecmcache_lock);
454 for(ecm = ecmcwcache; ecm; ecm = ecm->next)
455 {
456 timeout = time(NULL) - ((cfg.ctimeout + 500) / 1000);
457
458 if(ecm->tps.time <= timeout)
459 { break; }
460
461 if(ecm == er) { continue; }
462
463 if(memcmp(ecm->ecmd5, er->ecmd5, CS_ECMSTORESIZE))
464 { continue; }
465
466 if(!er->readers || !ecm->readers || er->readers != ecm->readers)
467 { continue; }
468
469 ea_ecm = ecm->matching_rdr;
470 ea_er = er->matching_rdr;
471 rdrs = er->readers;
472
473 while(rdrs && ea_ecm && ea_er)
474 {
475 if(ea_ecm->reader != ea_er->reader)
476 { break; }
477 ea_ecm = ea_ecm->next;
478 ea_er = ea_er->next;
479 rdrs--;
480 }
481
482 if(!rdrs)
483 {
484 cs_readunlock(&ecmcache_lock);
485 return ecm;
486 }
487 }
488 cs_readunlock(&ecmcache_lock);
489 return NULL; // nothing found so return null
490}
491
492
493void use_same_readers(ECM_REQUEST *er_new, ECM_REQUEST *er_cache)
494{
495 struct s_ecm_answer *ea_new = er_new->matching_rdr;
496 struct s_ecm_answer *ea_cache = er_cache->matching_rdr;
497 uint8_t rdrs = er_new->readers;
498 while(rdrs)
499 {
500 ea_new->status &= ~(READER_ACTIVE | READER_FALLBACK);
501 if((ea_cache->status & READER_ACTIVE))
502 {
503 if(!(ea_cache->status & READER_FALLBACK))
504 {
505 ea_new->status |= READER_ACTIVE;
506 }
507 else
508 {
509 ea_new->status |= (READER_ACTIVE | READER_FALLBACK);
510 }
511 }
512
513 ea_new = ea_new->next;
514 ea_cache = ea_cache->next;
515 rdrs--;
516 }
517}
518
519#endif
520
521
522
523void convert_to_beta(struct s_client *cl, ECM_REQUEST *er, uint16_t caidto)
524{
525 static uint8_t headerN3[10] = {0xc7, 0x00, 0x00, 0x00, 0x01, 0x10, 0x10, 0x00, 0x87, 0x12};
526 static uint8_t headerN2[10] = {0xc9, 0x00, 0x00, 0x00, 0x01, 0x10, 0x10, 0x00, 0x48, 0x12};
527
528 er->ocaid = er->caid;
529 er->caid = caidto;
530 er->prid = 0;
531 er->ecmlen = er->ecm[2] + 3;
532
533 memmove(er->ecm + 13, er->ecm + 3, er->ecmlen - 3);
534
535 if(er->ecmlen > 0x88)
536 {
537 memcpy(er->ecm + 3, headerN3, 10);
538 if(er->ecm[0] == 0x81)
539 { er->ecm[12] += 1; }
540 er->ecm[1] = 0x70;
541 }
542 else
543 {
544 memcpy(er->ecm + 3, headerN2, 10);
545 }
546
547 er->ecmlen += 10;
548 er->ecm[2] = er->ecmlen - 3;
549 er->btun = 1;
550
551 cl->cwtun++;
552 cl->account->cwtun++;
553 first_client->cwtun++;
554
555 cs_debug_mask(D_TRACE, "ECM converted ocaid from 0x%04X to BetaCrypt caid 0x%04X for service id 0x%04X",
556 er->ocaid, caidto, er->srvid);
557}
558
559void convert_to_nagra(struct s_client *cl, ECM_REQUEST *er, uint16_t caidto)
560{
561 cs_debug_mask(D_TRACE, "convert_to_nagra");
562 er->ocaid = er->caid;
563 er->caid = caidto;
564 er->prid = 0;
565 er->ecmlen = er->ecm[2] + 3;
566
567 //not sure
568 if(er->ecmlen < 0x52)
569 { er->ecm[1] = 0x30; }
570
571 memmove(er->ecm + 3, er->ecm + 13, er->ecmlen - 3);
572
573 er->ecmlen -= 10;
574 er->ecm[2] = er->ecmlen - 3;
575 er->btun = 1;
576
577 cl->cwtun++;
578 cl->account->cwtun++;
579 first_client->cwtun++;
580
581 cs_debug_mask(D_TRACE, "ECM converted ocaid from: 0x%04X to Nagra: 0x04%X for service id:0x04%X",
582 er->ocaid, caidto, er->srvid);
583}
584
585void cs_betatunnel(ECM_REQUEST *er)
586{
587 int32_t n;
588 struct s_client *cl = cur_client();
589 uint32_t mask_all = 0xFFFF;
590
591 TUNTAB *ttab;
592 ttab = &cl->ttab;
593
594 for(n = 0; n < ttab->n; n++)
595 {
596 if((er->caid == ttab->bt_caidfrom[n]) && ((er->srvid == ttab->bt_srvid[n]) || (ttab->bt_srvid[n]) == mask_all))
597 {
598 if(chk_is_betatunnel_caid(er->caid) == 1 && er->ocaid == 0x0000)
599 {
600 convert_to_nagra(cl, er, ttab->bt_caidto[n]);
601 }
602 else if(er->ocaid == 0x0000)
603 {
604 convert_to_beta(cl, er, ttab->bt_caidto[n]);
605 }
606 return;
607 }
608 }
609}
610
611static void remove_ecm_from_reader(ECM_REQUEST *ecm)
612{
613 int32_t i;
614 struct s_ecm_answer *ea = ecm->matching_rdr;
615 while(ea)
616 {
617 if((ea->status & REQUEST_SENT) && !(ea->status & REQUEST_ANSWERED))
618 {
619 //we found a outstanding reader, clean it:
620 struct s_reader *rdr = ea->reader;
621 if(rdr)
622 {
623 struct s_client *cl = rdr->client;
624 if(check_client(cl))
625 {
626 ECM_REQUEST *ecmtask = cl->ecmtask;
627 if(ecmtask)
628 {
629 for(i = 0; i < cfg.max_pending; ++i)
630 {
631 if(ecmtask[i].parent == ecm)
632 {
633 ecmtask[i].client = NULL;
634 cacheex_set_csp_lastnode(&ecmtask[i]);
635 }
636 }
637 }
638 }
639 }
640 }
641 ea = ea->next;
642 }
643}
644
645void free_ecm(ECM_REQUEST *ecm)
646{
647 struct s_ecm_answer *ea, *nxt;
648 cacheex_free_csp_lastnodes(ecm);
649 //remove this ecm from reader queue to avoid segfault on very late answers (when ecm is already disposed)
650 //first check for outstanding answers:
651 remove_ecm_from_reader(ecm);
652 //free matching_rdr list:
653 ea = ecm->matching_rdr;
654 ecm->matching_rdr = NULL;
655 while(ea)
656 {
657 nxt = ea->next;
658 cs_lock_destroy(&ea->ecmanswer_lock);
659 add_garbage(ea);
660 ea = nxt;
661 }
662 if(ecm->src_data)
663 { add_garbage(ecm->src_data); }
664 add_garbage(ecm);
665}
666
667
668void free_push_in_ecm(ECM_REQUEST *ecm)
669{
670 cacheex_free_csp_lastnodes(ecm);
671 if(ecm->src_data)
672 { free(ecm->src_data); }
673 free(ecm);
674}
675
676
677ECM_REQUEST *get_ecmtask(void)
678{
679 ECM_REQUEST *er = NULL;
680 struct s_client *cl = cur_client();
681 if(!cl)
682 { return NULL; }
683 if(!cs_malloc(&er, sizeof(ECM_REQUEST)))
684 { return NULL; }
685 cs_ftime(&er->tps);
686
687#ifdef CS_CACHEEX
688 er->cacheex_wait.time = er->tps.time;
689 er->cacheex_wait.millitm = er->tps.millitm;
690 er->cacheex_wait_time = 0;
691#endif
692#ifdef MODULE_GBOX
693 er->gbox_ecm_id = 0;
694 er->gbox_hops = 0;
695#endif
696 er->rc = E_UNHANDLED;
697 er->client = cl;
698 er->grp = 0; //no readers/cacheex-clients answers yet
699 //cs_log("client %s ECMTASK %d module %s", username(cl), n, get_module(cl)->desc);
700 return er;
701}
702
703void cleanup_ecmtasks(struct s_client *cl)
704{
705 if(cl && cl->account && !cl->account->usr[0]) { return; } //not for anonymous users!
706
707 ECM_REQUEST *ecm;
708
709 //remove this clients ecm from queue. because of cache, just null the client:
710 cs_readlock(&ecmcache_lock);
711 for(ecm = ecmcwcache; ecm; ecm = ecm->next)
712 {
713 if(ecm->client == cl)
714 {
715 ecm->client = NULL;
716 }
717 }
718 cs_readunlock(&ecmcache_lock);
719
720 //remove client from rdr ecm-queue:
721 cs_readlock(&readerlist_lock);
722 struct s_reader *rdr = first_active_reader;
723 while(rdr)
724 {
725 if(check_client(rdr->client) && rdr->client->ecmtask)
726 {
727 int i;
728 for(i = 0; i < cfg.max_pending; i++)
729 {
730 ecm = &rdr->client->ecmtask[i];
731 if(ecm->client == cl)
732 {
733 ecm->client = NULL;
734 }
735 }
736 }
737 rdr = rdr->next;
738 }
739 cs_readunlock(&readerlist_lock);
740
741}
742
743
744static void add_cascade_data(struct s_client *client, ECM_REQUEST *er)
745{
746 if(!client->cascadeusers)
747 { client->cascadeusers = ll_create("cascade_data"); }
748 LLIST *l = client->cascadeusers;
749 LL_ITER it = ll_iter_create(l);
750 time_t now = time(NULL);
751 struct s_cascadeuser *cu;
752 int8_t found = 0;
753 while((cu = ll_iter_next(&it)))
754 {
755 if(er->caid == cu->caid && er->prid == cu->prid && er->srvid == cu->srvid) //found it
756 {
757 if(cu->time < now)
758 { cu->cwrate = now - cu->time; }
759 cu->time = now;
760 found = 1;
761 }
762 else if(cu->time + 60 < now) // old
763 { ll_iter_remove_data(&it); }
764 }
765 if(!found) //add it if not found
766 {
767 if(!cs_malloc(&cu, sizeof(struct s_cascadeuser)))
768 { return; }
769 cu->caid = er->caid;
770 cu->prid = er->prid;
771 cu->srvid = er->srvid;
772 cu->time = now;
773 ll_append(l, cu);
774 }
775}
776
777static int32_t is_double_check_caid(ECM_REQUEST *er)
778{
779 if(!cfg.double_check_caid.caid[0]) //no caids defined: Check all
780 { return 1; }
781 int32_t i;
782 for(i = 0; i < CS_MAXCAIDTAB; i++)
783 {
784 uint16_t tcaid = cfg.double_check_caid.caid[i];
785 if(!tcaid)
786 { break; }
787 if(tcaid == er->caid || (tcaid < 0x0100 && (er->caid >> 8) == tcaid))
788 {
789 return 1;
790 }
791 }
792 return 0;
793}
794
795struct s_ecm_answer *get_ecm_answer(struct s_reader *reader, ECM_REQUEST *er)
796{
797 if(!er || !reader) { return NULL; }
798
799 struct s_ecm_answer *ea;
800
801 for(ea = er->matching_rdr; ea; ea = ea->next)
802 {
803 if(ea->reader == reader)
804 {
805 return ea;
806 }
807 }
808 return NULL;
809}
810
811
812void distribute_ea(struct s_ecm_answer *ea)
813{
814
815 struct s_ecm_answer *ea_temp;
816
817 for(ea_temp = ea->pending; ea_temp; ea_temp = ea_temp->pending_next)
818 {
819 cs_debug_mask(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 : "-"));
820
821 //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!
822 write_ecm_answer(ea_temp->reader, ea_temp->er, (ea->rc==E_FOUND? E_FOUND : E_NOTFOUND), ea->rcEx, ea->cw, NULL);
823 }
824}
825
826
827int32_t send_dcw(struct s_client *client, ECM_REQUEST *er)
828{
829 if(!check_client(client) || client->typ != 'c')
830 { return 0; }
831
832 cs_debug_mask(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 : "-");
833
834 static const char stageTxt[] = {'0', 'C', 'L', 'P', 'F', 'X'};
835 static const char *stxt[] = {"found", "cache1", "cache2", "cache3",
836 "not found", "timeout", "sleeping",
837 "fake", "invalid", "corrupt", "no card", "expdate", "disabled", "stopped"
838 };
839 static const char *stxtEx[16] = {"", "group", "caid", "ident", "class", "chid", "queue", "peer", "sid", "", "", "", "", "", "", ""};
840 static const char *stxtWh[16] = {"", "user ", "reader ", "server ", "lserver ", "", "", "", "", "", "", "", "" , "" , "", ""};
841 char sby[100] = "", sreason[32] = "", scwcinfo[32] = "", schaninfo[32] = "";
842 char erEx[32] = "";
843 char uname[38] = "";
844 char channame[32];
845 struct timeb tpe;
846
847 snprintf(uname, sizeof(uname) - 1, "%s", username(client));
848
849#ifdef WITH_DEBUG
850 if(cs_dblevel & D_CLIENTECM)
851 {
852 char buf[ECM_FMT_LEN];
853 char ecmd5[17 * 3];
854 char cwstr[17 * 3];
855 format_ecm(er, buf, ECM_FMT_LEN);
856 cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5));
857 cs_hexdump(0, er->cw, 16, cwstr, sizeof(cwstr));
858#ifdef CS_CACHEEX
859 char csphash[5 * 3];
860 cs_hexdump(0, (void *)&er->csp_hash, 4, csphash, sizeof(csphash));
861 cs_debug_mask(D_CLIENTECM, "Client %s csphash %s cw %s rc %d %s", username(client), csphash, cwstr, er->rc, buf);
862#else
863 cs_debug_mask(D_CLIENTECM, "Client %s cw %s rc %d %s", username(client), cwstr, er->rc, buf);
864#endif
865 }
866#endif
867
868 struct s_reader *er_reader = er->selected_reader; //responding reader
869 struct s_ecm_answer *ea_orig = get_ecm_answer(er_reader, er);
870
871 //check if ecm_answer from pending's
872 if(ea_orig && ea_orig->is_pending && er->rc == E_FOUND)
873 { er->rc = E_CACHE2; }
874
875 //check if answer from cacheex-1 reader
876 if(er->rc == E_FOUND && er_reader && cacheex_reader(er_reader)) //so add hit to cacheex mode 1 readers
877 {
878 er->rc = E_CACHEEX;
879 }
880
881 if(er->rc == E_TIMEOUT)
882 {
883 struct s_ecm_answer *ea_list;
884 int32_t ofs = 0;
885 for(ea_list = er->matching_rdr; ea_list; ea_list = ea_list->next)
886 {
887 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!
888 {
889 ofs += snprintf(sby + ofs, sizeof(sby) - ofs - 1, "%s%s", ofs ? "," : " by ", ea_list->reader->label);
890 }
891 }
892 if(er->ocaid && ofs < (int32_t)sizeof(sby))
893 { ofs += snprintf(sby + ofs, sizeof(sby) - ofs - 1, "(btun %04X)", er->ocaid); }
894 }
895 else if(er_reader)
896 {
897 // add marker to reader if ECM_REQUEST was betatunneled
898 if(er->ocaid)
899 { snprintf(sby, sizeof(sby) - 1, " by %s(btun %04X)", er_reader->label, er->ocaid); }
900 else
901 { snprintf(sby, sizeof(sby) - 1, " by %s", er_reader->label); }
902 }
903#ifdef CS_CACHEEX
904 else if(er->cacheex_src) //only for cacheex mode-3 clients (no mode-1 or mode-2 because reader is set!) and csp
905 {
906 char *cex_name = "-";
907 if(check_client(er->cacheex_src) && er->cacheex_src->account){
908 if(er->cacheex_src->account->usr[0] != '\0')
909 cex_name = er->cacheex_src->account->usr;
910 else
911 cex_name = "csp";
912 }
913
914 if(er->ocaid){
915 snprintf(sby, sizeof(sby) - 1, " by %s(btun %04X)", cex_name, er->ocaid);
916 }else{
917 snprintf(sby, sizeof(sby) - 1, " by %s", cex_name);
918 }
919 }
920#endif
921
922 if(er->rc < E_NOTFOUND)
923 { er->rcEx = 0; }
924
925 if(er->rcEx)
926 { snprintf(erEx, sizeof(erEx) - 1, "rejected %s%s", stxtWh[er->rcEx >> 4], stxtEx[er->rcEx & 0xf]); }
927
928 get_servicename_or_null(client, er->srvid, er->caid, channame);
929 if(!channame[0])
930 { schaninfo[0] = '\0'; }
931 else
932 { snprintf(schaninfo, sizeof(schaninfo) - 1, " - %s", channame); }
933
934 if(er->msglog[0])
935 { snprintf(sreason, sizeof(sreason) - 1, " (%s)", er->msglog); }
936#ifdef CW_CYCLE_CHECK
937 if(er->cwc_msg_log[0])
938 { snprintf(scwcinfo, sizeof(scwcinfo) - 1, " (%s)", er->cwc_msg_log); }
939#endif
940
941 cs_ftime(&tpe);
942
943#ifdef CS_CACHEEX
944 if(er->cacheex_wait_time && er->rc != E_TIMEOUT)
945 {
946 if(er->rc >= E_CACHEEX)
947 {
948 uint32_t ntime = comp_timeb(&tpe, &er->tps);
949 if(ntime >= er->cacheex_wait_time)
950 {
951 snprintf(sreason, sizeof(sreason) - 1, " (wait_time over)");
952 }
953 }
954 else if(er->rc == E_FOUND)
955 {
956 if(ea_orig) { snprintf(sreason, sizeof(sreason) - 1, " (real %d ms)", ea_orig->ecm_time); }
957 }
958 }
959#endif
960
961 client->cwlastresptime = 1000 * (tpe.time - er->tps.time) + tpe.millitm - er->tps.millitm;
962
963 time_t now = time(NULL);
964 webif_client_add_lastresponsetime(client, client->cwlastresptime, now, er->rc); // add to ringbuffer
965
966 if(er_reader)
967 {
968 struct s_client *er_cl = er_reader->client;
969 if(check_client(er_cl))
970 {
971 er_cl->cwlastresptime = client->cwlastresptime;
972 webif_client_add_lastresponsetime(er_cl, client->cwlastresptime, now, er->rc);
973 er_cl->last_srvidptr = client->last_srvidptr;
974 }
975 }
976
977 webif_client_init_lastreader(client, er, er_reader, stxt);
978
979 client->last = now;
980
981 //cs_debug_mask(D_TRACE, "CHECK rc=%d er->cacheex_src=%s", er->rc, username(er->cacheex_src));
982 switch(er->rc)
983 {
984 case E_FOUND:
985 {
986 client->cwfound++;
987 client->account->cwfound++;
988 first_client->cwfound++;
989 break;
990 }
991 case E_CACHE1:
992 case E_CACHE2:
993 case E_CACHEEX:
994 {
995 client->cwcache++;
996 client->account->cwcache++;
997 first_client->cwcache++;
998#ifdef CS_CACHEEX
999 if(check_client(er->cacheex_src))
1000 {
1001 er->cacheex_src->cwcacheexhit++;
1002 if(er->cacheex_src->account)
1003 { er->cacheex_src->account->cwcacheexhit++; }
1004 }
1005 first_client->cwcacheexhit++;
1006#endif
1007 break;
1008 }
1009 case E_NOTFOUND:
1010 case E_CORRUPT:
1011 case E_NOCARD:
1012 {
1013 if(er->rcEx)
1014 {
1015 client->cwignored++;
1016 client->account->cwignored++;
1017 first_client->cwignored++;
1018 }
1019 else
1020 {
1021 client->cwnot++;
1022 client->account->cwnot++;
1023 first_client->cwnot++;
1024 }
1025 break;
1026 }
1027 case E_TIMEOUT:
1028 {
1029 client->cwtout++;
1030 client->account->cwtout++;
1031 first_client->cwtout++;
1032 break;
1033 }
1034 default:
1035 {
1036 client->cwignored++;
1037 client->account->cwignored++;
1038 first_client->cwignored++;
1039 }
1040 }
1041
1042
1043 ac_chk(client, er, 1);
1044 int32_t is_fake = 0;
1045 if(er->rc == E_FAKE)
1046 {
1047 is_fake = 1;
1048 er->rc = E_FOUND;
1049 }
1050
1051 if (er->caid >> 8 == 0x09 && er->cw && er->rc < E_NOTFOUND){
1052 if (er->ecm[0] == 0x80 && checkCWpart(er->cw, 1) && !checkCWpart(er->cw, 0)){ // wrong: even ecm should only have even part of cw used
1053 cs_debug_mask(D_TRACE,"NDS videoguard controlword swapped");
1054 memcpy(er->cw, er->cw + 8, 8); // move card cw answer to right part!
1055 memset(er->cw+8,0,8); // blanc old position
1056 }
1057
1058 if (er->ecm[0] == 0x81 && checkCWpart(er->cw, 0) && !checkCWpart(er->cw, 1)){ // wrong: odd ecm should only have odd part of cw used
1059 cs_debug_mask(D_TRACE,"NDS videoguard controlword swapped");
1060 memcpy(er->cw+8, er->cw, 8); // move card cw answer to right part!
1061 memset(er->cw,0,8); // blanc old position
1062 }
1063 }
1064
1065 if(cfg.double_check && er->rc == E_FOUND && er->selected_reader && is_double_check_caid(er))
1066 {
1067 if(er->checked == 0) //First CW, save it and wait for next one
1068 {
1069 er->checked = 1;
1070 er->origin_reader = er->selected_reader;
1071 memcpy(er->cw_checked, er->cw, sizeof(er->cw));
1072 cs_log("DOUBLE CHECK FIRST CW by %s idx %d cpti %d", er->origin_reader->label, er->idx, er->msgid);
1073 }
1074 else if(er->origin_reader != er->selected_reader) //Second (or third and so on) cw. We have to compare
1075 {
1076 if(memcmp(er->cw_checked, er->cw, sizeof(er->cw)) == 0)
1077 {
1078 er->checked++;
1079 cs_log("DOUBLE CHECKED! %d. CW by %s idx %d cpti %d", er->checked, er->selected_reader->label, er->idx, er->msgid);
1080 }
1081 else
1082 {
1083 cs_log("DOUBLE CHECKED NONMATCHING! %d. CW by %s idx %d cpti %d", er->checked, er->selected_reader->label, er->idx, er->msgid);
1084 }
1085 }
1086 if(er->checked < 2) //less as two same cw? mark as pending!
1087 {
1088 er->rc = E_UNHANDLED;
1089 goto ESC;
1090 }
1091 }
1092
1093 get_module(client)->send_dcw(client, er);
1094
1095 add_cascade_data(client, er);
1096
1097 if(is_fake)
1098 { er->rc = E_FAKE; }
1099
1100 if(!(er->rc == E_SLEEPING && client->cwlastresptime == 0))
1101 {
1102 char buf[ECM_FMT_LEN];
1103 format_ecm(er, buf, ECM_FMT_LEN);
1104 if(er->reader_avail == 1 || er->stage == 0)
1105 {
1106 cs_log("%s (%s): %s (%d ms)%s%s%s%s",
1107 uname, buf,
1108 er->rcEx ? erEx : stxt[er->rc], client->cwlastresptime, sby, schaninfo, sreason, scwcinfo);
1109 }
1110 else
1111 {
1112 cs_log("%s (%s): %s (%d ms)%s (%c/%d/%d/%d)%s%s%s",
1113 uname, buf,
1114 er->rcEx ? erEx : stxt[er->rc],
1115 client->cwlastresptime, sby,
1116 stageTxt[er->stage], er->reader_requested, (er->reader_count + er->fallback_reader_count), er->reader_avail,
1117 schaninfo, sreason, scwcinfo);
1118 }
1119 }
1120
1121 cs_ddump_mask(D_ATR, er->cw, 16, "cw:");
1122 led_status_cw_not_found(er);
1123
1124ESC:
1125
1126 return 0;
1127}
1128
1129/*
1130 * write_ecm_request():
1131 */
1132static int32_t write_ecm_request(struct s_reader *rdr, ECM_REQUEST *er)
1133{
1134 add_job(rdr->client, ACTION_READER_ECM_REQUEST, (void *)er, 0);
1135 return 1;
1136}
1137
1138
1139/**
1140 * sends the ecm request to the readers
1141 * ECM_REQUEST er : the ecm
1142 * er->stage: 0 = no reader asked yet
1143 * 2 = ask only local reader (skipped without preferlocalcards)
1144 * 3 = ask any non fallback reader
1145 * 4 = ask fallback reader
1146 **/
1147void request_cw_from_readers(ECM_REQUEST *er, uint8_t stop_stage)
1148{
1149 struct s_ecm_answer *ea;
1150 int8_t sent = 0;
1151
1152 if(er->stage >= 4) { return; }
1153
1154 while(1)
1155 {
1156 if(stop_stage && er->stage >= stop_stage) { return; }
1157
1158 er->stage++;
1159
1160#ifndef CS_CACHEEX
1161 if(er->stage == 1)
1162 { er->stage++; }
1163#endif
1164 if(er->stage == 2 && !cfg.preferlocalcards)
1165 { er->stage++; }
1166
1167 for(ea = er->matching_rdr; ea; ea = ea->next)
1168 {
1169 switch(er->stage)
1170 {
1171#ifdef CS_CACHEEX
1172 case 1:
1173 {
1174 // Cache-Exchange
1175 if((ea->status & REQUEST_SENT) ||
1176 (ea->status & (READER_CACHEEX | READER_ACTIVE)) != (READER_CACHEEX | READER_ACTIVE) || cfg.preferlocalcards==2)
1177 { continue; }
1178 break;
1179 }
1180#endif
1181 case 2:
1182 {
1183 // only local reader
1184 if((ea->status & REQUEST_SENT) ||
1185 (ea->status & (READER_ACTIVE | READER_FALLBACK | READER_LOCAL)) != (READER_ACTIVE | READER_LOCAL))
1186 { continue; }
1187 break;
1188 }
1189 case 3:
1190 {
1191 // any non fallback reader not asked yet
1192 if((ea->status & REQUEST_SENT) ||
1193 (ea->status & (READER_ACTIVE | READER_FALLBACK)) != READER_ACTIVE)
1194 { continue; }
1195 break;
1196 }
1197 default:
1198 {
1199 // only fallbacks
1200 if((ea->status & REQUEST_SENT) ||
1201 (ea->status & (READER_ACTIVE | READER_FALLBACK)) != (READER_ACTIVE | READER_FALLBACK))
1202 { continue; }
1203 break;
1204 }
1205 }
1206
1207 struct s_reader *rdr = ea->reader;
1208 char ecmd5[17 * 3];
1209 cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5));
1210 cs_debug_mask(D_TRACE | D_CSP, "request_cw stage=%d to reader %s ecm hash=%s", er->stage, rdr ? rdr->label : "", ecmd5);
1211
1212 ea->status |= REQUEST_SENT;
1213 cs_ftime(&ea->time_request_sent);
1214
1215 er->reader_requested++;
1216
1217 write_ecm_request(ea->reader, er);
1218
1219 //set sent=1 only if reader is active/connected. If not, switch to next stage!
1220 if(!sent && rdr)
1221 {
1222 struct s_client *rcl = rdr->client;
1223 if(check_client(rcl))
1224 {
1225 if(rcl->typ == 'r' && rdr->card_status == CARD_INSERTED)
1226 { sent = 1; }
1227 else if(rcl->typ == 'p' && (rdr->card_status == CARD_INSERTED || rdr->tcp_connected))
1228 { sent = 1; }
1229 }
1230 }
1231
1232 cs_debug_mask(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);
1233 }
1234 if(sent || er->stage >= 4)
1235 { break; }
1236 }
1237}
1238
1239
1240void add_cache_from_reader(struct s_reader *rdr, int32_t csp_hash, uchar *ecmd5, uchar *cw, int16_t caid, int32_t prid, int16_t srvid ){
1241 ECM_REQUEST *ecm;
1242 if (cs_malloc(&ecm, sizeof(ECM_REQUEST))){
1243 cs_ftime(&ecm->tps);
1244
1245 ecm->caid = caid;
1246 ecm->prid = prid;
1247 ecm->srvid = srvid;
1248 memcpy(ecm->ecmd5, ecmd5, CS_ECMSTORESIZE);
1249 ecm->csp_hash = csp_hash;
1250 ecm->rc = E_FOUND;
1251 memcpy(ecm->cw, cw, sizeof(ecm->cw));
1252 ecm->grp = rdr->grp;
1253 ecm->selected_reader = rdr;
1254#ifdef CS_CACHEEX
1255 if(rdr && cacheex_reader(rdr))
1256 { ecm->cacheex_src = rdr->client; } //so adds hits to reader
1257#endif
1258
1259 add_cache(ecm); //add cw to cache
1260
1261#ifdef CS_CACHEEX
1262 cs_writelock(&ecm_pushed_deleted_lock);
1263 ecm->next = ecm_pushed_deleted;
1264 ecm_pushed_deleted = ecm;
1265 cs_writeunlock(&ecm_pushed_deleted_lock);
1266#else
1267 free(ecm);
1268#endif
1269 }
1270}
1271
1272
1273void chk_dcw(struct s_ecm_answer *ea)
1274{
1275 if(!ea || !ea->er)
1276 { return; }
1277
1278 ECM_REQUEST *ert = ea->er;
1279 struct s_ecm_answer *ea_list;
1280 struct s_reader *eardr = ea->reader;
1281 if(!ert)
1282 { return; }
1283
1284 //ecm request already answered!
1285 if(ert->rc < E_99)
1286 {
1287#ifdef CS_CACHEEX
1288 if(ea && ert->rc < E_NOTFOUND && ea->rc < E_NOTFOUND && memcmp(ea->cw, ert->cw, sizeof(ert->cw)) != 0)
1289 {
1290 char cw1[16 * 3 + 2], cw2[16 * 3 + 2];
1291 cs_hexdump(0, ea->cw, 16, cw1, sizeof(cw1));
1292 cs_hexdump(0, ert->cw, 16, cw2, sizeof(cw2));
1293
1294 char ip1[20] = "", ip2[20] = "";
1295 if(ea->reader && check_client(ea->reader->client)) { cs_strncpy(ip1, cs_inet_ntoa(ea->reader->client->ip), sizeof(ip1)); }
1296 if(ert->cacheex_src) { cs_strncpy(ip2, cs_inet_ntoa(ert->cacheex_src->ip), sizeof(ip2)); }
1297 else if(ert->selected_reader && check_client(ert->selected_reader->client)) { cs_strncpy(ip2, cs_inet_ntoa(ert->selected_reader->client->ip), sizeof(ip2)); }
1298
1299 ECM_REQUEST *er = ert;
1300 debug_ecm(D_TRACE, "WARNING2: Different CWs %s from %s(%s)<>%s(%s): %s<>%s", buf,
1301 username(ea->reader ? ea->reader->client : ert->client), ip1,
1302 er->cacheex_src ? username(er->cacheex_src) : (ea->reader ? ea->reader->label : "unknown/csp"), ip2,
1303 cw1, cw2);
1304 }
1305#endif
1306
1307 //answer too late, only cache update
1308 if(ea && ea->rc < E_NOTFOUND)
1309 {
1310 add_cache_from_reader(eardr, ert->csp_hash, ert->ecmd5, ea->cw, ert->caid, ert->prid, ert->srvid );
1311 }
1312
1313 }
1314
1315 if(ert->rc < E_99) { return; } // //ecm request already send to client!
1316
1317 int32_t reader_left = 0, local_left = 0, reader_not_flb_left = 0, has_not_fallback = 0, has_local = 0;
1318#ifdef CS_CACHEEX
1319 int8_t cacheex_left = 0;
1320 uint8_t has_cacheex = 0;
1321#endif
1322
1323 ert->selected_reader = eardr;
1324
1325 switch(ea->rc)
1326 {
1327 case E_FOUND:
1328 memcpy(ert->cw, ea->cw, 16);
1329 ert->rcEx = 0;
1330 ert->rc = ea->rc;
1331 ert->grp |= eardr->grp;
1332#ifdef CS_CACHEEX
1333 if(eardr && cacheex_reader(eardr))
1334 {
1335 ert->cacheex_src = eardr->client; //so adds hits to reader
1336 }
1337#endif
1338 break;
1339 case E_TIMEOUT: // if timeout, no one reader answered in ctimeout, so send timeout to client!
1340 ert->rc = E_TIMEOUT;
1341 ert->rcEx = 0;
1342 break;
1343 case E_NOTFOUND:
1344 {
1345
1346#ifdef CS_CACHEEX
1347 /* if not wait_time expired and wait_time due to hitcache, or ecm is cacheex-1 and there are other normal readers for check INT cache, we have to wait wait_time expires before send rc to client!
1348 * (Before cacheex_wait_time_expired, this answered reader is obviously a cacheex mode 1 reader!)
1349 */
1350 if((!ert->cacheex_wait_time_expired && ert->cacheex_hitcache) || (ert->from_cacheex1_client && ert->reader_nocacheex_avail))
1351 { return; }
1352#endif
1353
1354 //check if there are other readers to ask, and if not send NOT_FOUND to client
1355 ert->rcEx = ea->rcEx;
1356 cs_strncpy(ert->msglog, ea->msglog, sizeof(ert->msglog));
1357
1358 for(ea_list = ert->matching_rdr; ea_list; ea_list = ea_list->next)
1359 {
1360 cs_readlock(&ea_list->ecmanswer_lock);
1361
1362#ifdef CS_CACHEEX
1363 if(((ea_list->status & (READER_CACHEEX | READER_FALLBACK | READER_ACTIVE))) == (READER_CACHEEX | READER_ACTIVE))
1364 { has_cacheex = 1; }
1365 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)
1366 { cacheex_left++; }
1367#endif
1368 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)
1369 { local_left++; }
1370
1371 if((!(ea_list->status & READER_FALLBACK) && ((ea_list->status & (REQUEST_SENT | REQUEST_ANSWERED | READER_ACTIVE)) == (REQUEST_SENT | READER_ACTIVE))) || ea_list->rc < E_NOTFOUND)
1372 { reader_not_flb_left++; }
1373
1374 if(((ea_list->status & (REQUEST_ANSWERED | READER_ACTIVE)) == (READER_ACTIVE)) || ea_list->rc < E_NOTFOUND)
1375 { reader_left++; }
1376
1377 if(((ea_list->status & (READER_FALLBACK | READER_ACTIVE))) == (READER_ACTIVE))
1378 { has_not_fallback = 1; }
1379 if(((ea_list->status & (READER_LOCAL | READER_FALLBACK | READER_ACTIVE))) == (READER_LOCAL | READER_ACTIVE))
1380 { has_local = 1; }
1381
1382 cs_readunlock(&ea_list->ecmanswer_lock);
1383 }
1384
1385 switch(ert->stage)
1386 {
1387#ifdef CS_CACHEEX
1388 case 1: // Cache-Exchange
1389 {
1390 if(has_cacheex && !cacheex_left) { request_cw_from_readers(ert, 0); }
1391 break;
1392 }
1393#endif
1394 case 2: // only local reader (used only if cfg.preferlocalcards=1)
1395 {
1396 if(has_local && !local_left) { request_cw_from_readers(ert, 0); }
1397 break;
1398 }
1399 case 3:
1400 {
1401 // any fallback reader not asked yet
1402 if(has_not_fallback && !reader_not_flb_left) { request_cw_from_readers(ert, 0); }
1403 break;
1404 }
1405 }
1406
1407 if(!reader_left) // no more matching reader
1408 { ert->rc = E_NOTFOUND; } //so we set the return code
1409
1410 break;
1411 }
1412 default:
1413 cs_log("unexpected ecm answer rc=%d.", ea->rc);
1414 return;
1415 break;
1416 }
1417
1418 if(ert->rc < E_99)
1419 {
1420 if(ert->rc==E_FOUND)
1421 {
1422 add_cache_from_reader(eardr, ert->csp_hash, ert->ecmd5, ea->cw, ert->caid, ert->prid, ert->srvid );
1423#ifdef CS_CACHEEX
1424 if(ert->cacheex_src && cfg.check_cw_count>1) //if answer form cacheex reader, and we have to check cw count, not send answer to client
1425 { return; }
1426#endif
1427 }
1428 send_dcw(ert->client, ert);
1429 }
1430}
1431
1432uint32_t chk_provid(uint8_t *ecm, uint16_t caid)
1433{
1434 int32_t i, len, descriptor_length = 0;
1435 uint32_t provid = 0;
1436
1437 switch(caid >> 8)
1438 {
1439 case 0x01:
1440 // seca
1441 provid = b2i(2, ecm + 3);
1442 break;
1443 case 0x05:
1444 // viaccess
1445 i = (ecm[4] == 0xD2) ? ecm[5] + 2 : 0; // skip d2 nano
1446 if((ecm[5 + i] == 3) && ((ecm[4 + i] == 0x90) || (ecm[4 + i] == 0x40)))
1447 { provid = (b2i(3, ecm + 6 + i) & 0xFFFFF0); }
1448
1449 i = (ecm[6] == 0xD2) ? ecm[7] + 2 : 0; // skip d2 nano long ecm
1450 if((ecm[7 + i] == 7) && ((ecm[6 + i] == 0x90) || (ecm[6 + i] == 0x40)))
1451 { provid = (b2i(3, ecm + 8 + i) & 0xFFFFF0); }
1452
1453 break;
1454 case 0x0D:
1455 // cryptoworks
1456 len = (((ecm[1] & 0xf) << 8) | ecm[2]) + 3;
1457 for(i = 8; i < len; i += descriptor_length + 2)
1458 {
1459 descriptor_length = ecm[i + 1];
1460 if(ecm[i] == 0x83)
1461 {
1462 provid = (uint32_t)ecm[i + 2] & 0xFE;
1463 break;
1464 }
1465 }
1466 break;
1467#ifdef WITH_LB
1468 default:
1469 for(i = 0; i < CS_MAXCAIDTAB; i++)
1470 {
1471 uint16_t tcaid = cfg.lb_noproviderforcaid.caid[i];
1472 if(!tcaid) { break; }
1473 if(tcaid == caid)
1474 {
1475 provid = 0;
1476 break;
1477 }
1478 if(tcaid < 0x0100 && (caid >> 8) == tcaid)
1479 {
1480 provid = 0;
1481 break;
1482 }
1483 }
1484#endif
1485 }
1486 return provid;
1487}
1488
1489void update_chid(ECM_REQUEST *er)
1490{
1491 er->chid = get_subid(er);
1492}
1493
1494
1495int32_t write_ecm_answer(struct s_reader *reader, ECM_REQUEST *er, int8_t rc, uint8_t rcEx, uint8_t *cw, char *msglog)
1496{
1497 if(!reader || !er || !er->tps.time) { return 0; }
1498
1499 // drop too late answers, to avoid seg fault --> only answer until tps.time+((cfg.ctimeout+500)/1000+1) is accepted
1500 time_t timeout = time(NULL) - ((cfg.ctimeout+500)/1000+1);
1501 if(er->tps.time < timeout) //< and NOT <=
1502 { return 0; }
1503
1504 int32_t i;
1505 uint8_t c;
1506 struct timeb now;
1507 cs_ftime(&now);
1508
1509 if(er && er->parent)
1510 {
1511 // parent is only set on reader->client->ecmtask[], but we want original er
1512 ECM_REQUEST *er_reader_cp = er;
1513 er = er->parent; //Now er is "original" ecm, before it was the reader-copy
1514 er_reader_cp->rc = rc;
1515 er_reader_cp->idx = 0;
1516
1517 timeout = time(NULL) - ((cfg.ctimeout+500)/1000+1);
1518 if(er->tps.time < timeout)
1519 { return 0; }
1520 }
1521
1522 struct s_ecm_answer *ea = get_ecm_answer(reader, er);
1523 if(!ea) { return 0; }
1524
1525 cs_writelock(&ea->ecmanswer_lock);
1526
1527 if((ea->status & REQUEST_ANSWERED))
1528 {
1529 cs_debug_mask(D_READER, "Reader %s already answer, skip this ecm answer!", reader ? reader->label : "-");
1530 cs_writeunlock(&ea->ecmanswer_lock);
1531 return 0;
1532 }
1533
1534
1535 //SPECIAL CHECKs for rc
1536 if(rc < E_NOTFOUND && cw && chk_is_null_CW(cw)) //if cw=0 by anticascading
1537 {
1538 rc = E_NOTFOUND;
1539 cs_debug_mask(D_TRACE | D_LB, "WARNING: reader %s send fake cw, set rc=E_NOTFOUND!", reader ? reader->label : "-");
1540 }
1541
1542 if(reader && cw && rc < E_NOTFOUND)
1543 {
1544 if(reader->disablecrccws == 0)
1545 {
1546 for(i = 0; i < 16; i += 4)
1547 {
1548 c = ((cw[i] + cw[i + 1] + cw[i + 2]) & 0xff);
1549 if(cw[i + 3] != c)
1550 {
1551 if(reader->dropbadcws)
1552 {
1553 rc = E_NOTFOUND;
1554 rcEx = E2_WRONG_CHKSUM;
1555 break;
1556 }
1557 else
1558 {
1559 cs_debug_mask(D_TRACE, "notice: changed dcw checksum byte cw[%i] from %02x to %02x", i + 3, cw[i + 3], c);
1560 cw[i + 3] = c;
1561 }
1562 }
1563 }
1564 }
1565 else
1566 {
1567 cs_debug_mask(D_TRACE, "notice: CW checksum check disabled");
1568 }
1569 }
1570
1571#ifdef CW_CYCLE_CHECK
1572 if(!checkcwcycle(er, reader, cw, rc))
1573 {
1574 rc = E_NOTFOUND;
1575 rcEx = E2_WRONG_CHKSUM;
1576 cs_debug_mask(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);
1577 }
1578 else { cs_debug_mask(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); }
1579#endif
1580 //END -- SPECIAL CHECKs for rc
1581
1582
1583 ea->status |= REQUEST_ANSWERED;
1584 ea->rc = rc;
1585 ea->ecm_time = comp_timeb(&now, &ea->time_request_sent);
1586 if(ea->ecm_time < 1) { ea->ecm_time = 1; } //set ecm_time 1 if answer immediately
1587 ea->rcEx = rcEx;
1588 if(cw) { memcpy(ea->cw, cw, 16); }
1589 if(msglog) { memcpy(ea->msglog, msglog, MSGLOGSIZE); }
1590
1591 cs_writeunlock(&ea->ecmanswer_lock);
1592
1593 struct timeb tpe;
1594 cs_ftime(&tpe);
1595 int32_t ntime = comp_timeb(&tpe, &er->tps);
1596 if(ntime < 1) { ntime = 1; }
1597 cs_debug_mask(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);
1598
1599 //send ea for ecm request
1600 int32_t res = 0;
1601 struct s_client *cl = er->client;
1602 if(check_client(cl))
1603 {
1604 res = 1;
1605 add_job(er->client, ACTION_ECM_ANSWER_READER, ea, 0); //chk_dcw
1606 }
1607
1608 //distribute ea for pendings
1609 if(ea->pending) //has pending ea
1610 { distribute_ea(ea); }
1611
1612
1613 if(!ea->is_pending) //not for pending ea - only once for ea
1614 {
1615 send_reader_stat(reader, er, ea, ea->rc); //send stats for LB
1616
1617 //reader checks
1618 char ecmd5[17 * 3];
1619 cs_hexdump(0, er->ecmd5, 16, ecmd5, sizeof(ecmd5));
1620 rdr_debug_mask(reader, D_TRACE, "ecm answer for ecm hash %s rc=%d", ecmd5, ea->rc);
1621
1622 //Update reader stats:
1623 if(ea->rc == E_FOUND)
1624 {
1625 if(cfg.cwlogdir != NULL)
1626 { logCWtoFile(er, ea->cw); } /* CWL logging only if cwlogdir is set in config */
1627
1628 reader->ecmsok++;
1629#ifdef CS_CACHEEX
1630 struct s_client *eacl = reader->client;
1631 if(cacheex_reader(reader) && check_client(eacl))
1632 {
1633 eacl->cwcacheexgot++;
1634 cacheex_add_stats(eacl, ea->er->caid, ea->er->srvid, ea->er->prid, 1);
1635 first_client->cwcacheexgot++;
1636 }
1637#endif
1638 }
1639 else if(ea->rc == E_NOTFOUND)
1640 {
1641 reader->ecmsnok++;
1642 if(reader->ecmnotfoundlimit && reader->ecmsnok >= reader->ecmnotfoundlimit)
1643 {
1644 rdr_log(reader, "ECM not found limit reached %u. Restarting the reader.",
1645 reader->ecmsnok);
1646 reader->ecmsnok = 0; // Reset the variable
1647 reader->ecmshealthnok = 0; // Reset the variable
1648 add_job(reader->client, ACTION_READER_RESTART, NULL, 0);
1649 }
1650 }
1651
1652 //Reader ECMs Health Try (by Pickser)
1653 if(reader->ecmsok != 0 || reader->ecmsnok != 0)
1654 {
1655 reader->ecmshealthok = ((double) reader->ecmsok / (reader->ecmsok + reader->ecmsnok)) * 100;
1656 reader->ecmshealthnok = ((double) reader->ecmsnok / (reader->ecmsok + reader->ecmsnok)) * 100;
1657 }
1658
1659 if(rc == E_FOUND && reader->resetcycle > 0)
1660 {
1661 reader->resetcounter++;
1662 if(reader->resetcounter > reader->resetcycle)
1663 {
1664 reader->resetcounter = 0;
1665 rdr_log(reader, "Resetting reader, resetcyle of %d ecms reached", reader->resetcycle);
1666 reader->card_status = CARD_NEED_INIT;
1667 cardreader_reset(cl);
1668 }
1669 }
1670 }
1671
1672 return res;
1673}
1674
1675static void guess_cardsystem(ECM_REQUEST *er)
1676{
1677 uint16_t last_hope = 0;
1678
1679 // viaccess - check by provid-search
1680 if((er->prid = chk_provid(er->ecm, 0x500)))
1681 { er->caid = 0x500; }
1682
1683 // nagra
1684 // is ecm[1] always 0x30 ?
1685 // is ecm[3] always 0x07 ?
1686 if((er->ecm[6] == 1) && (er->ecm[4] == er->ecm[2] - 2))
1687 { er->caid = 0x1801; }
1688
1689 // seca2 - very poor
1690 if((er->ecm[8] == 0x10) && ((er->ecm[9] & 0xF1) == 1))
1691 { last_hope = 0x100; }
1692
1693 // is cryptoworks, but which caid ?
1694 if((er->ecm[3] == 0x81) && (er->ecm[4] == 0xFF) &&
1695 (!er->ecm[5]) && (!er->ecm[6]) && (er->ecm[7] == er->ecm[2] - 5))
1696 {
1697 last_hope = 0xd00;
1698 }
1699
1700 if(!er->caid && er->ecm[2] == 0x31 && er->ecm[0x0b] == 0x28)
1701 { guess_irdeto(er); }
1702
1703 if(!er->caid) // guess by len ..
1704 { er->caid = len4caid[er->ecm[2] + 3]; }
1705
1706 if(!er->caid)
1707 { er->caid = last_hope; }
1708}
1709
1710//chid calculation from module stat to here
1711//to improve the quickfix concerning ecm chid info and extend it to all client requests wereby the chid is known in module stat
1712
1713uint32_t get_subid(ECM_REQUEST *er)
1714{
1715 if(!er->ecmlen)
1716 { return 0; }
1717
1718 uint32_t id = 0;
1719 switch(er->caid >> 8)
1720 {
1721 case 0x01:
1722 id = b2i(2, er->ecm + 7);
1723 break; // seca
1724 case 0x05:
1725 id = b2i(2, er->ecm + 8);
1726 break; // viaccess
1727 case 0x06:
1728 id = b2i(2, er->ecm + 6);
1729 break; // irdeto
1730 case 0x09:
1731 id = b2i(2, er->ecm + 11);
1732 break; // videoguard
1733 case 0x4A: // DRE-Crypt, Bulcrypt, Tongfang and others?
1734 if(!(er->caid == 0x4AEE)) // Bulcrypt excluded for now
1735 { id = b2i(2, er->ecm + 6); }
1736 break;
1737 }
1738 return id;
1739}
1740
1741
1742static void set_readers_counter(ECM_REQUEST *er)
1743{
1744 struct s_ecm_answer *ea;
1745
1746 er->reader_count = 0;
1747 er->fallback_reader_count = 0;
1748 for(ea = er->matching_rdr; ea; ea = ea->next)
1749 {
1750 if(ea->status & READER_ACTIVE)
1751 {
1752 if(!(ea->status & READER_FALLBACK))
1753 { er->reader_count++; }
1754 else
1755 { er->fallback_reader_count++; }
1756 }
1757 }
1758}
1759
1760
1761void write_ecm_answer_fromcache(struct s_write_from_cache *wfc)
1762{
1763 ECM_REQUEST *er = NULL;
1764 ECM_REQUEST *ecm = NULL;
1765
1766 er = wfc->er_new;
1767 ecm = wfc->er_cache;
1768
1769 int8_t rc_orig = er->rc;
1770
1771 er->grp |= ecm->grp; //update group
1772#ifdef CS_CACHEEX
1773 if(ecm->from_csp) { er->csp_answered = 1; } //update er as answered by csp (csp have no group)
1774#endif
1775
1776 if(er->rc >= E_NOTFOUND)
1777 {
1778#ifdef CS_CACHEEX
1779 if(ecm->cacheex_src) //from cacheex or csp
1780 { er->rc = E_CACHEEX; }
1781 else
1782#endif
1783 { er->rc=E_CACHE1; } //from normal readers
1784
1785 memcpy(er->cw, ecm->cw, 16);
1786 er->selected_reader = ecm->selected_reader;
1787
1788#ifdef CS_CACHEEX
1789 if(ecm->cacheex_src && is_valid_client(ecm->cacheex_src) && !ecm->cacheex_src->kill){ //here we should be sure cex client has not been freed!
1790 er->cacheex_src = ecm->cacheex_src;
1791 }else{
1792 er->cacheex_src = NULL;
1793 }
1794
1795 int8_t cacheex = check_client(er->client) && er->client->account ? er->client->account->cacheex.mode : 0;
1796 if(cacheex == 1 && check_client(er->client))
1797 {
1798 cacheex_add_stats(er->client, er->caid, er->srvid, er->prid, 0);
1799 er->client->cwcacheexpush++;
1800 if(er->client->account)
1801 { er->client->account->cwcacheexpush++; }
1802 first_client->cwcacheexpush++;
1803 }
1804#endif
1805
1806#ifdef CS_CACHEEX
1807 if(cfg.delay && cacheex!=1) //No delay on cacheexchange mode 1 client!
1808 { cs_sleepms(cfg.delay); }
1809#else
1810 if(cfg.delay)
1811 { cs_sleepms(cfg.delay); }
1812#endif
1813
1814 if(rc_orig == E_UNHANDLED)
1815 {
1816 cs_debug_mask(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, ecm->cw_count);
1817 send_dcw(er->client, er);
1818 }
1819 }
1820}
1821
1822
1823void get_cw(struct s_client *client, ECM_REQUEST *er)
1824{
1825 cs_debug_mask(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);
1826 increment_n_request(client);
1827
1828 int32_t i, j, m;
1829 time_t now = time((time_t *)0);
1830 uint32_t line = 0;
1831
1832 er->client = client;
1833 er->rc = E_UNHANDLED; // set default rc status to unhandled
1834 if(now - client->lastecm > cfg.hideclient_to) { client->lastswitch = 0; } // user was on freetv or didn't request for some time so we reset lastswitch to get correct stats/webif display
1835 client->lastecm = now;
1836
1837 if(client == first_client || !client ->account || client->account == first_client->account)
1838 {
1839 //DVBApi+serial is allowed to request anonymous accounts:
1840 int16_t listenertype = get_module(client)->listenertype;
1841 if(listenertype != LIS_DVBAPI && listenertype != LIS_SERIAL)
1842 {
1843 er->rc = E_INVALID;
1844 er->rcEx = E2_GLOBAL;
1845 snprintf(er->msglog, sizeof(er->msglog), "invalid user account %s", username(client));
1846 }
1847 }
1848
1849 if(er->ecmlen > MAX_ECM_SIZE)
1850 {
1851 er->rc = E_INVALID;
1852 er->rcEx = E2_GLOBAL;
1853 snprintf(er->msglog, sizeof(er->msglog), "ECM size %d > Max Ecm size %d, ignored! client %s", er->ecmlen, MAX_ECM_SIZE, username(client));
1854 }
1855
1856 if(!client->grp)
1857 {
1858 er->rc = E_INVALID;
1859 er->rcEx = E2_GROUP;
1860 snprintf(er->msglog, sizeof(er->msglog), "invalid user group %s", username(client));
1861 }
1862
1863
1864 if(!er->caid)
1865 { guess_cardsystem(er); }
1866
1867 /* Quickfix Area */
1868
1869 // add chid for all client requests as in module stat
1870 update_chid(er);
1871
1872 // quickfix for 0100:000065
1873 if(er->caid == 0x100 && er->prid == 0x65 && er->srvid == 0)
1874 { er->srvid = 0x0642; }
1875
1876 // Quickfixes for Opticum/Globo HD9500
1877 // Quickfix for 0500:030300
1878 if(er->caid == 0x500 && er->prid == 0x030300)
1879 { er->prid = 0x030600; }
1880
1881 // Quickfix for 0500:D20200
1882 if(er->caid == 0x500 && er->prid == 0xD20200)
1883 { er->prid = 0x030600; }
1884
1885 //betacrypt ecm with nagra header
1886 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))
1887 {
1888 if(er->caid == 0x1702)
1889 {
1890 er->caid = 0x1833;
1891 }
1892 else
1893 {
1894 check_lb_auto_betatunnel_mode(er);
1895 }
1896 cs_debug_mask(D_TRACE, "Quickfix remap beta->nagra: 0x%X, 0x%X, 0x%X, 0x%X", er->caid, er->ecmlen, er->ecm[3], er->ecm[4]);
1897 }
1898
1899 //nagra ecm with betacrypt header 1801, 1833, 1834, 1835
1900 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))
1901 {
1902 if(er->caid == 0x1833)
1903 {
1904 er->caid = 0x1702;
1905 }
1906 else
1907 {
1908 er->caid = 0x1722;
1909 }
1910 cs_debug_mask(D_TRACE, "Quickfix remap nagra->beta: 0x%X, 0x%X, 0x%X, 0x%X", er->caid, er->ecmlen, er->ecm[13], er->ecm[44]);
1911 }
1912
1913 //Ariva quickfix (invalid nagra provider)
1914 if(((er->caid & 0xFF00) == 0x1800) && er->prid > 0x00FFFF)
1915 { er->prid = 0; }
1916
1917 //Check for invalid provider, extract provider out of ecm:
1918 uint32_t prid = chk_provid(er->ecm, er->caid);
1919 if(!er->prid)
1920 {
1921 er->prid = prid;
1922 }
1923 else
1924 {
1925 if(prid && prid != er->prid)
1926 {
1927 cs_debug_mask(D_TRACE, "provider fixed: %04X:%06X to %04X:%06X", er->caid, er->prid, er->caid, prid);
1928 er->prid = prid;
1929 }
1930 }
1931
1932#ifdef MODULE_NEWCAMD
1933 // Set providerid for newcamd clients if none is given
1934 if(!er->prid && client->ncd_server)
1935 {
1936 int32_t pi = client->port_idx;
1937 if(pi >= 0 && cfg.ncd_ptab.nports && cfg.ncd_ptab.nports >= pi && cfg.ncd_ptab.ports[pi].ncd)
1938 { er->prid = cfg.ncd_ptab.ports[pi].ncd->ncd_ftab.filts[0].prids[0]; }
1939 }
1940#endif
1941
1942 // CAID not supported or found
1943 if(!er->caid)
1944 {
1945 er->rc = E_INVALID;
1946 er->rcEx = E2_CAID;
1947 snprintf(er->msglog, MSGLOGSIZE, "CAID not supported or found");
1948 }
1949
1950 // user expired
1951 if(client->expirationdate && client->expirationdate < client->lastecm)
1952 { er->rc = E_EXPDATE; }
1953
1954 // out of timeframe
1955 if(client->allowedtimeframe[0] && client->allowedtimeframe[1])
1956 {
1957 struct tm acttm;
1958 localtime_r(&now, &acttm);
1959 int32_t curtime = (acttm.tm_hour * 60) + acttm.tm_min;
1960 int32_t mintime = client->allowedtimeframe[0];
1961 int32_t maxtime = client->allowedtimeframe[1];
1962 if(!((mintime <= maxtime && curtime > mintime && curtime < maxtime) || (mintime > maxtime && (curtime > mintime || curtime < maxtime))))
1963 {
1964 er->rc = E_EXPDATE;
1965 }
1966 cs_debug_mask(D_TRACE, "Check Timeframe - result: %d, start: %d, current: %d, end: %d\n", er->rc, mintime, curtime, maxtime);
1967 }
1968
1969 // user disabled
1970 if(client->disabled != 0)
1971 {
1972 if(client->failban & BAN_DISABLED)
1973 {
1974 cs_add_violation(client, client->account->usr);
1975 cs_disconnect_client(client);
1976 }
1977 er->rc = E_DISABLED;
1978 }
1979
1980 if(!chk_global_whitelist(er, &line))
1981 {
1982 debug_ecm(D_TRACE, "whitelist filtered: %s (%s) line %d", username(client), buf, line);
1983 er->rc = E_INVALID;
1984 }
1985
1986#ifdef CS_CACHEEX
1987 if(client->account && client->account->cacheex.mode==2 && !client->account->cacheex.allow_request)
1988 {
1989 er->rc = E_INVALID;
1990 snprintf(er->msglog, MSGLOGSIZE, "invalid request form cacheex-2 client");
1991 }
1992#endif
1993
1994
1995 // rc<100 -> ecm error
1996 if(er->rc >= E_UNHANDLED)
1997 {
1998 m = er->caid;
1999 i = er->srvid;
2000
2001 if(i != client->last_srvid || !client->lastswitch)
2002 {
2003 if(cfg.usrfileflag)
2004 { cs_statistics(client); }
2005 client->lastswitch = now;
2006 }
2007
2008 // user sleeping
2009 if(client->tosleep && (now - client->lastswitch > client->tosleep))
2010 {
2011 if(client->failban & BAN_SLEEPING)
2012 {
2013 cs_add_violation(client, client->account->usr);
2014 cs_disconnect_client(client);
2015 }
2016 if(client->c35_sleepsend != 0)
2017 {
2018 er->rc = E_STOPPED; // send stop command CMD08 {00 xx}
2019 }
2020 else
2021 {
2022 er->rc = E_SLEEPING;
2023 }
2024 }
2025
2026 client->last_srvid = i;
2027 client->last_caid = m;
2028
2029 int32_t ecm_len = (((er->ecm[1] & 0x0F) << 8) | er->ecm[2]) + 3;
2030
2031 for(j = 0; (j < 6) && (er->rc >= E_UNHANDLED); j++)
2032 {
2033 switch(j)
2034 {
2035 case 0:
2036 // fake (uniq)
2037 if(client->dup)
2038 { er->rc = E_FAKE; }
2039 break;
2040 case 1:
2041 // invalid (caid)
2042 if(!chk_bcaid(er, &client->ctab))
2043 {
2044 er->rc = E_INVALID;
2045 er->rcEx = E2_CAID;
2046 snprintf(er->msglog, MSGLOGSIZE, "invalid caid 0x%04X", er->caid);
2047 }
2048 break;
2049 case 2:
2050 // invalid (srvid)
2051 // matching srvids (or 0000) specified in betatunnel will bypass this filter
2052 if(!chk_srvid(client, er))
2053 {
2054 if(!chk_on_btun(SRVID_ZERO, client, er))
2055 {
2056 er->rc = E_INVALID;
2057 snprintf(er->msglog, MSGLOGSIZE, "invalid SID");
2058 }
2059 }
2060 break;
2061 case 3:
2062 // invalid (ufilters)
2063 if(!chk_ufilters(er))
2064 { er->rc = E_INVALID; }
2065 break;
2066 case 4:
2067 // invalid (sfilter)
2068 if(!chk_sfilter(er, &get_module(client)->ptab))
2069 { er->rc = E_INVALID; }
2070 break;
2071 case 5:
2072 // corrupt
2073 if((i = er->ecmlen - ecm_len))
2074 {
2075 if(i > 0)
2076 {
2077 cs_debug_mask(D_TRACE, "warning: ecm size adjusted from %d to %d", er->ecmlen, ecm_len);
2078 er->ecmlen = ecm_len;
2079 }
2080 else
2081 { er->rc = E_CORRUPT; }
2082 }
2083 break;
2084 }
2085 }
2086 }
2087
2088
2089 //not continue, send rc to client
2090 if(er->rc < E_UNHANDLED)
2091 {
2092 send_dcw(client, er);
2093 free_ecm(er);
2094 return;
2095 }
2096
2097
2098#ifdef CS_CACHEEX
2099 int8_t cacheex = client->account ? client->account->cacheex.mode : 0;
2100 er->from_cacheex1_client = 0;
2101 if(cacheex == 1) { er->from_cacheex1_client = 1; }
2102#endif
2103
2104
2105 //Schlocke: above checks could change er->rc so
2106 /*BetaCrypt tunneling
2107 *moved behind the check routines,
2108 *because newcamd ECM will fail
2109 *if ECM is converted before
2110 */
2111 if(chk_is_betatunnel_caid(er->caid) && client->ttab.n)
2112 {
2113 cs_ddump_mask(D_TRACE, er->ecm, 13, "betatunnel? ecmlen=%d", er->ecmlen);
2114 cs_betatunnel(er);
2115 }
2116
2117 // ignore ecm ...
2118 int32_t offset = 3;
2119 // ... and betacrypt header for cache md5 calculation
2120 if((er->caid >> 8) == 0x17)
2121 { offset = 13; }
2122 unsigned char md5tmp[MD5_DIGEST_LENGTH];
2123 // store ECM in cache
2124 memcpy(er->ecmd5, MD5(er->ecm + offset, er->ecmlen - offset, md5tmp), CS_ECMSTORESIZE);
2125 cacheex_update_hash(er);
2126 ac_chk(client, er, 0);
2127
2128
2129 //******** CHECK IF FOUND ECM IN CACHE
2130 struct ecm_request_t *ecm = NULL;
2131 ecm = check_cache(er, client);
2132 if(ecm) //found in cache
2133 {
2134 cs_debug_mask(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);
2135
2136 struct s_write_from_cache *wfc = NULL;
2137 if(!cs_malloc(&wfc, sizeof(struct s_write_from_cache)))
2138 {
2139 free(ecm);
2140 free_ecm(er);
2141 return;
2142 }
2143
2144 wfc->er_new = er;
2145 wfc->er_cache = ecm;
2146 write_ecm_answer_fromcache(wfc);
2147 free(ecm);
2148 free_ecm(er);
2149
2150 return;
2151 }
2152
2153
2154 er->reader_avail = 0;
2155 er->readers = 0;
2156#ifdef CS_CACHEEX
2157 er->reader_nocacheex_avail = 0;
2158#endif
2159
2160 struct s_ecm_answer *ea, *prv = NULL;
2161 struct s_reader *rdr;
2162
2163 cs_readlock(&readerlist_lock);
2164 cs_readlock(&clientlist_lock);
2165
2166 for(rdr = first_active_reader; rdr; rdr = rdr->next)
2167 {
2168 uint8_t is_fallback = chk_is_fixed_fallback(rdr, er);
2169
2170 int8_t match = matching_reader(er, rdr);
2171#ifdef WITH_LB
2172 //if this reader does not match, check betatunnel for it
2173 if(!match && cfg.lb_auto_betatunnel)
2174 {
2175 uint16_t caid = lb_get_betatunnel_caid_to(er->caid);
2176 if(caid)
2177 {
2178 uint16_t save_caid = er->caid;
2179 er->caid = caid;
2180 match = matching_reader(er, rdr); //matching
2181 er->caid = save_caid;
2182 }
2183 }
2184#endif
2185 if(match)
2186 {
2187 er->reader_avail++;
2188
2189#ifdef CS_CACHEEX
2190 if(!rdr->cacheex.mode) { er->reader_nocacheex_avail++; }
2191 if(cacheex == 1 && !cacheex_reader(rdr)) //ex1-cl only ask ex1-rdr
2192 { continue; }
2193#endif
2194
2195 if(!cs_malloc(&ea, sizeof(struct s_ecm_answer)))
2196 { goto OUT; }
2197
2198 er->readers++;
2199
2200 ea->reader = rdr;
2201 ea->er = er;
2202 ea->rc = E_UNHANDLED;
2203 if(prv)
2204 { prv->next = ea; }
2205 else
2206 { er->matching_rdr = ea; }
2207 prv = ea;
2208
2209 ea->status = READER_ACTIVE;
2210 if(!is_network_reader(rdr))
2211 { ea->status |= READER_LOCAL; }
2212 else if(cacheex_reader(rdr))
2213 {
2214 ea->status |= READER_CACHEEX;
2215 er->cacheex_reader_count++;
2216 }
2217
2218 if(is_fallback)
2219 { ea->status |= READER_FALLBACK; }
2220
2221 ea->pending = NULL;
2222 ea->is_pending = false;
2223 cs_lock_create(&ea->ecmanswer_lock, 5, "ecmanswer_lock");
2224 }
2225 }
2226
2227OUT:
2228 cs_readunlock(&clientlist_lock);
2229 cs_readunlock(&readerlist_lock);
2230
2231
2232#ifdef WITH_LB
2233 //FILTER readers by loadbalancing
2234 stat_get_best_reader(er);
2235#endif
2236
2237 //set reader_count and fallback_reader_count
2238 set_readers_counter(er);
2239
2240
2241#ifdef CS_CACHEEX
2242 //WAIT_TIME
2243 uint32_t cacheex_wait_time = 0;
2244 uint32_t wait_time_no_hitcache = 0;
2245 uint32_t wait_time_hitcache = 0;
2246
2247 if(client->account && !client->account->no_wait_time)
2248 {
2249 wait_time_no_hitcache = get_cacheex_wait_time(er,NULL); //NO check hitcache. Wait_time is dwtime, or, if 0, awtime.
2250 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.
2251
2252 if(
2253 //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!
2254 (cacheex != 1 && er->cacheex_reader_count)
2255 ||
2256 /* 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.
2257 * If readers, we have to wait cws generating by normal clients asking normal readers and answers by ex1-rdr (cannot use hitcache).
2258 * If no readers, use hitcache for calculating wait_time.
2259 */
2260 (cacheex == 1 && er->reader_avail)
2261 )
2262 { cacheex_wait_time = wait_time_no_hitcache; }
2263 else
2264 { cacheex_wait_time = wait_time_hitcache; }
2265 }
2266
2267 cs_debug_mask(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);
2268 cs_debug_mask(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", (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);
2269 //END WAIT_TIME calculation
2270
2271 if(!cacheex_wait_time && (er->reader_count + er->fallback_reader_count) == 0)
2272#else
2273 if((er->reader_count + er->fallback_reader_count) == 0)
2274#endif
2275 {
2276 er->rc = E_NOTFOUND;
2277 if(!er->rcEx)
2278 { er->rcEx = E2_GROUP; }
2279 snprintf(er->msglog, MSGLOGSIZE, "no matching reader");
2280 cs_debug_mask(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);
2281 send_dcw(client, er);
2282 free_ecm(er);
2283 return;
2284 }
2285
2286
2287 //insert it in ecmcwcache!
2288 cs_writelock(&ecmcache_lock);
2289 er->next = ecmcwcache;
2290 ecmcwcache = er;
2291 ecmcwcache_size++;
2292 cs_writeunlock(&ecmcache_lock);
2293
2294
2295#ifdef WITH_LB
2296 //cahe2 is handled by readers queue, so, if a same ecm hash with same readers, use these same readers to get cache2 from them! Not ask other readers!
2297 struct ecm_request_t *ecm_eq = NULL;
2298 ecm_eq = check_same_ecm(er);
2299 if(ecm_eq)
2300 {
2301 //set all readers used by ecm_eq, so we get cache2 from them!
2302 use_same_readers(er, ecm_eq);
2303 cs_debug_mask(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} [get_cw] found same ecm with same readers from client %s, use them!", (check_client(er->client) ? er->client->account->usr : "-"), er->caid, er->prid, er->srvid, (check_client(ecm_eq->client) ? ecm_eq->client->account->usr : "-"));
2304
2305 //set reader_count and fallback_reader_count
2306 set_readers_counter(er);
2307 }
2308#endif
2309
2310
2311 er->rcEx = 0;
2312#ifdef CS_CACHEEX
2313 er->cacheex_wait_time_expired = 1;
2314 er->cacheex_hitcache = 0;
2315 if(cacheex_wait_time) //wait time for cacheex
2316 {
2317 add_ms_to_timeb(&er->cacheex_wait, cacheex_wait_time);
2318 er->cacheex_wait_time = cacheex_wait_time;
2319 er->cacheex_wait_time_expired = 0;
2320 if(er->cacheex_reader_count > 0)
2321 {
2322 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.
2323 request_cw_from_readers(er, 1); // setting stop_stage=1, we request only cacheex mode 1 readers. Others are requested at cacheex timeout!
2324 }
2325 }
2326 else
2327#endif
2328 request_cw_from_readers(er, 0);
2329
2330
2331#ifdef WITH_DEBUG
2332 if(D_CLIENTECM & cs_dblevel)
2333 {
2334 char buf[ECM_FMT_LEN];
2335 format_ecm(er, buf, ECM_FMT_LEN);
2336 cs_ddump_mask(D_CLIENTECM, er->ecm, er->ecmlen, "Client %s ECM dump %s", username(client), buf);
2337 }
2338#endif
2339
2340 cw_process_thread_wakeup();
2341}
2342
2343
2344int32_t ecmfmt(uint16_t caid, uint16_t onid, uint32_t prid, uint16_t chid, uint16_t pid, uint16_t srvid, uint16_t l, char *ecmd5hex, char *csphash, char *cw, char *result, size_t size, uint16_t origin_peer, uint8_t distance)
2345{
2346 if(!cfg.ecmfmt)
2347 { return snprintf(result, size, "%04X&%06X/%04X/%04X/%02X:%s", caid, prid, chid, srvid, l, ecmd5hex); }
2348
2349 uint32_t s = 0, zero = 0, flen = 0, value = 0;
2350 char *c = cfg.ecmfmt, fmt[5] = "%04X";
2351 while(*c)
2352 {
2353 switch(*c)
2354 {
2355 case '0':
2356 zero = 1;
2357 value = 0;
2358 break;
2359 case 'c':
2360 flen = 4;
2361 value = caid;
2362 break;
2363 case 'o':
2364 flen = 4;
2365 value = onid;
2366 break;
2367 case 'p':
2368 flen = 6;
2369 value = prid;
2370 break;
2371 case 'i':
2372 flen = 4;
2373 value = chid;
2374 break;
2375 case 'd':
2376 flen = 4;
2377 value = pid;
2378 break;
2379 case 's':
2380 flen = 4;
2381 value = srvid;
2382 break;
2383 case 'l':
2384 flen = 2;
2385 value = l;
2386 break;
2387 case 'h':
2388 flen = CS_ECMSTORESIZE;
2389 break;
2390 case 'e':
2391 flen = 5;
2392 break;
2393 case 'w':
2394 flen = 17;
2395 break;
2396 case 'j':
2397 flen = 2;
2398 value = distance;
2399 break;
2400 case 'g':
2401 flen = 4;
2402 value = origin_peer;
2403 break;
2404 case '\\':
2405 c++;
2406 flen = 0;
2407 value = *c;
2408 break;
2409 default:
2410 flen = 0;
2411 value = *c;
2412 break;
2413 }
2414 if(value)
2415 { zero = 0; }
2416
2417 if(!zero)
2418 {
2419 //fmt[0] = '%';
2420 if(flen) //Build %04X / %06X / %02X
2421 {
2422 fmt[1] = '0';
2423 fmt[2] = flen + '0';
2424 fmt[3] = 'X';
2425 fmt[4] = 0;
2426 }
2427 else
2428 {
2429 fmt[1] = 'c';
2430 fmt[2] = 0;
2431 }
2432 if(flen == CS_ECMSTORESIZE) { s += snprintf(result + s, size - s , "%s", ecmd5hex); }
2433 else if(flen == 5) { s += snprintf(result + s, size - s , "%s", csphash); }
2434 else if(flen == 17) { s += snprintf(result + s, size - s , "%s", cw); }
2435 else { s += snprintf(result + s, size - s, fmt, value); }
2436 }
2437 c++;
2438 }
2439 return s;
2440}
2441
2442uint8_t checkCWpart(uchar *cw, int8_t part)
2443{
2444 uint8_t eo = part ? 8 : 0;
2445 int8_t i;
2446 for(i = 0; i < 8; i++)
2447 if(cw[i + eo]) { return 1; }
2448 return 0;
2449}
2450
2451int32_t format_ecm(ECM_REQUEST *ecm, char *result, size_t size)
2452{
2453 char ecmd5hex[17 * 3];
2454 char csphash[5 * 3] = { 0 };
2455 char cwhex[17 * 3];
2456 cs_hexdump(0, ecm->ecmd5, 16, ecmd5hex, sizeof(ecmd5hex));
2457#ifdef CS_CACHEEX
2458 cs_hexdump(0, (void *)&ecm->csp_hash, 4, csphash, sizeof(csphash));
2459#endif
2460 cs_hexdump(0, ecm->cw, 16, cwhex, sizeof(cwhex));
2461#ifdef MODULE_GBOX
2462 if(ecm->gbox_hops)
2463 { return ecmfmt(ecm->caid, ecm->onid, ecm->prid, ecm->chid, ecm->pid, ecm->srvid, ecm->ecmlen, ecmd5hex, csphash, cwhex, result, size, ecm->gbox_peer, ecm->gbox_hops); }
2464 else
2465#endif
2466 return ecmfmt(ecm->caid, ecm->onid, ecm->prid, ecm->chid, ecm->pid, ecm->srvid, ecm->ecmlen, ecmd5hex, csphash, cwhex, result, size, 0, 0);
2467}
2468
Note: See TracBrowser for help on using the repository browser.