Skyld AV  0.6
On access virus scanning for Linux
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ScanCache.cc
Go to the documentation of this file.
1 /*
2  * File: ScanCache.h
3  *
4  * Copyright 2013 Heinrich Schuchardt <xypron.glpk@gmx.de>
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19 
24 #include <iostream>
25 #include <sstream>
26 #include <time.h>
27 #include "Messaging.h"
28 #include "ScanCache.h"
29 
35  e = env;
36  s = new std::set<ScanResult *, ScanResultComperator>();
37  hits = 0;
38  misses = 0;
39  // Initialize mutex.
40  pthread_mutex_init(&mutex, NULL);
41  // Initialize the double linked list of scan results.
42  clear();
43 }
44 
50 void ScanCache::add(const struct stat *stat, const unsigned int response) {
51  std::set<ScanResult *, ScanResultComperator>::iterator it;
52  std::pair < std::set<ScanResult *, ScanResultComperator>::iterator, bool> pair;
53  unsigned int cacheMaxSize = e->getCacheMaxSize();
54 
55  if (0 == cacheMaxSize) {
56  return;
57  }
58 
59  ScanResult *scr = new ScanResult();
60  scr->dev = stat->st_dev;
61  scr->ino = stat->st_ino;
62  scr->mtime = stat->st_mtime;
63  scr->response = response;
64  gmtime(&(scr->age));
65 
66  pthread_mutex_lock(&mutex);
67  it = s->find(scr);
68  if (it != s->end()) {
69  // Old matching entry found. Remove from linked list and delete.
70  (*it)->left->right = (*it)->right;
71  (*it)->right->left = (*it)->left;
72  delete *it;
73  s->erase(it);
74  } else while (s->size() >= cacheMaxSize) {
75  // Cache size too big. Get last element.
76  it = s->find(root.left);
77  if (it != s->end()) {
78  // Remove from linked list and delete.
79  (*it)->left->right = (*it)->right;
80  (*it)->right->left = (*it)->left;
81  delete *it;
82  s->erase(it);
83  } else {
84  break;
85  }
86  }
87  pair = s->insert(scr);
88  if (pair.second) {
89  // Successful insertion. Introduce leftmost in linked list.
90  root.right->left = scr;
91  scr->right = root.right;
92  scr->left = &root;
93  root.right = scr;
94  } else {
95  // element already existed
96  delete scr;
97  }
98  pthread_mutex_unlock(&mutex);
99 }
100 
105  pthread_mutex_lock(&mutex);
106  std::set<ScanResult *, ScanResultComperator>::iterator pos;
107  for (pos = s->begin(); pos != s->end(); ++pos) {
108  delete *pos;
109  }
110  s->clear();
111  // Initialize the double linked list of scan results.
112  root.left = &root;
113  root.right = &root;
114  Messaging::message(Messaging::DEBUG, "Cache cleared.");
115  pthread_mutex_unlock(&mutex);
116 }
117 
123 int ScanCache::get(const struct stat *stat) {
124  int ret;
125  std::set<ScanResult *, ScanResultComperator>::iterator it;
126  ScanResult *scr = new ScanResult();
127  scr->dev = stat->st_dev;
128  scr->ino = stat->st_ino;
129 
130  pthread_mutex_lock(&mutex);
131  it = s->find(scr);
132  delete scr;
133  if (it == s->end()) {
134  ret = CACHE_MISS;
135  misses++;
136  } else {
137  scr = *it;
138  // Check modification time.
139  if (scr->mtime == stat->st_mtime) {
140  // Element is valid. Remove it from linked list.
141  scr->left->right = scr->right;
142  scr->right->left = scr->left;
143  // Insert it leftmost.
144  root.right->left = scr;
145  scr->right = root.right;
146  scr->left = &root;
147  root.right = scr;
148  ret = scr->response;
149  hits++;
150  } else {
151  // Remove outdated element from linked list and delete it.
152  (*it)->left->right = (*it)->right;
153  (*it)->right->left = (*it)->left;
154  delete *it;
155  s->erase(it);
156  ret = CACHE_MISS;
157  misses++;
158  }
159  }
160  pthread_mutex_unlock(&mutex);
161  return ret;
162 }
163 
168 void ScanCache::remove(const struct stat *stat) {
169  std::set<ScanResult *, ScanResultComperator>::iterator it;
170  ScanResult *scr = new ScanResult();
171  scr->dev = stat->st_dev;
172  scr->ino = stat->st_ino;
173 
174  pthread_mutex_lock(&mutex);
175  it = s->find(scr);
176  if (it != s->end()) {
177  // Remove from linked list and delete.
178  (*it)->left->right = (*it)->right;
179  (*it)->right->left = (*it)->left;
180  delete *it;
181  s->erase(it);
182  }
183  pthread_mutex_unlock(&mutex);
184  delete scr;
185 }
186 
188  std::stringstream msg;
189  msg << "Cache size " << s->size() <<
190  ", cache hits " << hits << ", cache misses " << misses << ".";
191  clear();
192  pthread_mutex_destroy(&mutex);
194 }
ScanCache(Environment *)
Definition: ScanCache.cc:34
unsigned int response
Result of scan.
Definition: ScanCache.h:55
void remove(const struct stat *)
Remove scan result from cache.
Definition: ScanCache.cc:168
std::set< ScanResult *, ScanResultComperator > * s
Definition: ScanCache.h:124
Send messages.
ScanResult * left
Left neighbour in double linked list.
Definition: ScanCache.h:63
ScanResult root
Root for double linked list.
Definition: ScanCache.h:144
time_t age
Time when this record entered the cache.
Definition: ScanCache.h:59
void clear()
Removes all entries from the cache.
Definition: ScanCache.cc:104
Result of scanning a file for viruses.
Definition: ScanCache.h:38
virtual ~ScanCache()
Definition: ScanCache.cc:187
Information, e.g. access scanning has started.
Definition: Messaging.h:48
static void message(const enum Level, const std::string &)
Sends message.
Definition: Messaging.cc:101
void add(const struct stat *, const unsigned int)
Adds scan result to cache.
Definition: ScanCache.cc:50
time_t mtime
Time of last modification.
Definition: ScanCache.h:51
unsigned long long misses
Number of cache misses.
Definition: ScanCache.h:136
Cache for virus scanning results.
dev_t dev
ID of device containing file.
Definition: ScanCache.h:43
ScanResult * right
Right neighbour in double linked list.
Definition: ScanCache.h:67
static const unsigned int CACHE_MISS
No matching element found in cache.
Definition: ScanCache.h:113
Environment * e
Environment.
Definition: ScanCache.h:132
Debugging information only to be shown in the console.
Definition: Messaging.h:44
The environment holds variables that are shared by instances of multiple classes. ...
Definition: Environment.h:38
int get(const struct stat *)
Adds scan result to cache.
Definition: ScanCache.cc:123
pthread_mutex_t mutex
Mutex used when reading from or writing to the cache.
Definition: ScanCache.h:128
unsigned long long hits
Number of cache hits.
Definition: ScanCache.h:140
ino_t ino
Inode number.
Definition: ScanCache.h:47
unsigned int getCacheMaxSize()
Gets the maximum number of entries in the cache with scan results.
Definition: Environment.cc:92