Changeset 1566
- Timestamp:
- 02/24/08 17:07:47 (8 months ago)
- Files:
-
- nebula/trunk/src/classify.c (modified) (11 diffs)
- nebula/trunk/src/cluster.c (modified) (7 diffs)
- nebula/trunk/src/cluster.h (modified) (2 diffs)
- nebula/trunk/src/nebula.c (modified) (12 diffs)
- nebula/trunk/src/nebula.h (modified) (2 diffs)
- nebula/trunk/src/nebulad.c (deleted)
- nebula/trunk/src/queue.c (modified) (12 diffs)
- nebula/trunk/src/queue.h (modified) (1 diff)
- nebula/trunk/src/session.c (modified) (10 diffs)
- nebula/trunk/src/session.h (modified) (3 diffs)
- nebula/trunk/src/sig.c (modified) (14 diffs)
- nebula/trunk/src/sig.h (modified) (2 diffs)
- nebula/trunk/src/signals.c (modified) (2 diffs)
- nebula/trunk/src/signals.h (modified) (1 diff)
- nebula/trunk/src/util.c (modified) (2 diffs)
- nebula/trunk/src/util.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
nebula/trunk/src/classify.c
r1563 r1566 34 34 #include <ctype.h> 35 35 36 36 37 // pthread wrapper function 37 38 void *pt_classify(void *s) { 38 int rv; 39 int rv; 40 41 // this thread needs to unlock the sessions mutex 42 // so that the session ID can be reused in the main thread 43 pthread_mutex_unlock(&sessions_mutex); 39 44 40 45 // call classification function 41 if ((rv = classify( (submission *)s)) == -1) {46 if ((rv = classify(s)) == -1) { 42 47 fprintf(stderr, "Error - Unable to classify submission.\n"); 43 48 return((void *) -1); 44 49 } else if (rv == 0) { 45 50 // known attack, do nothing 51 return((void *) 0); 46 52 } else { 47 // new attack , keep hash pointer by NULL'ing session hash pointer48 ((submission *) s)->md5sum = NULL;49 } 50 return((void *) 0);53 // new attack 54 free(s); 55 } 56 return((void *) 1); 51 57 } 52 58 … … 60 66 double score; 61 67 pthread_t ntid; 68 pthread_attr_t ptattr; 62 69 63 70 tmpbuf = NULL; 64 71 72 if (!s) { 73 fprintf(stderr, "Error - Cannot classify empty session.\n"); 74 return(-1); 75 } 76 65 77 pthread_rwlock_rdlock(&md5sum_trie_lock); 66 if ((t = trie_find_memstr(&md5sum_trie, (u_char *) s->md5sum, strlen(s->md5sum))) != NULL) { 78 t = trie_find_memstr(&md5sum_trie, (u_char *) s->md5sum, strlen(s->md5sum)); 79 pthread_rwlock_unlock(&md5sum_trie_lock); 80 81 if (t != NULL) { 67 82 // md5sum is already in trie 68 83 ((hash*)t->data)->cnt++; 69 pthread_rwlock_unlock(&md5sum_trie_lock);70 84 71 85 if (verbose) printf(" md5sum is %s (%u instances)\n", ((hash*)t->data)->md5sum, ((hash*)t->data)->cnt); … … 74 88 } else { 75 89 // md5sum not in trie, create new element 76 pthread_rwlock_unlock(&md5sum_trie_lock);77 90 pthread_rwlock_wrlock(&md5sum_trie_lock); 78 91 t = trie_memins(&md5sum_trie, (u_char *) s->md5sum, strlen(s->md5sum), NULL); 92 pthread_rwlock_unlock(&md5sum_trie_lock); 93 79 94 if ((t->data = calloc(1, sizeof(hash))) == NULL) { 80 95 fprintf(stderr, "Error - Unable to allocate memory: %m.\n"); … … 90 105 memcpy(((hash*)t->data)->submission, s, sizeof(submission)); 91 106 ((hash*)t->data)->cnt++; 92 pthread_rwlock_unlock(&md5sum_trie_lock);93 94 /*95 // set filename96 if ((((hash*)t->data)->filename = strdup(filename)) == NULL) {97 fprintf(stderr, "Error - Unable to allocate memory: %m.\n");98 exit(EXIT_FAILURE);99 }100 */101 107 102 108 // set spamsum hash … … 106 112 } 107 113 if (verbose) printf(" md5sum is %s (%u instances)\n", ((hash*)t->data)->md5sum, ((hash*)t->data)->cnt); 114 115 116 Q_WLOCK(&clusterq->lock); 108 117 109 118 // connect all clusters within range … … 113 122 if (!((hash*)t->data)->cl) { 114 123 add_entry_to_cluster((cluster *)cur_cqelem->data, (hash*)t->data); 124 if (verbose) printf(" cluster has now %u elements.\n", ((hash*)t->data)->cl->cnt); 115 125 break; 116 126 } else { … … 127 137 if ((score = spamsum_match(((hash*)t->data)->spamsum, ((hash*)cur_hqelem->data)->spamsum)) >= cluster_radius) { 128 138 // unlink match from outlier list 139 129 140 tmp_hqelem = cur_hqelem; 130 141 cur_hqelem = cur_hqelem->next; … … 136 147 // add other outliers to cluster 137 148 if (add_entry_to_cluster(((hash*)t->data)->cl, tmp_hash) == NULL) { 149 138 150 pthread_rwlock_wrlock(&md5sum_trie_lock); 151 trie_del_memstr(&md5sum_trie, (u_char *) tmp_hash->md5sum, strlen(tmp_hash->md5sum)); 152 pthread_rwlock_unlock(&md5sum_trie_lock); 153 139 154 pthread_rwlock_wrlock(&spamsum_trie_lock); 140 141 trie_del_memstr(&md5sum_trie, (u_char *) tmp_hash->md5sum, strlen(tmp_hash->md5sum));142 155 trie_del_memstr(&spamsum_trie, (u_char *) tmp_hash->spamsum, strlen(tmp_hash->spamsum)); 156 pthread_rwlock_unlock(&spamsum_trie_lock); 157 143 158 hash_free(tmp_hash); 144 159 145 pthread_rwlock_unlock(&md5sum_trie_lock); 146 pthread_rwlock_unlock(&spamsum_trie_lock); 147 148 } 160 161 } else if (verbose) printf(" cluster has now %u elements.\n", ((hash*)t->data)->cl->cnt); 149 162 } else { 150 163 // create new cluster of two outliers … … 154 167 /* first remove hashes from tries */ 155 168 for (tmp_hqelem = ((cluster *)tmp_cqelem->data)->hq->head; tmp_hqelem; tmp_hqelem=tmp_hqelem->next) { 169 156 170 pthread_rwlock_wrlock(&md5sum_trie_lock); 157 171 trie_del_memstr(&md5sum_trie, (u_char *) ((hash *)tmp_hqelem->data)->md5sum, … … 171 185 * we need this to be able to unlink a cluster from the queue */ 172 186 ((cluster *) clusterq->head->data)->parent = clusterq->head; 187 188 if (verbose) printf(" cluster created.\n"); 173 189 } 174 190 } 175 191 if (!cur_hqelem) break; 176 192 } 193 194 195 Q_ULOCK(&clusterq->lock); 196 177 197 178 198 … … 191 211 trie_del_memstr(&spamsum_trie, (u_char *) tmp_hash->spamsum, strlen(tmp_hash->spamsum)); 192 212 pthread_rwlock_unlock(&spamsum_trie_lock); 213 193 214 hash_free(tmp_hash); 194 215 } 195 216 queue_ins(outlierq, t->data, outlierq_max); 217 218 if (verbose) printf(" input added to outlier queue.\n"); 196 219 } 197 220 } 198 221 199 222 // check for signature generation criteria here 200 if ((((hash*)t->data)->cl) && ((hash*)t->data)->cl->cnt > 5) { 201 printf("[=] cluster hit size threshold, generating signature.\n"); 202 if (pthread_create(&ntid, NULL, pt_siggen, (void *) ((hash*)t->data)->cl)) { 203 fprintf(stderr, "Error - Cannot create signature generation thread: %s.\n", strerror(errno)); 204 exit(EXIT_FAILURE); 205 } 223 if ((((hash*)t->data)->cl) && ((hash*)t->data)->cl->cnt > ((hash*)t->data)->cl->threshold) { 224 printf("[=] cluster size (%u) hit threshold (%lu), generating signature.\n", 225 ((hash*)t->data)->cl->cnt, ((hash*)t->data)->cl->threshold); 226 227 // set threshold to current size plus 1 228 ((hash*)t->data)->cl->threshold = ((hash*)t->data)->cl->cnt + 1; 229 230 if (pthread_attr_init(&ptattr) || 231 pthread_attr_setdetachstate(&ptattr, PTHREAD_CREATE_DETACHED)) { 232 fprintf(stderr, "Error - Unable to initialize thread attributes: %s.\n", strerror(errno)); 233 exit(EXIT_FAILURE); 234 } 235 if (pthread_create(&ntid, NULL, pt_siggen, (void *) ((hash*)t->data)->cl)) { 236 fprintf(stderr, "Error - Cannot create signature generation thread: %s.\n", strerror(errno)); 237 exit(EXIT_FAILURE); 238 } 239 pthread_attr_destroy(&ptattr); 206 240 } 207 241 nebula/trunk/src/cluster.c
r1558 r1566 37 37 } 38 38 39 if (pthread_rwlock_init(&new->lock, NULL) != 0) { 40 fprintf(stderr, "Error - Unable to initialize thread lock: %m.\n"); 41 exit(EXIT_FAILURE); 42 } 43 39 44 /* create element queue */ 40 45 if ((new->hq = calloc(1, sizeof(queue))) == NULL) { … … 42 47 exit(EXIT_FAILURE); 43 48 } 49 50 // initialize size threshold 51 new->threshold = initial_threshold; 44 52 45 53 return(new); … … 51 59 if (!cl) return; 52 60 61 if (lock_mutex) CL_WLOCK(cl); 53 62 queue_free(((cluster *)cl)->hq, hash_free); 63 if (lock_mutex) CL_ULOCK(cl); 54 64 free(cl); 55 65 … … 61 71 qelem *new; 62 72 73 CL_WLOCK(cl); 63 74 if (cl->hq->size < clusterhashq_max) { 64 75 // set cluster pointer in hash struct … … 75 86 return(NULL); 76 87 } 88 CL_ULOCK(cl); 77 89 78 90 return(cl); … … 93 105 qelem *entry; 94 106 107 CL_WLOCK(dst); 108 CL_WLOCK(src); 109 95 110 // concatenate hash queues 96 111 dst->hq->tail->next = src->hq->head; … … 98 113 dst->hq->size += src->hq->size; 99 114 115 // add thresholds 116 dst->threshold += max(src->threshold, src->cnt); 117 100 118 // let elements of src point to dst 101 119 for (entry = src->hq->head; entry; entry = entry->next) ((hash*)entry->data)->cl = dst; 102 120 src->hq->head = src->hq->tail = NULL; 121 122 CL_ULOCK(dst); 123 CL_ULOCK(src); 103 124 104 125 // unlink and free old cluster nebula/trunk/src/cluster.h
r1560 r1566 26 26 #endif 27 27 28 #include <pthread.h> 28 29 #include <stdlib.h> 29 30 … … 32 33 #include "queue.h" 33 34 35 36 #define CL_WLOCK(x) pthread_rwlock_wrlock(&((cluster *)x)->lock); 37 #define CL_RLOCK(x) pthread_rwlock_rdlock(&((cluster *)x)->lock); 38 #define CL_ULOCK(x) pthread_rwlock_unlock(&((cluster *)x)->lock); 39 40 34 41 /* this struct can be extended when using different metrics, 35 42 * i.e. you may want to add a center when using the cosine measure 36 43 * for ngram vectors */ 37 44 typedef struct cluster { 38 u_int32_t cnt; 39 u_int32_t sig_id; 40 u_int32_t sig_rev; 41 void *parent; 42 struct cluster *prev; 43 struct cluster *next; 44 queue *hq; 45 pthread_rwlock_t lock; 46 u_int32_t cnt; 47 u_int32_t sig_id; 48 u_int32_t sig_rev; 49 unsigned long int threshold; 50 void *parent; 51 struct cluster *prev; 52 struct cluster *next; 53 queue *hq; 45 54 } cluster; 46 55 nebula/trunk/src/nebula.c
r1563 r1566 51 51 52 52 53 #define POLLFD_SET_SIZE 1054 55 56 53 void usage(const char* progname, const int exit_val) { 57 54 printf("Usage: %s " 58 55 " -a <filename>\t append new snort signatures to this file\n" 59 "\t\t -C <size>\t cluster queue size\n"56 "\t\t -C <size>\t cluster queue size\n" 60 57 "\t\t -c <similarity> cluster criteria (a similarity measure in percent)\n" 61 58 "\t\t -d\t\t daemonize\n" … … 67 64 "\t\t -r <snort pid>\t send a SIGHUP to this process ID after a new rule was generated\n" 68 65 "\t\t -s <secret>\t secret string for use in submissions\n" 66 "\t\t -t <threshold>\t initial cluster element threshold\n" 69 67 "\t\t -v\t\t be verbose\n" 70 68 "\t\t\t\t [files ...]\n", … … 74 72 } 75 73 74 76 75 int main(int argc, char *argv[]) { 77 76 int i, qsize, port, listen_fd, rv; 78 struct pollfd pfdset[POLLFD_SET_SIZE];79 77 u_char daemonize; 80 78 char option; 81 submission s[POLLFD_SET_SIZE-1], tmp_submission;82 79 pthread_t ntid; 83 84 85 memset(pfdset, 0, sizeof(struct pollfd) * POLLFD_SET_SIZE); 86 memset(s, 0, sizeof(submission) * (POLLFD_SET_SIZE-1)); 80 submission *tmp_submission, s[POLLFD_SET_SIZE]; 81 pthread_attr_t ptattr; 82 83 84 memset(pfdset, -1, sizeof(struct pollfd) * (POLLFD_SET_SIZE+1)); 85 memset(s, 0, sizeof(submission) * POLLFD_SET_SIZE); 87 86 88 87 global_sid = 2000000; … … 94 93 i = 0; 95 94 qsize = 0; 95 96 lock_mutex = 1; // if this is set, threads will lock mutexes 96 97 97 98 … … 107 108 secret = NULL; // s: NULL 108 109 verbose = 0; // v: don't be verbose 110 initial_threshold = 30; // initial cluster element threshold for signature generation 109 111 110 112 memset(&md5sum_trie, 0, sizeof(trie_node)); … … 112 114 memset(&sighash_trie, 0, sizeof(trie_node)); 113 115 116 // initialize thread locks 114 117 if (pthread_rwlock_init(&md5sum_trie_lock, NULL) || 115 118 pthread_rwlock_init(&spamsum_trie_lock, NULL) || 116 119 pthread_rwlock_init(&sighash_trie_lock, NULL) || 117 pthread_rwlock_init(&sidlock, NULL)) { 118 fprintf(stderr, "Error - Unable to initialize queue mutex: %m.\n"); 120 pthread_rwlock_init(&sidlock, NULL) || 121 pthread_mutex_init(&sessions_mutex, NULL) || 122 pthread_mutex_init(&siggen_mutex, NULL) || 123 pthread_mutex_init(&sigwrite_mutex, NULL)) { 124 fprintf(stderr, "Error - Unable to initialize thread lock: %m.\n"); 119 125 exit(EXIT_FAILURE); 120 126 } … … 123 129 124 130 // process args 125 while((option = getopt(argc, argv, "a:c:C:dE:hi:O:p:r:s: v?")) > 0) {131 while((option = getopt(argc, argv, "a:c:C:dE:hi:O:p:r:s:t:v?")) > 0) { 126 132 switch(option) { 127 133 case 'a': … … 183 189 secret = optarg; 184 190 break; 191 case 't': 192 initial_threshold = strtoul(optarg, NULL, 10); 193 if (initial_threshold < 2) { 194 fprintf(stderr, "Error - Invalid initial threshold.\n"); 195 exit(EXIT_FAILURE); 196 } 197 break; 185 198 case 'v': 186 199 verbose++; … … 194 207 } 195 208 209 // set up signal handling 196 210 set_signal_handlers(); 211 212 // initialize HMAC pads 213 memset(k_ipad, IPAD_VAL, HMAC_BLOCK_SIZE); 214 memset(k_opad, OPAD_VAL, HMAC_BLOCK_SIZE); 215 if (secret) for (i=0; i<strlen(secret); i++) { 216 k_ipad[i] ^= secret[i]; 217 k_opad[i] ^= secret[i]; 218 } 197 219 198 220 // initialize queues … … 208 230 } else if (verbose) printf(" Submission secret: %s\n", secret); 209 231 210 if ( snort_pid && !rules_file) {211 printf(" Warning - Snort will not be notified about updated rules: No rule filename given.\n");212 } else if (!snort_pid && rules_file) {213 printf(" Warning - Snort will not be notified about updated rules: No pid given.\n");214 } else if (verbose) { 215 printf(" Notifying snort about rule file updates in %s.\n", rules_file);216 }217 218 if (verbose) printf(" Initial snort signature ID: %u\n\n", global_sid);232 if (rules_file && verbose) 233 printf(" Appending new rules to %s.\n", rules_file); 234 if (snort_pid && verbose) 235 printf(" Forcing snort (process ID %u) reload on new rules.\n", snort_pid); 236 237 if (verbose) { 238 printf(" Initial snort signature ID: %u\n\n", global_sid); 239 printf(" Initial cluster size threshold: %lu\n\n", initial_threshold); 240 } 219 241 220 242 … … 222 244 printf("[*] Ready.\n"); 223 245 224 pfdset[0].fd = listen_fd;225 pfdset[0].events = POLLIN;246 LISTEN_SOCK.fd = listen_fd; 247 LISTEN_SOCK.events = POLLIN; 226 248 for(;;) { 227 switch (rv = poll(pfdset, POLLFD_SET_SIZE , -1)) {249 switch (rv = poll(pfdset, POLLFD_SET_SIZE+1, -1)) { 228 250 case -1: 229 fprintf(stderr, "Error with select(): %s.\n", strerror(errno)); 251 if (errno == EINTR) break; 252 fprintf(stderr, "Error - Unable to poll sockets: %s.\n", strerror(errno)); 230 253 exit(1); 231 254 case 0: … … 234 257 // check listen_fd 235 258 236 if ( pfdset[0].revents) {237 if ( pfdset[0].revents & POLLERR) {259 if (LISTEN_SOCK.revents) { 260 if (LISTEN_SOCK.revents & POLLERR) { 238 261 fprintf(stderr, "Error - Unable to poll listening socket: %s.\n", strerror(errno)); 239 262 exit(EXIT_FAILURE); 240 } else if ( pfdset[0].revents & POLLHUP) {263 } else if (LISTEN_SOCK.revents & POLLHUP) { 241 264 fprintf(stderr, "Error - Listening socket hangup.\n"); 242 265 exit(EXIT_FAILURE); 243 } else if ( pfdset[0].revents & POLLNVAL) {266 } else if (LISTEN_SOCK.revents & POLLNVAL) { 244 267 fprintf(stderr, "Error - Listening socket descriptor is invalid.\n"); 245 268 exit(EXIT_FAILURE); 246 269 } 247 270 248 if ( pfdset[0].revents & POLLIN) {271 if (LISTEN_SOCK.revents & POLLIN) { 249 272 // incoming connection, find next free place in poll fd set 250 273 251 for (i=1; i<POLLFD_SET_SIZE; i++) if (!pfdset[i].events) break; 252 pfdset[i].fd = net_accept(pfdset[0].fd); 253 pfdset[i].events = POLLIN; 254 255 if (verbose) printf("Connection accepted.\n"); 274 for (i=0; i<POLLFD_SET_SIZE; i++) { 275 if (pfdset[i].fd <= 0) { 276 pthread_mutex_lock(&sessions_mutex); 277 278 pfdset[i].fd = net_accept(LISTEN_SOCK.fd); 279 pfdset[i].events = POLLOUT; 280 281 memset(&s[i], 0, sizeof(submission)); 282 283 pthread_mutex_unlock(&sessions_mutex); 284 285 if (verbose) printf("[>] Connection accepted.\n"); 286 break; 287 } 288 } 256 289 } 257 290 } 258 for (i= 1; i<POLLFD_SET_SIZE; i++) {259 if (pfdset[i].revents & POLL IN) {291 for (i=0; i<POLLFD_SET_SIZE; i++) { 292 if (pfdset[i].revents & POLLOUT) { 260 293 switch (session_handle_data(&pfdset[i], &s[i])) { 261 case 1:262 // create submission copy so that we can reset the session263 memcpy(&tmp_submission, &s[i], sizeof(submission));264 s[i].attack = NULL;265 s[i].cattack = NULL;266 s[i].md5sum = NULL;267 268 // create clustering thread269 if (pthread_create(&ntid, NULL, pt_classify, (void *) &tmp_submission)) {270 fprintf(stderr, "Error - Cannot create clustering thread: %s.\n", strerror(errno));271 exit(EXIT_FAILURE);272 }273 274 // reset session275 session_reset(&s[i], &pfdset[i]);276 break;277 294 case -1: 278 295 fprintf(stderr, "Error - Invalid submission state. Terminating session.\n"); 296 session_reset(&s[i], &pfdset[i]); 297 break; 298 case 0: 299 session_reset(&s[i], &pfdset[i]); 279 300 break; 280 301 default: 302 pfdset[i].events = POLLIN; 281 303 break; 304 } 305 } 306 if (pfdset[i].revents) { 307 if (pfdset[i].revents & POLLIN) { 308 switch (session_handle_data(&pfdset[i], &s[i])) { 309 case 2: 310 // need more data to complete session 311 break; 312 case 1: 313 // create clustering thread 314 if ((tmp_submission = calloc(1, sizeof(submission))) == NULL) { 315 fprintf(stderr, "Error - Unable to allocate memory: %s.\n", strerror(errno)); 316 exit(EXIT_FAILURE); 317 } 318 memcpy(tmp_submission, &s[i], sizeof(submission)); 319 memset(&s[i], 0, sizeof(submission)); 320 321 if (pthread_attr_init(&ptattr) || 322 pthread_attr_setdetachstate(&ptattr, PTHREAD_CREATE_DETACHED)) { 323 fprintf(stderr, "Error - Unable to initialize thread attributes: %s.\n", strerror(errno)); 324 exit(EXIT_FAILURE); 325 } 326 pthread_mutex_lock(&sessions_mutex); 327 if (pthread_create(&ntid, &ptattr, pt_classify, (void *) tmp_submission)) { 328 fprintf(stderr, "Error - Cannot create clustering thread: %s.\n", strerror(errno)); 329 exit(EXIT_FAILURE); 330 } 331 pthread_attr_destroy(&ptattr); 332 333 session_reset(&s[i], &pfdset[i]); 334 break; 335 case 0: 336 // connection closed 337 session_reset(&s[i], &pfdset[i]); 338 break; 339 case -1: 340 // program error 341 fprintf(stderr, "Error - Terminating session.\n"); 342 session_reset(&s[i], &pfdset[i]); 343 break; 344 case -2: 345 // connection state error 346 fprintf(stderr, "Error - Invalid connection state.\n"); 347 session_reset(&s[i], &pfdset[i]); 348 break; 349 default: 350 break; 351 } 352 } else if (pfdset[i].revents & POLLERR && errno != EINTR) { 353 fprintf(stderr, "Error - Unable to poll socket: %s.\n", strerror(errno)); 354 session_reset(&s[i], &pfdset[i]); 355 } else if (pfdset[i].revents & POLLHUP) { 356 fprintf(stderr, "Error - Socket hangup.\n"); 357 session_reset(&s[i], &pfdset[i]); 358 } else if (pfdset[i].revents & POLLNVAL) { 359 fprintf(stderr, "Error - Socket descriptor is invalid.\n"); 360 session_reset(&s[i], &pfdset[i]); 282 361 } 283 362 } nebula/trunk/src/nebula.h
r1560 r1566 32 32 #include "cluster.h" 33 33 #include "hash.h" 34 #include "session.h" 34 35 #include "stree.h" 36 37 38 #define POLLFD_SET_SIZE 1023 39 #define LISTEN_SOCK pfdset[POLLFD_SET_SIZE] 40 41 struct pollfd pfdset[POLLFD_SET_SIZE+1]; 42 43 int lock_mutex; 35 44 36 45 u_char verbose; … … 41 50 double cluster_radius; 42 51 52 unsigned long int initial_threshold; 53 43 54 queue *clusterq; 44 55 queue *outlierq; 45 56 queue *aconnq; 46 57 47 pthread_rwlock_t md5sum_trie_lock; 48 pthread_rwlock_t spamsum_trie_lock; 49 pthread_rwlock_t sighash_trie_lock; 58 pthread_mutex_t sessions_mutex; 59 pthread_rwlock_t md5sum_trie_lock; 60 pthread_rwlock_t spamsum_trie_lock; 61 pthread_rwlock_t sighash_trie_lock; 50 62 51 63 #endif nebula/trunk/src/queue.c
r1558 r1566 32 32 if (!q || !data) return(NULL); 33 33 34 pthread_rwlock_wrlock(&q->lock);35 36 34 if ((new = calloc(1, sizeof(qelem))) == NULL) return(NULL); 37 35 new->data = data; … … 46 44 q->size++; 47 45 48 pthread_rwlock_unlock(&q->lock);49 46 return(new); 50 47 } … … 55 52 56 53 if (!q || !data) return(NULL); 57 58 pthread_rwlock_wrlock(&q->lock);59 54 60 55 if ((new = calloc(1, sizeof(qelem))) == NULL) return(NULL); … … 70 65 q->size++; 71 66 72 pthread_rwlock_unlock(&q->lock);73 67 return(new); 74 68 } … … 80 74 if (!q || q->head == NULL) return(NULL); 81 75 82 pthread_rwlock_wrlock(&q->lock);83 84 76 tmp = q->head; 85 77 q->head = q->head->next; … … 88 80 q->size--; 89 81 90 pthread_rwlock_unlock(&q->lock);91 82 return(tmp); 92 83 } … … 98 89 if (!q || q->tail == NULL) return(NULL); 99 90 100 pthread_rwlock_wrlock(&q->lock);101 102 91 tmp = q->tail; 103 92 q->tail = q->tail->prev; … … 106 95 q->size--; 107 96 108 pthread_rwlock_unlock(&q->lock);109 97 return(tmp); 110 98 } … … 136 124 e = queue_cuttail(q); 137 125 } else { 138 pthread_rwlock_wrlock(&q->lock);139 140 126 e->prev->next = e->next; 141 127 e->next->prev = e->prev; 142 128 if (!q->size--) q->head = q->tail = NULL; 143 144 pthread_rwlock_unlock(&q->lock);145 129 } 146 130 … … 159 143 } 160 144 if (pthread_rwlock_init(&q->lock, NULL) != 0) { 161 fprintf(stderr, "Error - Unable to initialize queue mutex: %m.\n");145 fprintf(stderr, "Error - Unable to initialize thread lock: %m.\n"); 162 146 exit(EXIT_FAILURE); 163 147 } … … 172 156 if (!q) return; 173 157 174 pthread_rwlock_wrlock(&q->lock);158 if (lock_mutex) pthread_rwlock_wrlock(&q->lock); 175 159 176 160 while (q->head) { … … 181 165 } 182 166 183 pthread_rwlock_unlock(&q->lock);167 if (lock_mutex) pthread_rwlock_unlock(&q->lock); 184 168 pthread_rwlock_destroy(&q->lock); 185 169 nebula/trunk/src/queue.h
r1558 r1566 28 28 #include <pthread.h> 29 29 30 #define Q_WLOCK(x) pthread_rwlock_wrlock(&((queue *)x)->lock); 31 #define Q_RLOCK(x) pthread_rwlock_rdlock(&((queue *)x)->lock); 32 #define Q_ULOCK(x) pthread_rwlock_unlock(&((queue *)x)->lock); 33 30 34 31 35 typedef struct qelem { nebula/trunk/src/session.c
r1563 r1566 34 34 35 35 36 36 37 void session_reset(submission *s, struct pollfd *pfd) { 37 38 if (!s) return; 39 40 pthread_mutex_lock(&sessions_mutex); 38 41 39 42 free(s->cattack); 40 43 free(s->attack); 41 44 free(s->md5sum); 45 free(s->hmac); 42 46 memset(s, 0, sizeof(submission)); 43 47 44 48 if (pfd) { 45 close(pfd->fd); 49 if (pfd->fd >= 0) close(pfd->fd); 50 if (verbose) printf("[<] Connection terminated.\n"); 51 46 52 memset(pfd, 0, sizeof(struct pollfd));
