static void ndpi_http_subprotocol_conf(struct ndpi_detection_module_struct *ndpi_struct, char *attr, char *value, int protocol_id) { #ifdef AHOCORASICK AC_PATTERN_t ac_pattern; #else ndpi_protocol_match *tmp_host_match; #endif /* e.g attr = "host" value = ".facebook.com" protocol_id = NDPI_PROTOCOL_FACEBOOK */ #ifdef AHOCORASICK if (strcmp(attr, "finalize") == 0) { /* trick to finalize automa */ if (ac_automa != NULL) ac_automata_finalize(ac_automa); return; } #endif if (strcmp(attr, "host") != 0) { #ifdef DEBUG printf("[NTOP] attribute %s not supported\n", attr); #endif return; } #ifdef AHOCORASICK if (ac_automa == NULL) ac_automa = ac_automata_init(ac_match_handler); /* call ac_automata_release(ac_automa); to free ac_automa */ ac_pattern.astring = value; ac_pattern.rep.number = protocol_id; ac_pattern.length = strlen(tmp_patt.astring); ac_automata_add(ac_automa, &ac_pattern); #else /* realloc */ tmp_host_match = ndpi_malloc(sizeof(ndpi_protocol_match) * (host_match_num_items + 1)); if (tmp_host_match == NULL) { return; } if (host_match != NULL) { memcpy(tmp_host_match, host_match, sizeof(ndpi_protocol_match) * host_match_num_items); ndpi_free(host_match); } host_match = tmp_host_match; host_match[host_match_num_items].string_to_match = ndpi_strdup(value); if (host_match[host_match_num_items].string_to_match == NULL) { return; } host_match[host_match_num_items].protocol_id = protocol_id; host_match_num_items++; #endif #ifdef DEBUG printf("[NTOP] new http subprotocol: %s = %s -> %d\n", attr, value, protocol_id); #endif }
struct ndpi_LruCacheEntry* lru_allocCacheStringNode(struct ndpi_LruCache *cache, char *key, char *value, u_int32_t timeout) { struct ndpi_LruCacheEntry *node = (struct ndpi_LruCacheEntry*)ndpi_calloc(1, sizeof(struct ndpi_LruCacheEntry)); if(unlikely(traceLRU)) printf("%s(key=%s, value=%s)", __FUNCTION__, key, value); if(node == NULL) printf("ERROR: Not enough memory?"); else { node->numeric_node = 0; node->u.str.key = ndpi_strdup(key), node->u.str.value = ndpi_strdup(value); node->u.str.expire_time = (timeout == 0) ? 0 : (compute_timeout(timeout) + get_now()); #ifdef FULL_STATS cache->mem_size += sizeof(struct ndpi_LruCacheEntry) + strlen(key) + strlen(value); //printf("%s(key=%s, value=%s) [memory: %u]", __FUNCTION__, key, value, cache->mem_size); #endif } return(node); }
int ndpi_add_to_lru_cache_str_timeout(struct ndpi_LruCache *cache, char *key, char *value, u_int32_t timeout) { if(cache->hash_size == 0) return(0); else { u_int32_t hash_val = lru_hash_string(key); u_int32_t hash_id = hash_val % cache->hash_size; struct ndpi_LruCacheEntry *node; u_int8_t node_already_existing = 0; int rc = 0; if(unlikely(traceLRU)) printf("%s(key=%s, value=%s)", __FUNCTION__, key, value); // validate_unit_len(cache, hash_id); cache->num_cache_add++; /* [1] Add to hash */ if(cache->hash[hash_id] == NULL) { if((node = lru_allocCacheStringNode(cache, key, value, timeout)) == NULL) { rc = -1; goto ret_add_to_lru_cache; } cache->hash[hash_id] = node; cache->current_hash_size[hash_id]++; } else { /* Check if the element exists */ struct ndpi_LruCacheEntry *head = cache->hash[hash_id]; while(head != NULL) { if(strcmp(head->u.str.key, key) == 0) { /* Duplicated key found */ node = head; if(node->u.str.value) { #ifdef FULL_STATS cache->mem_size -= strlen(node->u.str.value); #endif ndpi_free(node->u.str.value); } node->u.str.value = ndpi_strdup(value); /* Overwrite old value */ #ifdef FULL_STATS cache->mem_size += strlen(value); #endif node->u.str.expire_time = (timeout == 0) ? 0 : (compute_timeout(timeout) + get_now()); node_already_existing = 1; break; } else head = head->next; } if(!node_already_existing) { if((node = lru_allocCacheStringNode(cache, key, value, timeout)) == NULL) { rc = -2; goto ret_add_to_lru_cache; } node->next = cache->hash[hash_id]; cache->hash[hash_id] = node; cache->current_hash_size[hash_id]++; } } trim_subhash(cache, hash_id); // validate_unit_len(cache, hash_id); ret_add_to_lru_cache: return(rc); } }