~ubuntu-branches/ubuntu/utopic/suricata/utopic

« back to all changes in this revision

Viewing changes to src/counters.c

  • Committer: Package Import Robot
  • Author(s): Pierre Chifflier
  • Date: 2011-11-17 23:20:51 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20111117232051-wlo0g2fyinx0zi25
Tags: 1.1-1
* Imported Upstream version 1.1
* Add instructions on getting new rules using oinkmaster
* Add Recommends on oinkmaster
* Move snort-rules-default to Recommends

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#include "suricata.h"
28
28
#include "counters.h"
29
29
#include "threadvars.h"
30
 
#include "tm-modules.h"
31
30
#include "tm-threads.h"
32
31
#include "conf.h"
33
32
#include "util-time.h"
42
41
#define SC_PERF_PCRE_TIMEBASED_INTERVAL "^(?:(\\d+)([shm]))(?:(\\d+)([shm]))?(?:(\\d+)([shm]))?$"
43
42
 
44
43
static SCPerfOPIfaceContext *sc_perf_op_ctx = NULL;
 
44
static time_t sc_start_time;
 
45
/** refresh interval in seconds */
 
46
static uint32_t sc_counter_tts = SC_PERF_MGMTT_TTS;
 
47
/** is the stats counter enabled? */
 
48
static char sc_counter_enabled = TRUE;
 
49
/** append or overwrite? 1: append, 0: overwrite */
 
50
static char sc_counter_append = TRUE;
45
51
 
46
52
/**
47
53
 * \brief Adds a value of type uint64_t to the local counter.
263
269
 * \retval An allocated string containing the log filename on success or NULL on
264
270
 *         failure.
265
271
 */
266
 
static char *SCPerfGetLogFilename(void)
 
272
static char *SCPerfGetLogFilename(ConfNode *stats)
267
273
{
268
274
    char *log_dir = NULL;
269
275
    char *log_filename = NULL;
 
276
    const char* filename = NULL;
270
277
 
271
278
    if (ConfGet("default-log-dir", &log_dir) != 1)
272
279
        log_dir = DEFAULT_LOG_DIR;
275
282
        return NULL;
276
283
    }
277
284
 
 
285
    if (stats != NULL) {
 
286
        filename = ConfNodeLookupChildValue(stats, "filename");
 
287
        if (filename == NULL) {
 
288
            filename = SC_PERF_DEFAULT_LOG_FILENAME;
 
289
        }
 
290
    } else {
 
291
        filename = SC_PERF_DEFAULT_LOG_FILENAME;
 
292
    }
 
293
 
