Changeset 1618

Show
Ignore:
Timestamp:
04/16/08 10:33:50 (1 month ago)
Author:
till
Message:

nebula
- new threading concept: one clustering thread and one or more signature generation threads poll job queues

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • nebula/trunk/ChangeLog

    r1611 r1618  
     10.2.2 
     2- new threading concept: one clustering thread and one or more signature generation threads poll job queues 
    130.2.1 
    24- polling corrected 
  • nebula/trunk/configure.in

    r1581 r1618  
    11# $Id$  
    22AC_PREREQ(02.50) 
    3 AC_INIT([nebula], [0.2.1], [tillmann.werner@gmx.de]) 
     3AC_INIT([nebula], [0.2.2], [tillmann.werner@gmx.de]) 
    44AM_CONFIG_HEADER(config.h) 
    5 AM_INIT_AUTOMAKE(nebula,0.2.1
     5AM_INIT_AUTOMAKE(nebula,0.2.2
    66 
    77AC_PROG_CC 
     
    2929# Check for electric fence malloc debugger 
    3030AC_ARG_ENABLE(efence, 
    31 [  --enable-efence       link with electric fence], enable_efence="X", enable_efence=" ") 
     31[  --enable-efence         link with electric fence], enable_efence="X", enable_efence=" ") 
    3232        if test "$enable_efence" = "X"; then 
    3333                AC_CHECK_LIB(efence, EF_ALIGNMENT, LIBS="${LIBS} -lefence", AC_MSG_ERROR(libefence not found)) 
  • nebula/trunk/src/classify.c

    r1617 r1618  
    2323#include <stdlib.h> 
    2424#include <string.h> 
     25#include <sys/select.h> 
     26#include <unistd.h> 
    2527 
    2628#include "classify.h" 
    2729#include "cluster.h" 
    2830#include "nebula.h" 
     31#include "queue.h" 
    2932#include "spamsum.h" 
    3033#include "session.h" 
     
    3639 
    3740// pthread wrapper function 
    38 void *pt_classify(void *s) { 
    39         int     rv; 
    40  
    41         if (!s) return((void *) 0); 
    42  
    43         // this thread needs to unlock the sessions mutex 
    44         // so that the session ID can be reused in the main thread 
    45         pthread_mutex_unlock(&sessions_mutex); 
    46  
    47         // call classification function 
    48         if ((rv = classify(s)) == -1) { 
    49                 fprintf(stderr, "Error - Unable to classify submission.\n"); 
    50                 return((void *) -1); 
    51         } else if (rv == 0) { 
    52                 // known attack, do nothing 
    53                 return((void *) 0); 
    54         } else { 
    55                 // new attack 
    56                 free(s); 
    57         } 
     41void *pt_pollcq(void *param) { 
     42        int                     rv; 
     43        qelem                   *elem; 
     44        struct timeval          timeout; 
     45        fd_set                  rfds; 
     46        u_char                  buf; 
     47 
     48        for (;;) { 
     49                FD_ZERO(&rfds); 
     50                FD_SET(cpipe[0], &rfds); 
     51 
     52                timeout.tv_sec  = 10; 
     53                timeout.tv_usec = 0; 
     54 
     55                // this thread just processes a clustering job queue 
     56                // it reads wakeup calls from a pipe 
     57                switch (select(cpipe[0]+1, &rfds, NULL, NULL, &timeout)) { 
     58                case -1: 
     59                        fprintf(stderr, "Error - select() failed: %s.\n", strerror(errno)); 
     60                        exit(EXIT_FAILURE); 
     61                case 0: 
     62                        break; 
     63                default: 
     64                        if (FD_ISSET(cpipe[0], &rfds)) { 
     65                                if (read(cpipe[0], &buf, 1) != 1) { 
     66                                        fprintf(stderr, "Error - Unable to read from pipe: %s.\n", strerror(errno)); 
     67                                        exit(EXIT_FAILURE); 
     68                                } 
     69                        } 
     70                        pthread_mutex_lock(&classifyq_mutex); 
     71                        elem = queue_cuthead(classifyq); 
     72                        pthread_mutex_unlock(&classifyq_mutex); 
     73 
     74                        if (elem) { 
     75                                // call classification function 
     76                                if ((rv = classify((submission *) elem->data)) == -1) { 
     77                                        fprintf(stderr, "Error - Unable to classify submission.\n"); 
     78                                        free(elem); 
     79                                        return((void *) -1); 
     80                                } else if (rv == 0) { 
     81                                        // known attack, do nothing 
     82                                        free(elem); 
     83                                        return((void *) 0); 
     84                                } else { 
     85                                        // new attack 
     86                                        free(elem->data); 
     87                                        free(elem); 
     88                                } 
     89                        } 
     90                        break; 
     91                } 
     92        } 
     93         
    5894        return((void *) 1); 
    5995} 
     
    65101        hash            *tmp_hash; 
    66102        u_char          *tmpbuf; 
    67         qelem           *cur_cqelem, *tmp_cqelem, *cur_hqelem, *tmp_hqelem, *qtail
     103        qelem           *cur_cqelem, *tmp_cqelem, *cur_hqelem, *tmp_hqelem, *qtail, *jqelem
    68104        double          score, max_score; 
    69         pthread_t       ntid; 
    70         pthread_attr_t  ptattr; 
    71105 
    72106        qtail           = NULL; 
     
    111145        for (cur_cqelem = clusterq->head; cur_cqelem; cur_cqelem = cur_cqelem->next) { 
    112146                for (cur_hqelem = ((cluster *)cur_cqelem->data)->hq->head; cur_hqelem; cur_hqelem = cur_hqelem->next) { 
    113                         if ((score = spamsum_match(((hash*)t->data)->spamsum, ((hash*)cur_hqelem->data)->spamsum)) >= cluster_radius) { 
     147                        if ((score = spamsum_match(((hash*)t->data)->spamsum, ((hash*)cur_hqelem->data)->spamsum)) >= sim_threshold) { 
    114148                                if (!((hash*)t->data)->cl) { 
    115149                                        Q_ULOCK(&clusterq->lock); 
     
    149183        Q_RLOCK(&outlierq->lock); 
    150184        for (cur_hqelem = outlierq->head; cur_hqelem; cur_hqelem = cur_hqelem->next) { 
    151                 if ((score = spamsum_match(((hash*)t->data)->spamsum, ((hash*)cur_hqelem->data)->spamsum)) >= cluster_radius) { 
     185                if ((score = spamsum_match(((hash*)t->data)->spamsum, ((hash*)cur_hqelem->data)->spamsum)) >= sim_threshold) { 
    152186                // unlink match from outlier list 
    153187 
     
    240274        } 
    241275 
    242         // check for signature generation criterion here 
     276        pthread_mutex_lock(&siggenq_mutex); 
     277        // check for signature generation criterion 
    243278        if ((((hash*)t->data)->cl) && ((hash*)t->data)->cl->hq->size >= ((hash*)t->data)->cl->threshold) { 
    244279                printf("[=] Cluster size (%lu) hit threshold (%lu), generating signature.\n", 
     
    246281 
    247282                // increment size threshold 
     283                if  (((long unsigned) ((hash*)t->data)->cl->hq->size) > ((hash*)t->data)->cl->threshold) 
     284                        ((hash*)t->data)->cl->threshold = ((long unsigned) ((hash*)t->data)->cl->hq->size); 
    248285                ((hash*)t->data)->cl->threshold *= 1.2; 
    249286 
    250                 if (pthread_attr_init(&ptattr) || 
    251                     pthread_attr_setdetachstate(&ptattr, PTHREAD_CREATE_DETACHED)) { 
    252                         fprintf(stderr, "Error - Unable to initialize thread attributes: %s.\n", strerror(errno)); 
    253                         exit(EXIT_FAILURE); 
     287                // make sure every cluster gets queued only once 
     288                for (jqelem = siggenq->head; jqelem && jqelem->data != ((hash*)t->data)->cl; jqelem = jqelem->next); 
     289 
     290                // queue cluster for signature generation 
     291                if (!jqelem || jqelem->data != ((hash*)t->data)->cl) { 
     292                        // append cluster to signature generation job queue 
     293                        if (queue_append(siggenq, (void *) (void *) ((hash*)t->data)->cl) == NULL) { 
     294                                fprintf(stderr, "Error - Unable to queue cluster for signature generation.\n"); 
     295                                exit(EXIT_FAILURE); 
     296                        }  
     297                        if (write(gpipe[1], "x", sizeof(u_char)) == -1) { 
     298                                fprintf(stderr, "Error - Unable to write to pipe: %s.\n", strerror(errno)); 
     299                                exit(EXIT_FAILURE); 
     300                        } 
     301                } else { 
     302                        printf("[=] Cluster is already queued for signature generation.\n"); 
    254303                } 
    255                 if (pthread_create(&ntid, NULL, pt_siggen, (void *) ((hash*)t->data)->cl)) { 
    256                         fprintf(stderr, "Error - Cannot create signature generation thread: %s.\n", strerror(errno)); 
    257                         exit(EXIT_FAILURE); 
    258                 } 
    259                 pthread_attr_destroy(&ptattr); 
    260         } 
     304        } 
     305        pthread_mutex_unlock(&siggenq_mutex); 
    261306 
    262307        return(1); 
  • nebula/trunk/src/classify.h

    r1558 r1618  
    2828#include "session.h" 
    2929 
     30void *pt_pollcq(void *param); 
    3031void *pt_classify(void *s); 
    3132int classify(submission *s); 
  • nebula/trunk/src/nebula.c

    r1614 r1618  
    5959                "\t\t -d\t\t daemonize\n" 
    6060                "\t\t -e\t\t minimum substring entropy\n" 
     61                "\t\t -g\t\t number of signature generation threads\n" 
    6162                "\t\t -h\t\t this help\n" 
    6263                "\t\t -E <size>\t cluster element queue size\n" 
     
    7778 
    7879int main(int argc, char *argv[]) { 
    79         int             i, qsize, port, listen_fd, rv; 
     80        int             i, qsize, port, listen_fd, rv, gthread_no;  
    8081        u_char          daemonize; 
    8182        char            option; 
     
    9697        aconnq                  = NULL; 
    9798 
     99        classifyq               = NULL;         // classification job queue 
     100        siggenq                 = NULL;         // signature generation job queue 
     101 
    98102        i                       = 0; 
    99103        qsize                   = 0; 
     
    105109        rules_file              = NULL;         // a: NULL 
    106110        clusterq_max            = 5000;         // C 
    107         cluster_radius         = 95.0;         // c: 95% similarity as cluster criterion 
     111        sim_threshold          = 70.0;         // c: 70% similarity as cluster criterion 
    108112        daemonize               = 0;            // d: 0 
    109113        clusterhashq_max        = 500000;       // E 
     114        gthread_no              = 1;            // g 
    110115        snort_pid               = 0;            // h 
    111116        outlierq_max            = 500000;       // O 
     
    124129            pthread_rwlock_init(&sighash_trie_lock, NULL) || 
    125130            pthread_rwlock_init(&sidlock, NULL) || 
    126             pthread_mutex_init(&sessions_mutex, NULL) || 
     131            pthread_mutex_init(&classifyq_mutex, NULL) || 
     132            pthread_mutex_init(&siggenq_mutex, NULL) || 
    127133            pthread_mutex_init(&siggen_mutex, NULL) || 
    128134            pthread_mutex_init(&sigwrite_mutex, NULL)) { 
     
    134140 
    135141        // process args 
    136         while((option = getopt(argc, argv, "a:c:C:de:E:hi:l:O:p:r:s:t:v?")) > 0) { 
     142        while((option = getopt(argc, argv, "a:c:C:de:E:g:hi:l:O:p:r:s:t:v?")) > 0) { 
    137143                switch(option) { 
    138144                        case 'a': 
     
    140146                                break; 
    141147                        case 'c': 
    142                                 cluster_radius = atof(optarg); 
    143                                 if ((cluster_radius < 0) || (cluster_radius > 100)) { 
     148                                sim_threshold = atof(optarg); 
     149                                if ((sim_threshold < 0) || (sim_threshold > 100)) { 
    144150                                        fprintf(stderr, "Error - Cluster radius must be a value between 0 and 100 (in percent).\n"); 
    145151                                        exit(EXIT_FAILURE); 
     
    170176                                } 
    171177                                break; 
     178                        case 'g': 
     179                                gthread_no = atoi(optarg); 
     180                                if (gthread_no < 1) { 
     181                                        fprintf(stderr, "Error - Need at least one signature generation thread.\n"); 
     182                                        exit(EXIT_FAILURE); 
     183                                } 
     184                                break; 
    172185                        case 'i': 
    173186                                global_sid = strtoul(optarg, NULL, 10); 
     
    228241        // set up signal handling 
    229242        set_signal_handlers(); 
     243 
     244 
     245        // spawn classification thread 
     246        // the main thread writes to a pipe to inform the classification thread about pending jobs 
     247 
     248        if (pipe(cpipe) == -1) { 
     249                fprintf(stderr, "Error - Unable to create interthread communication pipe: %s.\n", strerror(errno)); 
     250                exit(EXIT_FAILURE); 
     251        } 
     252 
     253        if (pthread_attr_init(&ptattr) || pthread_attr_setdetachstate(&ptattr, PTHREAD_CREATE_DETACHED)) { 
     254                fprintf(stderr, "Error - Unable to initialize thread attributes: %s.\n", strerror(errno)); 
     255                exit(EXIT_FAILURE); 
     256        } 
     257        if (pthread_create(&ntid, &ptattr, pt_pollcq, NULL)) { 
     258                fprintf(stderr, "Error - Cannot create clustering thread: %s.\n", strerror(errno)); 
     259                exit(EXIT_FAILURE); 
     260        } 
     261        pthread_attr_destroy(&ptattr); 
     262 
     263 
     264 
     265        // spawn signature generation thread(s) 
     266        // the main thread writes to a pipe to inform the generation thread(s) about pending jobs 
     267 
     268        for (; gthread_no; gthread_no--) { 
     269                if (verbose > 1) printf("  Signature generation thread spawned.\n"); 
     270                if (pipe(gpipe) == -1) { 
     271                        fprintf(stderr, "Error - Unable to create interthread communication pipe: %s.\n", strerror(errno)); 
     272                        exit(EXIT_FAILURE); 
     273                } 
     274                if (pthread_attr_init(&ptattr) || pthread_attr_setdetachstate(&ptattr, PTHREAD_CREATE_DETACHED)) { 
     275                        fprintf(stderr, "Error - Unable to initialize thread attributes: %s.\n", strerror(errno)); 
     276                        exit(EXIT_FAILURE); 
     277                } 
     278                if (pthread_create(&ntid, &ptattr, pt_pollgq, (void *) gthread_no)) { 
     279                        fprintf(stderr, "Error - Cannot create signature generation thread: %s.\n", strerror(errno)); 
     280                        exit(EXIT_FAILURE); 
     281                } 
     282                pthread_attr_destroy(&ptattr); 
     283        } 
     284        if (verbose > 1) putchar('\n'); 
    230285 
    231286 
     
    255310 
    256311        // initialize queues 
    257         outlierq = queue_new(); 
    258         clusterq = queue_new(); 
     312        outlierq        = queue_new(); 
     313        clusterq        = queue_new(); 
     314        classifyq       = queue_new(); 
     315        siggenq         = queue_new(); 
    259316 
    260317 
     
    274331                printf("  Initial snort signature ID: %u\n", global_sid); 
    275332                printf("  Initial cluster size threshold: %lu\n", initial_threshold); 
    276                 printf("  Cluster criterion (minimal similarity): %.1f percent\n", cluster_radius); 
     333                printf("  Cluster criterion (minimal similarity): %.1f percent\n", sim_threshold); 
    277334                printf("  Accepting submissions on port %u/tcp.\n", port); 
    278335        } 
    279         printf("\n"); 
     336        putchar('\n'); 
    280337 
    281338 
     
    312369                                if ((LISTEN_SOCK.revents & POLLIN) && pollfd_set_size < POLLFD_MAX_SET_SIZE) { 
    313370                                        // incoming connection, accept it and place fd in pollfd set 
    314                                         pthread_mutex_lock(&sessions_mutex); 
    315  
    316371                                        pollfd_set_size++; 
    317372 
     
    320375 
    321376                                        memset(&s[pollfd_set_size], 0, sizeof(submission)); 
    322  
    323                                         pthread_mutex_unlock(&sessions_mutex); 
    324377 
    325378                                        if (verbose > 1) printf("[>] Connection accepted: %d.\n", pfdset[pollfd_set_size].fd); 
     
    356409                                                memset(&s[i], 0, sizeof(submission)); 
    357410                                                 
    358                                                 if (pthread_attr_init(&ptattr) || 
    359                                                     pthread_attr_setdetachstate(&ptattr, PTHREAD_CREATE_DETACHED)) { 
    360                                                         fprintf(stderr, "Error - Unable to initialize thread attributes: %s.\n", strerror(errno)); 
     411                                                // add session to classify queue 
     412                                                // and write a byte to the itc thread to wakeup the classification thread 
     413                                                pthread_mutex_lock(&classifyq_mutex); 
     414                                                if (queue_append(classifyq, (void *) tmp_submission) == NULL) { 
     415                                                        fprintf(stderr, "Error - Unable to queue session for classification.\n"); 
     416                                                        exit(EXIT_FAILURE); 
     417                                                }  
     418                                                if (write(cpipe[1], "x", sizeof(u_char)) == -1) { 
     419                                                        fprintf(stderr, "Error - Unable to write to pipe: %s.\n", strerror(errno)); 
    361420                                                        exit(EXIT_FAILURE); 
    362421                                                } 
    363                                                 pthread_mutex_lock(&sessions_mutex); 
    364                                                 if (pthread_create(&ntid, &ptattr, pt_classify, (void *) tmp_submission)) { 
    365                                                         fprintf(stderr, "Error - Cannot create clustering thread: %s.\n", strerror(errno)); 
    366                                                         exit(EXIT_FAILURE); 
    367                                                 } 
    368                                                 pthread_attr_destroy(&ptattr); 
     422                                                pthread_mutex_unlock(&classifyq_mutex); 
    369423 
    370424                                                session_reset(&s[i], i); 
  • nebula/trunk/src/nebula.h

    r1614 r1618  
    3939#define LISTEN_SOCK             pfdset[0] 
    4040 
    41 submission      s[POLLFD_MAX_SET_SIZE+1]; 
    42 struct pollfd   pfdset[POLLFD_MAX_SET_SIZE+1]; 
    43 nfds_t          pollfd_set_size;              // size of dynamically adjusted set 
     41submission             s[POLLFD_MAX_SET_SIZE+1]; 
     42struct pollfd          pfdset[POLLFD_MAX_SET_SIZE+1]; 
     43nfds_t                 pollfd_set_size;               // size of dynamically adjusted set 
    4444 
    45 int             lock_mutex
     45int                    lock_mutex, cpipe[2], gpipe[2]
    4646 
    47 u_char          verbose; 
    48 char            *secret; 
    49 trie_node       spamsum_trie, md5sum_trie, sighash_trie; 
     47u_char                 verbose; 
     48char                   *secret; 
     49trie_node              spamsum_trie, md5sum_trie, sighash_trie; 
    5050 
    51 ssize_t         clusterq_max, clusterhashq_max, outlierq_max;  
    52 double          cluster_radius
     51ssize_t                clusterq_max, clusterhashq_max, outlierq_max;  
     52double                 sim_threshold
    5353 
    54 unsigned long int     initial_threshold; 
     54unsigned long         initial_threshold; 
    5555 
    56 ssize_t         min_sstr_len; 
    57 double          min_sstr_ent; 
     56ssize_t                min_sstr_len; 
     57double                 min_sstr_ent; 
    5858 
    59 queue           *clusterq; 
    60 queue           *outlierq; 
    61 queue           *aconnq; 
     59queue                  *clusterq; 
     60queue                  *outlierq; 
     61queue                  *aconnq; 
    6262 
    63 pthread_mutex_t         sessions_mutex; 
     63queue                   *classifyq;     // clustering job queue 
     64queue                   *siggenq;       // signature generation job queue 
     65 
     66 
     67pthread_mutex_t         classifyq_mutex; 
     68pthread_mutex_t         siggenq_mutex; 
     69 
    6470pthread_rwlock_t        md5sum_trie_lock; 
    6571pthread_rwlock_t        spamsum_trie_lock; 
  • nebula/trunk/src/queue.h

    r1585 r1618  
    4949queue *queue_new(void); 
    5050void queue_free(queue *q, void(*cbfn)(void *data)); 
     51inline qelem *queue_append(queue *q, void *data); 
     52inline qelem *queue_cuthead(queue *q); 
    5153qelem *queue_ins(queue *q, void *data, ssize_t max_size); 
    5254inline qelem *queue_cuttail(queue *q); 
  • nebula/trunk/src/session.c

    r1612 r1618  
    3838        if (!subm) return; 
    3939 
    40         pthread_mutex_lock(&sessions_mutex); 
    41  
    4240        free(subm->cattack); 
    4341        free(subm->attack); 
     
    5957                pollfd_set_size--; 
    6058        } 
    61  
    62         pthread_mutex_unlock(&sessions_mutex); 
    6359 
    6460        fflush(stdout); 
  • nebula/trunk/src/sig.c

    r1614 r1618  
    2525#include <stdlib.h> 
    2626#include <string.h> 
     27#include <sys/select.h> 
    2728#include <sys/types.h> 
     29#include <unistd.h> 
    2830 
    2931#include "cluster.h" 
     
    354356 
    355357 
    356 void *pt_siggen(void *cl) { 
     358void *pt_pollgq(void *param) { 
     359        qelem                   *elem; 
     360        struct timeval          timeout; 
     361        fd_set                  rfds; 
     362        u_char                  buf; 
     363 
     364        for (;;) { 
     365                FD_ZERO(&rfds); 
     366                FD_SET(gpipe[0], &rfds); 
     367 
     368                timeout.tv_sec  = 10; 
     369                timeout.tv_usec = 0; 
     370 
     371                switch (select(gpipe[0]+1, &rfds, NULL, NULL, &timeout)) { 
     372                case -1: 
     373                        fprintf(stderr, "Error - select() failed: %s.\n", strerror(errno)); 
     374                        exit(EXIT_FAILURE); 
     375                case 0: 
     376                        break; 
     377                default: 
     378                        if (FD_ISSET(gpipe[0], &rfds)) { 
     379                                if (read(gpipe[0], &buf, 1) != 1) { 
     380                                        fprintf(stderr, "Error - Unable to read from pipe: %s.\n", strerror(errno)); 
     381                                        exit(EXIT_FAILURE); 
     382                                } 
     383                        } 
     384                        pthread_mutex_lock(&siggenq_mutex); 
     385                        elem = queue_cuthead(siggenq); 
     386                        pthread_mutex_unlock(&siggenq_mutex); 
     387 
     388                        if (elem != NULL) { 
     389                                gensig(elem->data); 
     390                                free(elem); 
     391                        } 
     392 
     393                        break; 
     394                } 
     395        } 
     396 
     397        return((void *) 1); 
     398
     399 
     400 
     401void *gensig(void *cl) { 
    357402        cluster         *attacks = cl; 
    358403        lchar           *content; 
  • nebula/trunk/src/sig.h

    r1611 r1618  
    9090} sseg; 
    9191 
    92  
    93 void *pt_siggen(void *cl); 
     92void *pt_pollgq(void *param); 
     93void *gensig(void *cl); 
    9494void build_sig(signature *sig, stree *t, lcatbl *lca_table, stnode **leaves, ssize_t num_leaves, ssize_t min_len, double min_ent); 
    9595int append_snortsig_to_rulefile(const char *filename, const stree *t, const signature *sig, const sseg *seglist, const ssize_t num_frags); 
  • nebula/trunk/src/signals.c

    r1613 r1618  
    5252        } 
    5353        if (sig == SIGINCC) { 
    54                 if (cluster_radius == 100.0) return; 
    55                 if (cluster_radius < 95.0) { 
    56                         cluster_radius += 5.0; 
     54                if (sim_threshold == 100.0) return; 
     55                if (sim_threshold < 95.0) { 
     56                        sim_threshold += 5.0; 
    5757                        write(STDOUT_FILENO, "[*] Cluster criterion increased by 5 percent\n", 45); 
    5858                } else { 
    59                         cluster_radius = 100.0; 
     59                        sim_threshold = 100.0; 
    6060                        write(STDOUT_FILENO, "[*] Cluster criterion increased to 100 percent\n", 46); 
    6161                } 
     
    6363        } 
    6464        if (sig == SIGDECC) { 
    65                 if (cluster_radius == 0.0) return; 
    66                 if (cluster_radius > 5.0) { 
    67                         cluster_radius -= 5.0; 
     65                if (sim_threshold == 0.0) return; 
     66                if (sim_threshold > 5.0) { 
     67                        sim_threshold -= 5.0; 
    6868                        write(STDOUT_FILENO, "[*] Cluster criterion decreased by 5 percent\n", 45); 
    6969                } else { 
    70                         cluster_radius = 0.0; 
     70                        sim_threshold = 0.0; 
    7171                        write(STDOUT_FILENO, "[*] Cluster criterion decreased to 0 percent\n", 45); 
    7272                } 
  • nebula/trunk/src/util.c

    r1612 r1618  
    114114        for (i = 0; i <= POLLFD_MAX_SET_SIZE; i++) shutdown(pfdset[i].fd, SHUT_RDWR); 
    115115 
    116         // free data structures 
     116        // free job queues 
     117        queue_free(siggenq, NULL); 
     118        queue_free(classifyq, NULL); 
     119         
     120        // free hash queues 
     121        queue_free(clusterq, cluster_free); 
    117122        queue_free(outlierq, hash_free); 
    118         queue_free(clusterq, cluster_free); 
    119123 
     124        // free tries 
    120125        trie_delete(md5sum_trie.childlist, md5sum_trie.childlist_len, NULL); 
    121  
    122126        trie_delete(spamsum_trie.childlist, spamsum_trie.childlist_len, NULL); 
    123          
    124127        trie_delete(sighash_trie.childlist, sighash_trie.childlist_len, NULL); 
    125128         
    126         pthread_mutex_destroy(&sessions_mutex); 
    127129        pthread_mutex_destroy(&siggen_mutex); 
    128130        pthread_mutex_destroy(&sigwrite_mutex);