Esempio n. 1
0
/**
 *  \brief Get a new host
 *
 *  Get a new host. We're checking memcap first and will try to make room
 *  if the memcap is reached.
 *
 *  \retval h *LOCKED* host on succes, NULL on error.
 */
static Host *HostGetNew(Address *a) {
    Host *h = NULL;

    /* get a host from the spare queue */
    h = HostDequeue(&host_spare_q);
    if (h == NULL) {
        /* If we reached the max memcap, we get a used host */
        if (!(HOST_CHECK_MEMCAP(sizeof(Host)))) {
            /* declare state of emergency */
            //if (!(SC_ATOMIC_GET(host_flags) & HOST_EMERGENCY)) {
            //    SC_ATOMIC_OR(host_flags, HOST_EMERGENCY);

                /* under high load, waking up the flow mgr each time leads
                 * to high cpu usage. Flows are not timed out much faster if
                 * we check a 1000 times a second. */
            //    FlowWakeupFlowManagerThread();
            //}

            h = HostGetUsedHost();
            if (h == NULL) {
                return NULL;
            }

            /* freed a host, but it's unlocked */
        } else {
            /* now see if we can alloc a new host */
            h = HostNew(a);
            if (h == NULL) {
                return NULL;
            }

            /* host is initialized but *unlocked* */
        }
    } else {
        /* host has been recycled before it went into the spare queue */

        /* host is initialized (recylced) but *unlocked* */
    }

    (void) SC_ATOMIC_ADD(host_counter, 1);
    SCMutexLock(&h->m);
    return h;
}
Esempio n. 2
0
Host *HostAlloc(void) {
    if (!(HOST_CHECK_MEMCAP(sizeof(Host)))) {
        return NULL;
    }

    (void) SC_ATOMIC_ADD(host_memuse, sizeof(Host));

    Host *h = SCMalloc(sizeof(Host));
    if (unlikely(h == NULL))
        goto error;

    memset(h, 0x00, sizeof(Host));

    SCMutexInit(&h->m, NULL);
    SC_ATOMIC_INIT(h->use_cnt);
    return h;

error:
    return NULL;
}
Esempio n. 3
0
/** \brief initialize the configuration
 *  \warning Not thread safe */
void HostInitConfig(char quiet)
{
    SCLogDebug("initializing host engine...");

    memset(&host_config,  0, sizeof(host_config));
    //SC_ATOMIC_INIT(flow_flags);
    SC_ATOMIC_INIT(host_counter);
    SC_ATOMIC_INIT(host_memuse);
    SC_ATOMIC_INIT(host_prune_idx);
    HostQueueInit(&host_spare_q);

    unsigned int seed = RandomTimePreseed();
    /* set defaults */
    host_config.hash_rand   = (int)( HOST_DEFAULT_HASHSIZE * (rand_r(&seed) / RAND_MAX + 1.0));

    host_config.hash_size   = HOST_DEFAULT_HASHSIZE;
    host_config.memcap      = HOST_DEFAULT_MEMCAP;
    host_config.prealloc    = HOST_DEFAULT_PREALLOC;

    /* Check if we have memcap and hash_size defined at config */
    char *conf_val;
    uint32_t configval = 0;

    /** set config values for memcap, prealloc and hash_size */
    if ((ConfGet("host.memcap", &conf_val)) == 1)
    {
        if (ParseSizeStringU64(conf_val, &host_config.memcap) < 0) {
            SCLogError(SC_ERR_SIZE_PARSE, "Error parsing host.memcap "
                       "from conf file - %s.  Killing engine",
                       conf_val);
            exit(EXIT_FAILURE);
        }
    }
    if ((ConfGet("host.hash-size", &conf_val)) == 1)
    {
        if (ByteExtractStringUint32(&configval, 10, strlen(conf_val),
                                    conf_val) > 0) {
            host_config.hash_size = configval;
        }
    }

    if ((ConfGet("host.prealloc", &conf_val)) == 1)
    {
        if (ByteExtractStringUint32(&configval, 10, strlen(conf_val),
                                    conf_val) > 0) {
            host_config.prealloc = configval;
        }
    }
    SCLogDebug("Host config from suricata.yaml: memcap: %"PRIu64", hash-size: "
               "%"PRIu32", prealloc: %"PRIu32, host_config.memcap,
               host_config.hash_size, host_config.prealloc);

    /* alloc hash memory */
    uint64_t hash_size = host_config.hash_size * sizeof(HostHashRow);
    if (!(HOST_CHECK_MEMCAP(hash_size))) {
        SCLogError(SC_ERR_HOST_INIT, "allocating host hash failed: "
                "max host memcap is smaller than projected hash size. "
                "Memcap: %"PRIu64", Hash table size %"PRIu64". Calculate "
                "total hash size by multiplying \"host.hash-size\" with %"PRIuMAX", "
                "which is the hash bucket size.", host_config.memcap, hash_size,
                (uintmax_t)sizeof(HostHashRow));
        exit(EXIT_FAILURE);
    }
    host_hash = SCCalloc(host_config.hash_size, sizeof(HostHashRow));
    if (unlikely(host_hash == NULL)) {
        SCLogError(SC_ERR_FATAL, "Fatal error encountered in HostInitConfig. Exiting...");
        exit(EXIT_FAILURE);
    }
    memset(host_hash, 0, host_config.hash_size * sizeof(HostHashRow));

    uint32_t i = 0;
    for (i = 0; i < host_config.hash_size; i++) {
        HRLOCK_INIT(&host_hash[i]);
    }
    (void) SC_ATOMIC_ADD(host_memuse, (host_config.hash_size * sizeof(HostHashRow)));

    if (quiet == FALSE) {
        SCLogInfo("allocated %llu bytes of memory for the host hash... "
                  "%" PRIu32 " buckets of size %" PRIuMAX "",
                  SC_ATOMIC_GET(host_memuse), host_config.hash_size,
                  (uintmax_t)sizeof(HostHashRow));
    }

    /* pre allocate hosts */
    for (i = 0; i < host_config.prealloc; i++) {
        if (!(HOST_CHECK_MEMCAP(sizeof(Host)))) {
            SCLogError(SC_ERR_HOST_INIT, "preallocating hosts failed: "
                    "max host memcap reached. Memcap %"PRIu64", "
                    "Memuse %"PRIu64".", host_config.memcap,
                    ((uint64_t)SC_ATOMIC_GET(host_memuse) + (uint64_t)sizeof(Host)));
            exit(EXIT_FAILURE);
        }

        Host *h = HostAlloc();
        if (h == NULL) {
            SCLogError(SC_ERR_HOST_INIT, "preallocating host failed: %s", strerror(errno));
            exit(EXIT_FAILURE);
        }
        HostEnqueue(&host_spare_q,h);
    }

    if (quiet == FALSE) {
        SCLogInfo("preallocated %" PRIu32 " hosts of size %" PRIuMAX "",
                host_spare_q.len, (uintmax_t)sizeof(Host));
        SCLogInfo("host memory usage: %llu bytes, maximum: %"PRIu64,
                SC_ATOMIC_GET(host_memuse), host_config.memcap);
    }

    return;
}