...
|
...
|
@@ -263,6 +263,7 @@ struct node { /* a node */
|
263
|
263
|
struct node *next;
|
264
|
264
|
struct node *prev;
|
265
|
265
|
uint32_t size;
|
|
266
|
+ uint32_t minrec;
|
266
|
267
|
};
|
267
|
268
|
|
268
|
269
|
struct cache_set { /* a tree */
|
...
|
...
|
@@ -367,7 +368,7 @@ static int printtree(struct cache_set *cs, struct node *n, int d) {
|
367
|
367
|
|
368
|
368
|
/* Looks up a node and splays it up to the root of the tree */
|
369
|
369
|
static int splay(int64_t *md5, size_t len, struct cache_set *cs) {
|
370
|
|
- struct node next = {{0, 0}, NULL, NULL, NULL, NULL, NULL, 0}, *right = &next, *left = &next, *temp, *root = cs->root;
|
|
370
|
+ struct node next = {{0, 0}, NULL, NULL, NULL, NULL, NULL, 0, 0}, *right = &next, *left = &next, *temp, *root = cs->root;
|
371
|
371
|
int comp, found = 0;
|
372
|
372
|
|
373
|
373
|
if(!root)
|
...
|
...
|
@@ -426,7 +427,7 @@ static int splay(int64_t *md5, size_t len, struct cache_set *cs) {
|
426
|
426
|
|
427
|
427
|
|
428
|
428
|
/* Looks up an hash in the tree and maintains the replacement chain */
|
429
|
|
-static int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size_t size) {
|
|
429
|
+static inline int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size_t size, uint32_t reclevel) {
|
430
|
430
|
int64_t hash[2];
|
431
|
431
|
|
432
|
432
|
memcpy(hash, md5, 16);
|
...
|
...
|
@@ -450,8 +451,6 @@ static int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size_t size
|
450
|
450
|
printf("\n");
|
451
|
451
|
}
|
452
|
452
|
#endif
|
453
|
|
-#define TO_END_OF_CHAIN
|
454
|
|
-#ifdef TO_END_OF_CHAIN
|
455
|
453
|
if(q) {
|
456
|
454
|
if(o)
|
457
|
455
|
o->next = q;
|
...
|
...
|
@@ -463,18 +462,6 @@ static int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size_t size
|
463
|
463
|
p->next = NULL;
|
464
|
464
|
cs->last = p;
|
465
|
465
|
}
|
466
|
|
-#else
|
467
|
|
- if(cs->last != p) {
|
468
|
|
- if(cs->last == q) cs->last = p;
|
469
|
|
- if(o) o->next = q;
|
470
|
|
- else cs->first = q;
|
471
|
|
- p->next = q->next;
|
472
|
|
- if(q->next) q->next->prev = p;
|
473
|
|
- q->next = p;
|
474
|
|
- q->prev = o;
|
475
|
|
- p->prev = q;
|
476
|
|
- }
|
477
|
|
-#endif
|
478
|
466
|
#ifdef PRINT_CHAINS
|
479
|
467
|
{
|
480
|
468
|
struct node *x = cs->first;
|
...
|
...
|
@@ -492,7 +479,8 @@ static int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size_t size
|
492
|
492
|
printf("\n");
|
493
|
493
|
}
|
494
|
494
|
#endif
|
495
|
|
- return 1;
|
|
495
|
+ if(reclevel >= p->minrec)
|
|
496
|
+ return 1;
|
496
|
497
|
}
|
497
|
498
|
return 0;
|
498
|
499
|
}
|
...
|
...
|
@@ -500,13 +488,16 @@ static int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size_t size
|
500
|
500
|
/* If the hash is present nothing happens.
|
501
|
501
|
Otherwise a new node is created for the hash picking one from the begin of the chain.
|
502
|
502
|
Used nodes are moved to the end of the chain */
|
503
|
|
-static void cacheset_add(struct cache_set *cs, unsigned char *md5, size_t size) {
|
|
503
|
+static inline void cacheset_add(struct cache_set *cs, unsigned char *md5, size_t size, uint32_t reclevel) {
|
504
|
504
|
struct node *newnode;
|
505
|
505
|
int64_t hash[2];
|
506
|
506
|
|
507
|
507
|
memcpy(hash, md5, 16);
|
508
|
|
- if(splay(hash, size, cs))
|
|
508
|
+ if(splay(hash, size, cs)) {
|
|
509
|
+ if(cs->root->minrec > reclevel)
|
|
510
|
+ cs->root->minrec = reclevel;
|
509
|
511
|
return; /* Already there */
|
|
512
|
+ }
|
510
|
513
|
|
511
|
514
|
ptree("1:\n");
|
512
|
515
|
if(printtree(cs, cs->root, 0)) {
|
...
|
...
|
@@ -607,6 +598,7 @@ static void cacheset_add(struct cache_set *cs, unsigned char *md5, size_t size)
|
607
|
607
|
newnode->digest[1] = hash[1];
|
608
|
608
|
newnode->up = NULL;
|
609
|
609
|
newnode->size = size;
|
|
610
|
+ newnode->minrec = reclevel;
|
610
|
611
|
cs->root = newnode;
|
611
|
612
|
|
612
|
613
|
ptree("3: %lld\n", hash[1]);
|
...
|
...
|
@@ -674,7 +666,7 @@ void cli_cache_destroy(struct cl_engine *engine) {
|
674
|
674
|
}
|
675
|
675
|
|
676
|
676
|
/* Looks up an hash in the proper tree */
|
677
|
|
-static int cache_lookup_hash(unsigned char *md5, size_t len, struct CACHE *cache) {
|
|
677
|
+static int cache_lookup_hash(unsigned char *md5, size_t len, struct CACHE *cache, uint32_t reclevel) {
|
678
|
678
|
unsigned int key = getkey(md5);
|
679
|
679
|
int ret = CL_VIRUS;
|
680
|
680
|
struct CACHE *c;
|
...
|
...
|
@@ -685,7 +677,7 @@ static int cache_lookup_hash(unsigned char *md5, size_t len, struct CACHE *cache
|
685
|
685
|
return ret;
|
686
|
686
|
}
|
687
|
687
|
|
688
|
|
- ret = (cacheset_lookup(&c->cacheset, md5, len)) ? CL_CLEAN : CL_VIRUS;
|
|
688
|
+ ret = (cacheset_lookup(&c->cacheset, md5, len, reclevel)) ? CL_CLEAN : CL_VIRUS;
|
689
|
689
|
pthread_mutex_unlock(&c->mutex);
|
690
|
690
|
/* if(ret == CL_CLEAN) cli_warnmsg("cached\n"); */
|
691
|
691
|
return ret;
|
...
|
...
|
@@ -694,6 +686,7 @@ static int cache_lookup_hash(unsigned char *md5, size_t len, struct CACHE *cache
|
694
|
694
|
/* Adds an hash to the cache */
|
695
|
695
|
void cache_add(unsigned char *md5, size_t size, cli_ctx *ctx) {
|
696
|
696
|
unsigned int key = getkey(md5);
|
|
697
|
+ uint32_t level;
|
697
|
698
|
struct CACHE *c;
|
698
|
699
|
|
699
|
700
|
if(!ctx || !ctx->engine || !ctx->engine->cache)
|
...
|
...
|
@@ -709,14 +702,15 @@ void cache_add(unsigned char *md5, size_t size, cli_ctx *ctx) {
|
709
|
709
|
cacheset_add(&c->cacheset, md5, size, ctx->engine->mempool);
|
710
|
710
|
#else
|
711
|
711
|
#ifdef USE_SPLAY
|
712
|
|
- cacheset_add(&c->cacheset, md5, size);
|
|
712
|
+ cacheset_add(&c->cacheset, md5, size, level);
|
713
|
713
|
#else
|
714
|
714
|
#error #define USE_SPLAY or USE_LRUHASHCACHE
|
715
|
715
|
#endif
|
716
|
716
|
#endif
|
717
|
717
|
|
718
|
718
|
pthread_mutex_unlock(&c->mutex);
|
719
|
|
- cli_dbgmsg("cache_add: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", md5[0], md5[1], md5[2], md5[3], md5[4], md5[5], md5[6], md5[7], md5[8], md5[9], md5[10], md5[11], md5[12], md5[13], md5[14], md5[15]);
|
|
719
|
+ level = (*ctx->fmap && (*ctx->fmap)->dont_cache_flag) ? ctx->recursion : 0;
|
|
720
|
+ cli_dbgmsg("cache_add: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x (level %u)\n", md5[0], md5[1], md5[2], md5[3], md5[4], md5[5], md5[6], md5[7], md5[8], md5[9], md5[10], md5[11], md5[12], md5[13], md5[14], md5[15], level);
|
720
|
721
|
return;
|
721
|
722
|
}
|
722
|
723
|
|
...
|
...
|
@@ -745,7 +739,7 @@ int cache_check(unsigned char *hash, cli_ctx *ctx) {
|
745
|
745
|
cli_md5_update(&md5, buf, readme);
|
746
|
746
|
}
|
747
|
747
|
cli_md5_final(hash, &md5);
|
748
|
|
- ret = cache_lookup_hash(hash, map->len, ctx->engine->cache);
|
|
748
|
+ ret = cache_lookup_hash(hash, map->len, ctx->engine->cache, ctx->recursion);
|
749
|
749
|
cli_dbgmsg("cache_check: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x is %s\n", hash[0], hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7], hash[8], hash[9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15], (ret == CL_VIRUS) ? "negative" : "positive");
|
750
|
750
|
return ret;
|
751
|
751
|
}
|