Changeset 11473 for trunk/oscam-reader.c
- Timestamp:
- 01/18/19 20:17:57 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/oscam-reader.c
r11369 r11473 44 44 gone = comp_timeb(actualtime, &reader->lastdvbapirateoverride); 45 45 46 if (gone > reader->ratelimittime) { 46 if (gone > reader->ratelimittime) 47 { 47 48 int32_t h; 48 49 struct timeb minecmtime = *actualtime; 49 for (h = 0; h < MAXECMRATELIMIT; h++) { 50 51 for (h = 0; h < MAXECMRATELIMIT; h++) 52 { 50 53 gone = comp_timeb(&minecmtime, &reader->rlecmh[h].last); 51 54 if (gone > 0) { … … 55 58 } 56 59 reader->lastdvbapirateoverride = *actualtime; 57 cs_log_dbg(D_CLIENT, "prioritizing DVBAPI user %s over other watching client", er->client->account->usr); 58 cs_log_dbg(D_CLIENT, "ratelimiter forcing srvid %04X into slot %d/%d of reader %s", er->srvid, foundspace + 1, maxecms, reader->label); 59 } else { 60 61 cs_log_dbg(D_CLIENT, "prioritizing DVBAPI user %s over other watching client", 62 er->client->account->usr); 63 64 cs_log_dbg(D_CLIENT, "ratelimiter forcing srvid %04X into slot %d/%d of reader %s", 65 er->srvid, foundspace + 1, maxecms, reader->label); 66 } 67 else 68 { 60 69 cs_log_dbg(D_CLIENT, "DVBAPI User %s is switching too fast for ratelimit and can't be prioritized!", 61 70 er->client->account->usr); 62 71 } 63 72 return foundspace; … … 66 75 static int32_t ecm_ratelimit_findspace(struct s_reader *reader, ECM_REQUEST *er, struct ecmrl rl, int32_t reader_mode) 67 76 { 68 69 77 int32_t h, foundspace = -1; 70 78 int32_t maxecms = MAXECMRATELIMIT; // init maxecms … … 72 80 struct timeb actualtime; 73 81 cs_ftime(&actualtime); 74 for(h = 0; h < MAXECMRATELIMIT; h++) // release slots with srvid that are overtime, even if not called from reader module to maximize available slots! 82 83 for(h = 0; h < MAXECMRATELIMIT; h++) // release slots with srvid that are overtime, even if not called from reader module to maximize available slots! 75 84 { 76 85 if(reader->rlecmh[h].last.time == -1) { continue; } 86 77 87 int64_t gone = comp_timeb(&actualtime, &reader->rlecmh[h].last); 78 if( 88 if(gone >= (reader->rlecmh[h].ratelimittime + reader->rlecmh[h].srvidholdtime) || gone < 0) // gone <0 fixup for bad systemtime on dvb receivers while changing transponders 79 89 { 80 90 cs_log_dbg(D_CLIENT, "ratelimiter srvid %04X released from slot %d/%d of reader %s (%"PRId64">=%d ratelimit ms + %d ms srvidhold!)", 81 reader->rlecmh[h].srvid, h + 1, MAXECMRATELIMIT, reader->label, gone, 82 reader->rlecmh[h].ratelimittime, reader->rlecmh[h].srvidholdtime); 91 reader->rlecmh[h].srvid, h + 1, MAXECMRATELIMIT, reader->label, gone, 92 reader->rlecmh[h].ratelimittime, reader->rlecmh[h].srvidholdtime); 93 83 94 reader->rlecmh[h].last.time = -1; 84 95 reader->rlecmh[h].srvid = -1; … … 86 97 reader->rlecmh[h].once = 0; 87 98 } 99 88 100 if(reader->rlecmh[h].last.time == -1) { continue; } 89 if(reader->rlecmh[h].ratelimitecm < maxecms) { maxecms = reader->rlecmh[h].ratelimitecm; } 101 if(reader->rlecmh[h].ratelimitecm < maxecms) { maxecms = reader->rlecmh[h].ratelimitecm; } // we found a more critical ratelimit srvid 90 102 totalecms++; 91 103 } 92 104 93 cs_log_dbg(D_CLIENT, "ratelimiter found total of %d srvid for reader %s most critical is limited to %d requests", totalecms, reader->label, maxecms); 94 95 if(reader->cooldown[0] && reader->cooldownstate != 1) { maxecms = MAXECMRATELIMIT; } // dont apply ratelimits if cooldown isnt in use or not in effect 96 97 for(h = 0; h < MAXECMRATELIMIT; h++) // check if srvid is already in a slot 105 cs_log_dbg(D_CLIENT, "ratelimiter found total of %d srvid for reader %s most critical is limited to %d requests", 106 totalecms, reader->label, maxecms); 107 108 if(reader->cooldown[0] && reader->cooldownstate != 1) { maxecms = MAXECMRATELIMIT; } // dont apply ratelimits if cooldown isnt in use or not in effect 109 110 for(h = 0; h < MAXECMRATELIMIT; h++) // check if srvid is already in a slot 98 111 { 99 112 if(reader->rlecmh[h].last.time == -1) { continue; } 113 100 114 if(reader->rlecmh[h].srvid == er->srvid && reader->rlecmh[h].caid == rl.caid && reader->rlecmh[h].provid == rl.provid 101 115 && (!reader->rlecmh[h].chid || (reader->rlecmh[h].chid == rl.chid))) 102 116 { 103 117 int64_t gone = comp_timeb(&actualtime, &reader->rlecmh[h].last); … … 110 124 if(gone < reader->ratelimittime) 111 125 { 112 if(memcmp(reader->rlecmh[h].ecmd5, er->ecmd5, CS_ECMSTORESIZE)) //some boxes seem to send different ecms but asking in fact for same cw! 113 { // different ecm request than one in the slot! 126 // some boxes seem to send different ecms but asking in fact for same cw! 127 if(memcmp(reader->rlecmh[h].ecmd5, er->ecmd5, CS_ECMSTORESIZE)) 128 { 129 // different ecm request than one in the slot! 114 130 if(er->ecm[0] == reader->rlecmh[h].kindecm) 115 131 { … … 118 134 cs_hexdump(0, reader->rlecmh[h].ecmd5, 16, ecmd5, sizeof(ecmd5)); 119 135 cs_log_dbg(D_CLIENT, "ratelimiter ecm %s in this slot for next %d ms!", ecmd5, 120 136 (int)(reader->rlecmh[h].ratelimittime - gone)); 121 137 122 138 struct ecm_request_t *erold = NULL; 123 139 if(!cs_malloc(&erold, sizeof(struct ecm_request_t))) 124 140 { return -2; } 141 125 142 memcpy(erold, er, sizeof(struct ecm_request_t)); // copy ecm all 126 143 memcpy(erold->ecmd5, reader->rlecmh[h].ecmd5, CS_ECMSTORESIZE); // replace md5 hash … … 128 145 ecm = check_cache(erold, erold->client); //CHECK IF FOUND ECM IN CACHE 129 146 NULLFREE(erold); 130 if(ecm) //found in cache 131 { write_ecm_answer(reader, er, ecm->rc, ecm->rcEx, ecm->cw, NULL, 0, &ecm->cw_ex); } // return controlword of the ecm sitting in the slot! 147 148 if(ecm) // found in cache 149 { 150 // return controlword of the ecm sitting in the slot! 151 write_ecm_answer(reader, er, ecm->rc, ecm->rcEx, ecm->cw, NULL, 0, &ecm->cw_ex); 152 } 132 153 else 133 { write_ecm_answer(reader, er, E_NOTFOUND, E2_RATELIMIT, NULL, "Ratelimiter: no slots free!", 0, NULL); } 154 { 155 write_ecm_answer(reader, er, E_NOTFOUND, E2_RATELIMIT, NULL, "Ratelimiter: no slots free!", 0, NULL); 156 } 134 157 135 158 NULLFREE(ecm); … … 138 161 } 139 162 } 163 140 164 if((er->ecm[0] != reader->rlecmh[h].kindecm) && (gone <= reader->ratelimittime)) 141 165 { … … 148 172 else 149 173 { 150 cs_log_dbg(D_CLIENT, "ratelimiter srvid %04X only allowing ecmtype %s for next %d ms in slot %d/%d of reader %s -> skipping this slot!", reader->rlecmh[h].srvid, 151 (reader->rlecmh[h].kindecm == 0x80 ? "even" : "odd"), (int)(reader->rlecmh[h].ratelimittime - gone), h + 1, maxecms, reader->label); 174 cs_log_dbg(D_CLIENT, "ratelimiter srvid %04X only allowing ecmtype %s for next %d ms in slot %d/%d of reader %s -> skipping this slot!", 175 reader->rlecmh[h].srvid, (reader->rlecmh[h].kindecm == 0x80 ? "even" : "odd"), 176 (int)(reader->rlecmh[h].ratelimittime - gone), h + 1, maxecms, reader->label); 152 177 continue; 153 178 } … … 157 182 if(h > 0) 158 183 { 159 for(foundspace = 0; foundspace < h; foundspace++) 184 for(foundspace = 0; foundspace < h; foundspace++) // check for free lower slot 160 185 { 161 186 if(reader->rlecmh[foundspace].last.time == -1) … … 166 191 reader->rlecmh[h].kindecm = 0; 167 192 reader->rlecmh[h].once = 0; 193 168 194 if(foundspace < maxecms) 169 195 { 170 cs_log_dbg(D_CLIENT, "ratelimiter moved srvid %04X to slot %d/%d of reader %s", er->srvid, foundspace + 1, maxecms, reader->label); 196 cs_log_dbg(D_CLIENT, "ratelimiter moved srvid %04X to slot %d/%d of reader %s", 197 er->srvid, foundspace + 1, maxecms, reader->label); 198 171 199 return foundspace; // moving to lower free slot! 172 200 } 173 201 else 174 202 { 175 cs_log_dbg(D_CLIENT, "ratelimiter removed srvid %04X from slot %d/%d of reader %s", er->srvid, foundspace + 1, maxecms, reader->label); 203 cs_log_dbg(D_CLIENT, "ratelimiter removed srvid %04X from slot %d/%d of reader %s", 204 er->srvid, foundspace + 1, maxecms, reader->label); 205 176 206 reader->rlecmh[foundspace].last.time = -1; // free this slot since we are over ratelimit! 177 207 return -1; // sorry, ratelimit! … … 180 210 } 181 211 } 182 if(h < maxecms) // found but cant move to lower position! 212 213 if(h < maxecms) // found but cant move to lower position! 183 214 { 184 215 return h; // return position if within ratelimits! … … 190 221 reader->rlecmh[h].kindecm = 0; 191 222 reader->rlecmh[h].once = 0; 192 cs_log_dbg(D_CLIENT, "ratelimiter removed srvid %04X from slot %d/%d of reader %s", er->srvid, h + 1, maxecms, reader->label); 223 224 cs_log_dbg(D_CLIENT, "ratelimiter removed srvid %04X from slot %d/%d of reader %s", 225 er->srvid, h + 1, maxecms, reader->label); 226 193 227 return -1; // sorry, ratelimit! 194 228 } … … 202 236 { 203 237 // we are in cooldown or no cooldown configured! 204 if(totalecms + 1 > maxecms || totalecms + 1 > rl.ratelimitecm) 238 if(totalecms + 1 > maxecms || totalecms + 1 > rl.ratelimitecm) // check if this channel fits in! 205 239 { 206 240 cs_log_dbg(D_CLIENT, "ratelimiter for reader %s has no free slots!", reader->label); … … 213 247 } 214 248 215 for(h = 0; h < maxecms; h++) 249 for(h = 0; h < maxecms; h++) // check for free slot 216 250 { 217 251 if(reader->rlecmh[h].last.time == -1) 218 252 { 219 if(reader_mode) { cs_log_dbg(D_CLIENT, "ratelimiter added srvid %04X to slot %d/%d of reader %s", er->srvid, h + 1, maxecms, reader->label); } 253 if(reader_mode) 254 { 255 cs_log_dbg(D_CLIENT, "ratelimiter added srvid %04X to slot %d/%d of reader %s", 256 er->srvid, h + 1, maxecms, reader->label); 257 } 220 258 return h; // free slot found -> assign it! 221 259 } 222 else { 260 else // occupied slots 261 { 223 262 int64_t gone = comp_timeb(&actualtime, &reader->rlecmh[h].last); 224 cs_log_dbg(D_CLIENT, "ratelimiter srvid %04X for %"PRId64" ms present in slot %d/%d of reader %s", reader->rlecmh[h].srvid, gone , h + 1, 225 maxecms, reader->label); } //occupied slots 263 cs_log_dbg(D_CLIENT, "ratelimiter srvid %04X for %"PRId64" ms present in slot %d/%d of reader %s", 264 reader->rlecmh[h].srvid, gone , h + 1, maxecms, reader->label); 265 } 226 266 } 227 267 … … 238 278 struct ecmrl tmp; 239 279 240 for(i = 0; i < reader->ratelimitecm; i++) // inspect all slots 241 { 242 if(reader->rlecmh[i].last.time == -1) { continue; } // skip empty slots 280 for(i = 0; i < reader->ratelimitecm; i++) // inspect all slots 281 { 282 if(reader->rlecmh[i].last.time == -1) { continue; } // skip empty slots 283 243 284 loc = i; 244 285 tmp = reader->rlecmh[i]; // tmp is ecm in slot to evaluate 245 286 246 for(j = i + 1; j < MAXECMRATELIMIT; j++) // inspect all slots above the slot to be inspected 247 { 248 if(reader->rlecmh[j].last.time == -1) { continue; } // skip empty slots 287 for(j = i + 1; j < MAXECMRATELIMIT; j++) // inspect all slots above the slot to be inspected 288 { 289 if(reader->rlecmh[j].last.time == -1) { continue; } // skip empty slots 290 249 291 int32_t gone = comp_timeb(&reader->rlecmh[i].last, &tmp.last); 250 if(gone > 0) 292 if(gone > 0) // is higher slot holding a younger ecmrequest? 251 293 { 252 294 loc = j; // found a younger one … … 255 297 } 256 298 257 if(loc != i) 299 if(loc != i) // Did we find a younger ecmrequest? 258 300 { 259 301 reader->rlecmh[loc] = reader->rlecmh[i]; // place older request in slot of younger one we found … … 273 315 } 274 316 275 int32_t ecm_ratelimit_check(struct s_reader *reader, ECM_REQUEST *er, int32_t reader_mode)276 317 // If reader_mode is 1, ECM_REQUEST need to be assigned to reader and slot. 277 318 // Else just report if a free slot is available. 319 int32_t ecm_ratelimit_check(struct s_reader *reader, ECM_REQUEST *er, int32_t reader_mode) 278 320 { 279 321 // No rate limit set … … 283 325 } 284 326 285 int32_t foundspace = -1, h, maxslots = MAXECMRATELIMIT; // init slots to oscam global maximums327 int32_t foundspace = -1, h, maxslots = MAXECMRATELIMIT; // init slots to oscam global maximums 286 328 struct ecmrl rl; 287 329 struct timeb now; … … 291 333 { 292 334 cs_log_dbg(D_CLIENT, "ratelimit found for CAID: %04X PROVID: %06X SRVID: %04X CHID: %04X maxecms: %d cycle: %d ms srvidhold: %d ms", 293 294 } 295 else 335 rl.caid, rl.provid, rl.srvid, rl.chid, rl.ratelimitecm, rl.ratelimittime, rl.srvidholdtime); 336 } 337 else // nothing found: apply general reader limits 296 338 { 297 339 rl.ratelimitecm = reader->ratelimitecm; … … 303 345 rl.srvid = er->srvid; 304 346 cs_log_dbg(D_CLIENT, "ratelimiter apply readerdefault for CAID: %04X PROVID: %06X SRVID: %04X CHID: %04X maxecms: %d cycle: %d ms srvidhold: %d ms", 305 rl.caid, rl.provid, rl.srvid, rl.chid, rl.ratelimitecm, rl.ratelimittime, rl.srvidholdtime); 306 } 347 rl.caid, rl.provid, rl.srvid, rl.chid, rl.ratelimitecm, rl.ratelimittime, rl.srvidholdtime); 348 } 349 307 350 // Below this line: rate limit functionality. 308 351 // No cooldown set … … 324 367 return ERROR; // not even trowing an error... obvious reason ;) 325 368 } 326 else //we are within ecmratelimits369 else // we are within ecmratelimits 327 370 { 328 371 if(reader_mode) … … 332 375 reader->rlecmh[foundspace] = rl; // register this srvid ratelimit params 333 376 cs_ftime(&reader->rlecmh[foundspace].last); // register request time 334 memcpy(reader->rlecmh[foundspace].ecmd5, er->ecmd5, CS_ECMSTORESIZE); // register ecmhash377 memcpy(reader->rlecmh[foundspace].ecmd5, er->ecmd5, CS_ECMSTORESIZE); // register ecmhash 335 378 reader->rlecmh[foundspace].kindecm = er->ecm[0]; // register kind of ecm 336 379 } … … 353 396 354 397 cs_ftime(&now); 355 int32_t 356 if(reader->cooldownstate == 1) 357 { 358 if(gone <= reader->cooldown[1] *1000)// check if cooldowntime is elapsed398 int32_t gone = comp_timeb(&now, &reader->cooldowntime); 399 if(reader->cooldownstate == 1) // Cooldown in ratelimit phase 400 { 401 if(gone <= reader->cooldown[1] * 1000) // check if cooldowntime is elapsed 359 402 { maxslots = reader->ratelimitecm; } // use user defined ratelimitecm 360 else 403 else // Cooldown time is elapsed 361 404 { 362 405 reader->cooldownstate = 0; // set cooldown setup phase … … 364 407 maxslots = MAXECMRATELIMIT; //use oscam defined max slots 365 408 cs_log("Reader: %s ratelimiter returning to setup phase cooling down period of %d seconds is done!", 366 409 reader->label, reader->cooldown[1]); 367 410 } 368 411 } // if cooldownstate == 1 369 412 370 if(reader->cooldownstate == 2 && gone > reader->cooldown[0] *1000)413 if(reader->cooldownstate == 2 && gone > reader->cooldown[0] * 1000) 371 414 { 372 415 // Need to check if the otherslots are not exceeding the ratelimit at the moment that … … 376 419 for(h = 0; h < MAXECMRATELIMIT; h++) 377 420 { 378 if(reader->rlecmh[h].last.time == -1) { continue; } 421 if(reader->rlecmh[h].last.time == -1) { continue; } // skip empty slots 379 422 // how many active slots are registered at end of cooldown delay period 380 423 381 424 gone = comp_timeb(&now, &reader->rlecmh[h].last); 382 425 if(gone <= (reader->ratelimittime + reader->srvidholdtime)) 383 426 { 384 427 maxslots++; 385 if(maxslots >= reader->ratelimitecm) { break; } 428 if(maxslots >= reader->ratelimitecm) { break; } // Need to go cooling down phase 386 429 } 387 430 } … … 393 436 maxslots = MAXECMRATELIMIT; // maxslots is maxslots again 394 437 cs_log("Reader: %s ratelimiter returning to setup phase after %d seconds cooldowndelay!", 395 438 reader->label, reader->cooldown[0]); 396 439 } 397 440 else … … 401 444 maxslots = reader->ratelimitecm; // maxslots is maxslots again 402 445 sort_ecmrl(reader); // keep youngest ecm requests in list + housekeeping 403 cs_log("Reader: %s ratelimiter starting cooling down period of %d seconds!", reader->label, reader->cooldown[1]); 446 cs_log("Reader: %s ratelimiter starting cooling down period of %d seconds!", 447 reader->label, reader->cooldown[1]); 404 448 } 405 449 } // if cooldownstate == 2 406 450 407 cs_log_dbg(D_CLIENT, "ratelimiter cooldownphase %d find a slot for srvid %04X on reader %s", reader->cooldownstate, er->srvid, reader->label); 451 cs_log_dbg(D_CLIENT, "ratelimiter cooldownphase %d find a slot for srvid %04X on reader %s", 452 reader->cooldownstate, er->srvid, reader->label); 453 408 454 foundspace = ecm_ratelimit_findspace(reader, er, rl, reader_mode); 409 455 … … 415 461 { 416 462 cs_log_dbg(D_CLIENT, "ratelimiter cooldownphase %d no free slot for srvid %04X on reader %s -> dropping!", 417 463 reader->cooldownstate, er->srvid, reader->label); 418 464 write_ecm_answer(reader, er, E_NOTFOUND, E2_RATELIMIT, NULL, "Ratelimiter: cooldown no slots free!", 0, NULL); 419 465 } … … 422 468 return ERROR; // not even trowing an error... obvious reason ;) 423 469 } 424 else //we are within ecmratelimits470 else // we are within ecmratelimits 425 471 { 426 472 if(reader_mode) … … 437 483 if(reader->cooldownstate == 0 && foundspace >= reader->ratelimitecm) 438 484 { 439 if(!reader_mode) // No actual ecm request, just check 440 { 441 485 if(!reader_mode) // No actual ecm request, just check 486 { 442 487 return OK; 443 488 } 489 444 490 cs_log("Reader: %s ratelimiter cooldown detected overrun ecmratelimit of %d during setup phase!", 445 491 reader->label, (foundspace - reader->ratelimitecm + 1)); 446 492 reader->cooldownstate = 2; // Entering cooldowndelay phase 447 493 cs_ftime(&reader->cooldowntime); // Set cooldowntime to calculate delay … … 527 573 } 528 574 529 void hexserial_to_newcamd(u char *source, uchar*dest, uint16_t caid)575 void hexserial_to_newcamd(uint8_t *source, uint8_t *dest, uint16_t caid) 530 576 { 531 577 if(caid_is_bulcrypt(caid)) … … 559 605 } 560 606 561 void newcamd_to_hexserial(u char *source, uchar*dest, uint16_t caid)607 void newcamd_to_hexserial(uint8_t *source, uint8_t *dest, uint16_t caid) 562 608 { 563 609 if(caid_is_bulcrypt(caid)) … … 587 633 /** 588 634 * add or find one entitlement item to entitlements of reader 589 * use add = 0 for find only, or add > 0 to find and add if not found 635 * use add = 0 for find only, or add > 0 to find and add if not found 590 636 **/ 591 637 S_ENTITLEMENT *cs_add_entitlement(struct s_reader *rdr, uint16_t caid, uint32_t provid, uint64_t id, uint32_t class, time_t start, time_t end, uint8_t type, uint8_t add) 592 638 { 593 639 if(!rdr->ll_entitlements) 594 { 595 rdr->ll_entitlements = ll_create("ll_entitlements"); 640 { 641 rdr->ll_entitlements = ll_create("ll_entitlements"); 596 642 } 597 643 598 644 S_ENTITLEMENT *item = NULL; 599 645 LL_ITER it; 600 646 601 647 it = ll_iter_create(rdr->ll_entitlements); 602 648 while((item = ll_iter_next(&it)) != NULL) 603 { 604 if( 605 (caid && item->caid != caid) || 606 (provid && item->provid != provid) || 607 (id && item->id != id) || 608 (class && item->class != class) || 649 { 650 if((caid && item->caid != caid) || (provid && item->provid != provid) || 651 (id && item->id != id) || (class && item->class != class) || 609 652 (start && ((!add && item->start < start) || (add && item->start !=start))) || 610 653 (end && ((!add && item->end < end) || (add && item->end != end))) || … … 615 658 break; // match found! 616 659 } 617 660 618 661 if(add && item == NULL) 619 662 { … … 629 672 item->type = type; 630 673 631 // add item674 // add item 632 675 ll_append(rdr->ll_entitlements, item); 633 676 // cs_log_dbg(D_TRACE, "entitlement: Add caid %4X id %4X %s - %s ", item->caid, item->id, item->start, item->end); … … 636 679 { 637 680 cs_log("ERROR: Can't allocate entitlement to reader!"); 638 639 } 640 } 641 681 } 682 } 683 642 684 return item; 643 685 } … … 655 697 656 698 657 void casc_check_dcw(struct s_reader *reader, int32_t idx, int32_t rc, u char*cw)699 void casc_check_dcw(struct s_reader *reader, int32_t idx, int32_t rc, uint8_t *cw) 658 700 { 659 701 int32_t i, pending = 0; … … 669 711 if((ecm->rc >= E_NOCARD) && ecm->caid == cl->ecmtask[idx].caid && (!memcmp(ecm->ecmd5, cl->ecmtask[idx].ecmd5, CS_ECMSTORESIZE))) 670 712 { 671 if(rc ==2) //E_INVALID from camd35 CMD08713 if(rc == 2) // E_INVALID from camd35 CMD08 672 714 { 673 715 write_ecm_answer(reader, ecm, E_INVALID, 0, cw, NULL, 0, NULL); … … 685 727 } 686 728 687 if(ecm->rc >= E_NOCARD && (t - (uint32_t)ecm->tps.time > ((cfg.ctimeout + 500) / 1000) + 1)) 729 if(ecm->rc >= E_NOCARD && (t - (uint32_t)ecm->tps.time > ((cfg.ctimeout + 500) / 1000) + 1)) // drop timeouts 688 730 { 689 731 ecm->rc = E_FOUND; … … 724 766 { 725 767 if(!rdr->tcp_block_delay) 726 { rdr->tcp_block_delay = 100; } //starting blocking time, 100ms 768 { rdr->tcp_block_delay = 100; } // starting blocking time, 100ms 769 727 770 cs_ftime(&rdr->tcp_block_connect_till); 728 771 add_ms_to_timeb(&rdr->tcp_block_connect_till, rdr->tcp_block_delay); 729 rdr->tcp_block_delay *= 4; //increment timeouts 772 rdr->tcp_block_delay *= 4; // increment timeouts 773 730 774 if(rdr->tcp_block_delay >= rdr->tcp_reconnect_delay) 731 775 { rdr->tcp_block_delay = rdr->tcp_reconnect_delay; } 776 732 777 rdr_log_dbg(rdr, D_TRACE, "tcp connect blocking delay set to %d", rdr->tcp_block_delay); 733 778 } … … 739 784 int32_t diff = comp_timeb(&cur_time, &rdr->tcp_block_connect_till); 740 785 int32_t blocked = rdr->tcp_block_delay && diff < 0; 786 741 787 if(blocked) 742 788 rdr_log_dbg(rdr, D_TRACE, "connection blocked, retrying in %d ms", -diff); 789 743 790 return blocked; 744 791 } … … 757 804 { return -1; } 758 805 759 if(!IP_EQUAL(last_ip, client->ip)) //clean blocking delay on ip change:806 if(!IP_EQUAL(last_ip, client->ip)) // clean blocking delay on ip change: 760 807 { clear_block_delay(rdr); } 761 808 762 if(is_connect_blocked(rdr)) //inside of blocking delay, do not connect!809 if(is_connect_blocked(rdr)) // inside of blocking delay, do not connect! 763 810 { 764 811 return -1; … … 787 834 } 788 835 #endif 789 int s_type 790 int s_proto 836 int s_type = client->is_udp ? SOCK_DGRAM : SOCK_STREAM; 837 int s_proto = client->is_udp ? IPPROTO_UDP : IPPROTO_TCP; 791 838 792 839 if((client->udp_fd = socket(s_domain, s_type, s_proto)) < 0) … … 818 865 memset((char *)&loc_sa, 0, sizeof(loc_sa)); 819 866 SIN_GET_FAMILY(loc_sa) = s_family; 867 820 868 if(IP_ISSET(cfg.srvip)) 821 869 { IP_ASSIGN(SIN_GET_ADDR(loc_sa), cfg.srvip); } … … 825 873 if(client->reader->l_port) 826 874 { SIN_GET_PORT(loc_sa) = htons(client->reader->l_port); } 875 827 876 if(client->is_udp && bind(client->udp_fd, (struct sockaddr *)&loc_sa, sizeof(loc_sa)) < 0) 828 877 { … … 886 935 { 887 936 rdr_log(rdr, "connect failed: %s", strerror(errno)); 888 block_connect(rdr); // connect has failed. Block connect for a while937 block_connect(rdr); // connect has failed. Block connect for a while 889 938 close(client->udp_fd); 890 939 client->udp_fd = 0; … … 893 942 } 894 943 895 set_nonblock(client->udp_fd, false); // restore blocking mode944 set_nonblock(client->udp_fd, false); // restore blocking mode 896 945 897 946 setTCPTimeouts(client->udp_fd); … … 911 960 if(!reader) 912 961 { 913 // only proxy reader should call this, client connections are closed on thread cleanup962 // only proxy reader should call this, client connections are closed on thread cleanup 914 963 cs_log("WARNING: invalid client"); 915 964 cs_disconnect_client(cur_client()); … … 967 1016 { 968 1017 ecm = &cl->ecmtask[i]; 969 if((ecm->rc >= E_NOCARD) && (t - (uint32_t)ecm->tps.time > ((cfg.ctimeout + 500) / 1000) + 1)) 1018 if((ecm->rc >= E_NOCARD) && (t - (uint32_t)ecm->tps.time > ((cfg.ctimeout + 500) / 1000) + 1)) // drop timeouts 970 1019 { 971 1020 ecm->rc = E_FOUND; … … 976 1025 { 977 1026 ecm = &cl->ecmtask[i]; 978 if(n < 0 && (ecm->rc < E_NOCARD)) 1027 if(n < 0 && (ecm->rc < E_NOCARD)) // free slot found 979 1028 { n = i; } 980 1029 981 1030 // ecm already pending 982 // ... 983 if((ecm->rc >= E_NOCARD) && 1031 // ...this level at least 1032 if((ecm->rc >= E_NOCARD) && er->caid == ecm->caid && (!memcmp(er->ecmd5, ecm->ecmd5, CS_ECMSTORESIZE))) 984 1033 { sflag = 0; } 985 1034 … … 996 1045 997 1046 memcpy(&cl->ecmtask[n], er, sizeof(ECM_REQUEST)); 998 cl->ecmtask[n].matching_rdr = NULL; // This avoids double free of matching_rdr!1047 cl->ecmtask[n].matching_rdr = NULL; // This avoids double free of matching_rdr! 999 1048 #ifdef CS_CACHEEX 1000 cl->ecmtask[n].csp_lastnodes = NULL; // This avoids double free of csp_lastnodes!1049 cl->ecmtask[n].csp_lastnodes = NULL; // This avoids double free of csp_lastnodes! 1001 1050 #endif 1002 1051 cl->ecmtask[n].parent = er; … … 1016 1065 cs_log_dump_dbg(D_ATR, er->ecm, er->ecmlen, "casc ecm (%s):", (reader) ? reader->label : "n/a"); 1017 1066 rc = 0; 1067 1018 1068 if(sflag) 1019 1069 { 1020 1070 rc = reader->ph.c_send_ecm(cl, &cl->ecmtask[n]); 1021 1071 if(rc != 0) 1022 { 1072 { 1023 1073 casc_check_dcw(reader, n, 0, cl->ecmtask[n].cw); // simulate "not found" 1024 } 1074 } 1025 1075 else 1026 1076 { cl->last_idx = cl->ecmtask[n].idx; } 1027 reader->last_s = t; 1077 reader->last_s = t; // used for inactive_timeout and reconnect_timeout in TCP reader 1028 1078 } 1029 1079 … … 1046 1096 } 1047 1097 1048 // CHECK if ecm already sent to reader1098 // CHECK if ecm already sent to reader 1049 1099 struct s_ecm_answer *ea_er = get_ecm_answer(reader, er); 1050 1100 if(!ea_er) { return; } … … 1055 1105 1056 1106 cs_readlock(__func__, &ecmcache_lock); 1107 1057 1108 for(ecm = ecmcwcache; ecm; ecm = ecm->next) 1058 1109 { … … 1063 1114 if(!ecm->matching_rdr || ecm == er || ecm->rc == E_99) { continue; } 1064 1115 1065 // match same ecm1116 // match same ecm 1066 1117 if(er->caid == ecm->caid && !memcmp(er->ecmd5, ecm->ecmd5, CS_ECMSTORESIZE)) 1067 1118 { … … 1072 1123 } 1073 1124 } 1125 1074 1126 cs_readunlock(__func__, &ecmcache_lock); 1075 if(ea) //found ea in cached ecm, asking for this reader 1127 1128 if(ea) // found ea in cached ecm, asking for this reader 1076 1129 { 1077 1130 ea_er->is_pending = true; … … 1106 1159 } 1107 1160 1108 if(is_cascading_reader(reader)) 1161 if(is_cascading_reader(reader)) // forward request to proxy reader 1109 1162 { 1110 1163 cl->last_srvid = er->srvid; … … 1116 1169 } 1117 1170 1118 cardreader_process_ecm(reader, cl, er); 1171 cardreader_process_ecm(reader, cl, er); // forward request to physical reader 1119 1172 } 1120 1173 … … 1199 1252 #if !defined(WITH_CARDREADER) && (defined(WITH_STAPI) || defined(WITH_STAPI5)) 1200 1253 /* Dummy function stub for stapi compiles without cardreader as libstapi needs it. */ 1201 int32_t ATR_InitFromArray(ATR *atr, const u nsigned charatr_buffer[ATR_MAX_SIZE], uint32_t length)1254 int32_t ATR_InitFromArray(ATR *atr, const uint8_t atr_buffer[ATR_MAX_SIZE], uint32_t length) 1202 1255 { 1203 1256 (void)atr; … … 1251 1304 rdr->next = first_active_reader; 1252 1305 first_active_reader = rdr; 1253 //resort client list: 1306 1307 // resort client list: 1254 1308 struct s_client *prev, *cl; 1309 1255 1310 for(prev = first_client, cl = first_client->next; 1256 1311 prev->next != NULL; prev = prev->next, cl = cl->next) … … 1259 1314 { break; } 1260 1315 } 1316 1261 1317 if(cl && rdr->client == cl) 1262 1318 { 1263 prev->next = cl->next; // remove client from list1319 prev->next = cl->next; // remove client from list 1264 1320 cl->next = first_client->next; 1265 1321 first_client->next = cl; … … 1268 1324 else 1269 1325 { 1270 for(rdr2 = first_active_reader; rdr2->next && rdr2 != rdr_prv ; rdr2 = rdr2->next) { ; } //search last element 1326 for(rdr2 = first_active_reader; rdr2->next && rdr2 != rdr_prv ; rdr2 = rdr2->next) { ; } // search last element 1327 1271 1328 rdr_prv = rdr2; 1272 1329 rdr_tmp = rdr2->next; 1273 1330 rdr2->next = rdr; 1274 1331 rdr->next = rdr_tmp; 1275 //resort client list: 1332 1333 // resort client list: 1276 1334 struct s_client *prev, *cl; 1335 1277 1336 for(prev = first_client, cl = first_client->next; 1278 1337 prev->next != NULL; prev = prev->next, cl = cl->next) … … 1281 1340 { break; } 1282 1341 } 1342 1283 1343 if(cl && rdr->client == cl) 1284 1344 { 1285 prev->next = cl->next; // remove client from list1345 prev->next = cl->next; // remove client from list 1286 1346 cl->next = rdr_prv->client->next; 1287 1347 rdr_prv->client->next = cl; … … 1327 1387 remove_reader_from_active(rdr); // remove from list 1328 1388 kill_thread(cl); // kill old thread 1329 cs_sleepms(1500); //we have to wait a bit so free_client is ended and socket closed too!1389 cs_sleepms(1500); // we have to wait a bit so free_client is ended and socket closed too! 1330 1390 } 1331 1391 … … 1432 1492 int32_t reader_slots_available(struct s_reader *reader, ECM_REQUEST *er) 1433 1493 { 1434 if(ecm_ratelimit_check(reader, er, 0) != OK) //check ratelimiter & cooldown -> in check mode: dont register srvid!!!1494 if(ecm_ratelimit_check(reader, er, 0) != OK) // check ratelimiter & cooldown -> in check mode: dont register srvid!!! 1435 1495 { 1436 1496 return 0; // no slot free
Note:
See TracChangeset
for help on using the changeset viewer.