278
294
    if (snprintf(log_filename, PATH_MAX, "%s/%s", log_dir,
279
 
                 SC_PERF_DEFAULT_LOG_FILENAME) < 0) {
 
295
                 filename) < 0) {
280
296
        SCLogError(SC_ERR_SPRINTF, "Sprintf Error");
281
297
        SCFree(log_filename);
282
298
        return NULL;
294
310
{
295
311
    SCEnter();
296
312
 
 
313
    ConfNode *root = ConfGetNode("outputs");
 
314
    ConfNode *node = NULL;
 
315
    ConfNode *stats = NULL;
 
316
    if (root != NULL) {
 
317
        TAILQ_FOREACH(node, &root->head, next) {
 
318
            if (strncmp(node->val, "stats", 5) == 0) {
 
319
                stats = node->head.tqh_first;
 
320
            }
 
321
        }
 
322
    }
 
323
    /* Check if the stats module is enabled or not */
 
324
    if (stats != NULL) {
 
325
        const char *enabled = ConfNodeLookupChildValue(stats, "enabled");
 
326
        if (enabled != NULL && ConfValIsFalse(enabled)) {
 
327
            sc_counter_enabled = FALSE;
 
328
            SCLogDebug("Stats module has been disabled");
 
329
            SCReturn;
 
330
        }
 
331
        const char *interval = ConfNodeLookupChildValue(stats, "interval");
 
332
        if (interval != NULL)
 
333
            sc_counter_tts = (uint32_t) atoi(interval);
 
334
 
 
335
        const char *append = ConfNodeLookupChildValue(stats, "append");
 
336
        if (append != NULL)
 
337
            sc_counter_append = ConfValIsTrue(append);
 
338
    }
 
339
 
 
340
    /* Store the engine start time */
 
341
    time(&sc_start_time);
 
342
 
297
343
    if ( (sc_perf_op_ctx = SCMalloc(sizeof(SCPerfOPIfaceContext))) == NULL) {
298
344
        SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCPerfInitOPCtx. Exiting...");
299
345
        exit(EXIT_FAILURE);
302
348
 
303
349
    sc_perf_op_ctx->iface = SC_PERF_IFACE_FILE;
304
350
 
305
 
    if ( (sc_perf_op_ctx->file = SCPerfGetLogFilename()) == NULL) {
 
351
    if ( (sc_perf_op_ctx->file = SCPerfGetLogFilename(stats)) == NULL) {
306
352
        SCLogInfo("Error retrieving Perf Counter API output file path");
307
353
    }
308
354
 
309
 
    if ( (sc_perf_op_ctx->fp = fopen(sc_perf_op_ctx->file, "w+")) == NULL) {
 
355
    char *mode;
 
356
    if (sc_counter_append)
 
357
        mode = "a+";
 
358
    else
 
359
        mode = "w+";
 
360
 
 
361
    if ( (sc_perf_op_ctx->fp = fopen(sc_perf_op_ctx->file, mode)) == NULL) {
310
362
        SCLogError(SC_ERR_FOPEN, "fopen error opening file \"%s\".  Resorting "
311
363
                   "to using the standard output for output",
312
364
                   sc_perf_op_ctx->file);
339
391
 */
340
392
static void SCPerfReleaseOPCtx()
341
393
{
 
394
    if (sc_perf_op_ctx == NULL) {
 
395
        SCLogDebug("Counter module has been disabled");
 
396
        return;
 
397
    }
 
398
 
342
399
    SCPerfClubTMInst *pctmi = NULL;
343
400
    SCPerfClubTMInst *temp = NULL;
344
401
    pctmi = sc_perf_op_ctx->pctmi;
345
402
 
346
 
    if (sc_perf_op_ctx != NULL) {
347
 
        if (sc_perf_op_ctx->fp != NULL)
348
 
            fclose(sc_perf_op_ctx->fp);
349
 
 
350
 
        if (sc_perf_op_ctx->file != NULL)
351
 
            SCFree(sc_perf_op_ctx->file);
352
 
 
353
 
        while (pctmi != NULL) {
354
 
            if (pctmi->tm_name != NULL)
355
 
                SCFree(pctmi->tm_name);
356
 
 
357
 
            if (pctmi->head != NULL)
358
 
                SCFree(pctmi->head);
359
 
 
360
 
            temp = pctmi->next;
361
 
            SCFree(pctmi);
362
 
            pctmi = temp;
363
 
        }
364
 
 
365
 
        SCFree(sc_perf_op_ctx);
 
403
    if (sc_perf_op_ctx->fp != NULL)
 
404
        fclose(sc_perf_op_ctx->fp);
 
405
 
 
406
    if (sc_perf_op_ctx->file != NULL)
 
407
        SCFree(sc_perf_op_ctx->file);
 
408
 
 
409
    while (pctmi != NULL) {
 
410
        if (pctmi->tm_name != NULL)
 
411
            SCFree(pctmi->tm_name);
 
412
 
 
413
        if (pctmi->head != NULL)
 
414
            SCFree(pctmi->head);
 
415
 
 
416
        temp = pctmi->next;
 
417
        SCFree(pctmi);
 
418
        pctmi = temp;
366
419
    }
367
420
 
 
421
    SCFree(sc_perf_op_ctx);
 
422
 
368
423
    return;
369
424
}
370
425
 
400
455
    while (run) {
401
456
        TmThreadTestThreadUnPaused(tv_local);
402
457
 
403
 
        cond_time.tv_sec = time(NULL) + SC_PERF_MGMTT_TTS;
 
458
        cond_time.tv_sec = time(NULL) + sc_counter_tts;
404
459
        cond_time.tv_nsec = 0;
405
460
 
406
461
        SCMutexLock(tv_local->m);
410
465
        SCPerfOutputCounters();
411
466
 
412
467
        if (TmThreadsCheckFlag(tv_local, THV_KILL)) {
413
 
            TmThreadsSetFlag(tv_local, THV_CLOSED);
414
468
            run = 0;
415
469
        }
416
470
    }
417
471
 
 
472
    TmThreadWaitForFlag(tv_local, THV_DEINIT);
 
473
 
 
474
    TmThreadsSetFlag(tv_local, THV_CLOSED);
418
475
    return NULL;
419
476
}
420
477
 
461
518
 
462
519
        tv = tv_root[TVT_PPT];
463
520
        while (tv != NULL) {
464
 
            if (tv->inq == NULL || tv->sc_perf_pctx.head == NULL) {
465
 
                tv = tv->next;
466
 
                continue;
467
 
            }
468
 
 
469
 
            q = &trans_q[tv->inq->id];
470
 
 
471
 
            /* assuming the assignment of an int to be atomic, and even if it's
472
 
             * not, it should be okay */
473
 
            tv->sc_perf_pctx.perf_flag = 1;
474
 
 
475
 
            SCCondSignal(&q->cond_q);
 
521
            if (tv->sc_perf_pctx.head == NULL) {
 
522
                tv = tv->next;
 
523
                continue;
 
524
            }
 
525
 
 
526
            /* assuming the assignment of an int to be atomic, and even if it's
 
527
             * not, it should be okay */
 
528
            tv->sc_perf_pctx.perf_flag = 1;
 
529
 
 
530
            if (tv->inq != NULL) {
 
531
                q = &trans_q[tv->inq->id];
 
532
                SCCondSignal(&q->cond_q);
 
533
            }
 
534
 
 
535
            tv = tv->next;
 
536
        }
 
537
 
 
538
        /* mgt threads for flow manager */
 
539
        tv = tv_root[TVT_MGMT];
 
540
        while (tv != NULL) {
 
541
            if (tv->sc_perf_pctx.head == NULL) {
 
542
                tv = tv->next;
 
543
                continue;
 
544
            }
 
545
 
 
546
            /* assuming the assignment of an int to be atomic, and even if it's
 
547
             * not, it should be okay */
 
548
            tv->sc_perf_pctx.perf_flag = 1;
476
549
 
477
550
            tv = tv->next;
478
551
        }
479
552
 
480
553
        if (TmThreadsCheckFlag(tv_local, THV_KILL)) {
481
 
            TmThreadsSetFlag(tv_local, THV_CLOSED);
482
554
            run = 0;
483
555
        }
484
556
    }
485
557
 
 
558
    TmThreadWaitForFlag(tv_local, THV_DEINIT);
 
559
 
 
560
    TmThreadsSetFlag(tv_local, THV_CLOSED);
486
561
    return NULL;
487
562
}
488
563
 
719
794
        exit(EXIT_FAILURE);
720
795
    }
721
796
 
722
 
    if ( (pc->type_q = SCMalloc(sizeof(SCPerfCounterTypeQ))) == NULL) {
723
 
        SCPerfReleaseCounter(pc);
 
797
    if ( (pc->type_q = SCMalloc(sizeof(SCPerfCounterTypeQ))) == NULL)
724
798
        return 0;
725
 
    }
726
799
    memset(pc->type_q, 0, sizeof(SCPerfCounterTypeQ));
727
800
 
728
801
    pc->type_q->type = type_q;
750
823
            break;
751
824
    }
752
825
 
753
 
    if ( (pc->value->cvalue = SCMalloc(pc->value->size)) == NULL) {
754
 
        SCPerfReleaseCounter(pc);
 
826
    if ( (pc->value->cvalue = SCMalloc(pc->value->size)) == NULL)
755
827
        return 0;
756
 
    }
757
828
    memset(pc->value->cvalue, 0, pc->value->size);
758
829
 
759
830
    /* display flag which specifies if the counter should be displayed or not */
949
1020
    struct tm local_tm;
950
1021
    tms = (struct tm *)localtime_r(&tval.tv_sec, &local_tm);
951
1022
 
 
1023
    /* Calculate the Engine uptime */
 
1024
    int up_time = (int)difftime(tval.tv_sec, sc_start_time);
 
1025
    int sec = up_time % 60;     // Seconds in a minute
 
1026
    int in_min = up_time / 60;
 
1027
    int min = in_min % 60;      // Minutes in a hour
 
1028
    int in_hours = in_min / 60;
 
1029
    int hours = in_hours % 24;  // Hours in a day
 
1030
    int days = in_hours / 24;
 
1031
 
952
1032
    fprintf(sc_perf_op_ctx->fp, "----------------------------------------------"
953
1033
            "---------------------\n");
954
 
    fprintf(sc_perf_op_ctx->fp, "%" PRId32 "/%" PRId32 "/%04d -- %02d:%02d:%02d\n",
955
 
            tms->tm_mday, tms->tm_mon + 1, tms->tm_year + 1900, tms->tm_hour,
956
 
            tms->tm_min, tms->tm_sec);
 
1034
    fprintf(sc_perf_op_ctx->fp, "Date: %" PRId32 "/%" PRId32 "/%04d -- "
 
1035
            "%02d:%02d:%02d (uptime: %"PRId32"d, %02dh %02dm %02ds)\n",
 
1036
            tms->tm_mon + 1, tms->tm_mday, tms->tm_year + 1900, tms->tm_hour,
 
1037
            tms->tm_min, tms->tm_sec, days, hours, min, sec);
957
1038
    fprintf(sc_perf_op_ctx->fp, "----------------------------------------------"
958
1039
            "---------------------\n");
959
1040
    fprintf(sc_perf_op_ctx->fp, "%-25s | %-25s | %-s\n", "Counter", "TM Name",
965
1046
        for (u = 0; u < TVT_MAX; u++) {
966
1047
            tv = tv_root[u];
967
1048
            //if (pc_heads == NULL || pc_heads[u] == NULL)
968
 
            //continue;
 
1049
            //    continue;
969
1050
 
970
1051
            while (tv != NULL) {
971
1052
                SCMutexLock(&tv->sc_perf_pctx.m);
1049
1130
 
1050
1131
                if (pc_heads[u] == NULL ||
1051
1132
                    (pc_heads[0] != NULL &&
1052
 
                        strcmp(pctmi->tm_name, pc_heads[0]->name->tm_name)))
 
1133
                        strcmp(pctmi->tm_name, pc_heads[0]->name->tm_name))) {
1053
1134
                    flag = 0;
 
1135
                }
1054
1136
            }
1055
1137
 
1056
1138
            if (pc->disp == 0 || pc->value == NULL)
1100
1182
 */
1101
1183
void SCPerfSpawnThreads(void)
1102
1184
{
 
1185
    SCEnter();
 
1186
 
 
1187
    if (!sc_counter_enabled) {
 
1188
        SCReturn;
 
1189
    }
 
1190
 
1103
1191
    ThreadVars *tv_wakeup = NULL;
1104
1192
    ThreadVars *tv_mgmt = NULL;
1105
1193
 
1131
1219
        exit(EXIT_FAILURE);
1132
1220
    }
1133
1221
 
1134
 
    return;
 
1222
    SCReturn;
1135
1223
}
1136
1224
 
1137
1225
/**
1357
1445
 */
1358
1446
int SCPerfAddToClubbedTMTable(char *tm_name, SCPerfContext *pctx)
1359
1447
{
 
1448
    if (sc_perf_op_ctx == NULL) {
 
1449
        SCLogDebug("Counter module has been disabled");
 
1450
        return 0;
 
1451
    }
 
1452
 
1360
1453
    SCPerfClubTMInst *pctmi = NULL;
1361
1454
    SCPerfClubTMInst *prev = NULL;
1362
1455
    SCPerfClubTMInst *temp = NULL;
1385
1478
 
1386
1479
    /* get me the bugger who wrote this junk of a code :P */
1387
1480
    if (pctmi == NULL) {
1388
 
        if ( (temp = SCMalloc(sizeof(SCPerfClubTMInst))) == NULL) {
1389
 
            SCMutexUnlock(&sc_perf_op_ctx->pctmi_lock);
 
1481
        if ( (temp = SCMalloc(sizeof(SCPerfClubTMInst))) == NULL)
1390
1482
            return 0;
1391
 
        }
1392
1483
        memset(temp, 0, sizeof(SCPerfClubTMInst));
1393
1484
 
1394
1485
        temp->size = 1;
1395
1486
        temp->head = SCMalloc(sizeof(SCPerfContext **));
1396
 
        if (temp->head == NULL) {
1397
 
            SCFree(temp);
1398
 
            SCMutexUnlock(&sc_perf_op_ctx->pctmi_lock);
 
1487
        if (temp->head == NULL)
1399
1488
            return 0;
1400
 
        }
1401
1489
        temp->head[0] = pctx;
1402
1490
        temp->tm_name = SCStrdup(tm_name);
1403
1491
 
1421
1509
    }
1422
1510
 
1423
1511
    pctmi->head = SCRealloc(pctmi->head,
1424
 
                          (pctmi->size + 1) * sizeof(SCPerfContext *));
1425
 
    if (pctmi->head == NULL) {
1426
 
        SCMutexUnlock(&sc_perf_op_ctx->pctmi_lock);
 
1512
                          (pctmi->size + 1) * sizeof(SCPerfContext **));
 
1513
    if (pctmi->head == NULL)
1427
1514
        return 0;
1428
 
    }
1429
1515
    hpctx = pctmi->head;
1430
1516
 
1431
1517
    hpctx[pctmi->size] = pctx;
1479
1565
        return NULL;
1480
1566
    memset(pca, 0, sizeof(SCPerfCounterArray));
1481
1567
 
1482
 
    if ( (pca->head = SCMalloc(sizeof(SCPCAElem) * (e_id - s_id  + 2))) == NULL) {
1483
 
        SCFree(pca);
 
1568
    if ( (pca->head = SCMalloc(sizeof(SCPCAElem) * (e_id - s_id  + 2))) == NULL)
1484
1569
        return NULL;
1485
 
    }
1486
1570
    memset(pca->head, 0, sizeof(SCPCAElem) * (e_id - s_id  + 2));
1487
1571
 
1488
1572
    pc = pctx->head;
1715
1799
 
1716
1800
/*----------------------------------Unit_Tests--------------------------------*/
1717
1801
 
1718
 
#ifdef UNITTESTS
1719
 
 
1720
1802
static int SCPerfTestCounterReg01()
1721
1803
{
1722
1804
    SCPerfContext pctx;
1776
1858
 
1777
1859
    id = SCPerfRegisterCounter("t1", "c1", SC_PERF_TYPE_UINT64, NULL,
1778
1860
                               &tv.sc_perf_pctx);
 
1861
    if (id != 1) {
 
1862
        printf("id %d: ", id);
 
1863
        return 0;
 
1864
    }
1779
1865
 
1780
1866
    tv.sc_perf_pca = SCPerfGetAllCountersArray(NULL);
1781
1867
 
1792
1878
 
1793
1879
    id = SCPerfRegisterCounter("t1", "c1", SC_PERF_TYPE_UINT64, NULL,
1794
1880
                               &tv.sc_perf_pctx);
 
1881
    if (id != 1)
 
1882
        return 0;
1795
1883
 
1796
1884
    tv.sc_perf_pca = SCPerfGetAllCountersArray(&tv.sc_perf_pctx);
1797
1885
 
1811
1899
 
1812
1900
    memset(&tv, 0, sizeof(ThreadVars));
1813
1901
 
1814
 
    pca = (SCPerfCounterArray *)&tv.sc_perf_pca;
 
1902
    //pca = (SCPerfCounterArray *)&tv.sc_perf_pca;
1815
1903
 
1816
1904
    SCPerfRegisterCounter("t1", "c1", SC_PERF_TYPE_UINT64, NULL,
1817
1905
                          &tv.sc_perf_pctx);
1932
2020
 
1933
2021
    int result = 1;
1934
2022
    uint16_t id1, id2, id3, id4;
1935
 
    uint8_t *u8p;
1936
2023
 
1937
2024
    memset(&tv, 0, sizeof(ThreadVars));
1938
2025
 
1954
2041
 
1955
2042
    SCPerfUpdateCounterArray(pca, &tv.sc_perf_pctx, 0);
1956
2043
 
1957
 
    u8p = (uint8_t *)tv.sc_perf_pctx.head->value->cvalue;
1958
 
    result &= (1 == *u8p);
1959
 
    result &= (0 == *(u8p + 1));
1960
 
    result &= (0 == *(u8p + 2));
1961
 
    result &= (0 == *(u8p + 3));
1962
 
 
1963
 
    u8p = (uint8_t *)tv.sc_perf_pctx.head->next->value->cvalue;
1964
 
    result &= (0 == *u8p);
1965
 
    result &= (1 == *(u8p + 1));
1966
 
    result &= (0 == *(u8p + 2));
1967
 
    result &= (0 == *(u8p + 3));
1968
 
 
1969
 
    u8p = (uint8_t *)tv.sc_perf_pctx.head->next->next->value->cvalue;
1970
 
    result &= (1 == *u8p);
1971
 
    result &= (1 == *(u8p + 1));
1972
 
    result &= (0 == *(u8p + 2));
1973
 
    result &= (0 == *(u8p + 3));
1974
 
 
1975
 
    u8p = (uint8_t *)tv.sc_perf_pctx.head->next->next->next->value->cvalue;
1976
 
    result &= (16 == *u8p);
1977
 
    result &= (1 == *(u8p + 1));
1978
 
    result &= (1 == *(u8p + 2));
1979
 
    result &= (1 == *(u8p + 3));
 
2044
    uint64_t *u64p = (uint64_t *)tv.sc_perf_pctx.head->value->cvalue;
 
2045
    result &= (1 == *u64p);
 
2046
 
 
2047
    u64p = (uint64_t *)tv.sc_perf_pctx.head->next->value->cvalue;
 
2048
    result &= (256 == *u64p);
 
2049
 
 
2050
    u64p = (uint64_t *)tv.sc_perf_pctx.head->next->next->value->cvalue;
 
2051
    result &= (257 == *u64p);
 
2052
 
 
2053
    u64p = (uint64_t *)tv.sc_perf_pctx.head->next->next->next->value->cvalue;
 
2054
    result &= (16843024 == *u64p);
1980
2055
 
1981
2056
    SCPerfReleasePerfCounterS(tv.sc_perf_pctx.head);
1982
2057
    SCPerfReleasePCA(pca);
2328
2403
 
2329
2404
    return result;
2330
2405
}
2331
 
#endif /* UNITTESTS */
2332
2406
 
2333
2407
void SCPerfRegisterTests()
2334
2408
{
2335
 
#ifdef UNITTESTS
2336
2409
    UtRegisterTest("SCPerfTestCounterReg01", SCPerfTestCounterReg01, 0);
2337
2410
    UtRegisterTest("SCPerfTestCounterReg02", SCPerfTestCounterReg02, 0);
2338
2411
    UtRegisterTest("SCPerfTestCounterReg03", SCPerfTestCounterReg03, 1);
2352
2425
    UtRegisterTest("SCPerfTestIntervalQual16", SCPerfTestIntervalQual16, 1);
2353
2426
    UtRegisterTest("SCPerfTestIntervalQual17", SCPerfTestIntervalQual17, 1);
2354
2427
    UtRegisterTest("SCPerfTestIntervalQual18", SCPerfTestIntervalQual18, 1);
2355
 
#endif
 
2428
 
2356
2429
    return;
2357
2430
}