HASH_INT hash_tands(HASH_INT triad, hash_table_t *theTable) { hash_cell_t *theElement= theTable->table+hash_hash(triad,theTable); int isScratch; if(theElement->triad == 0)/*No such a triad -- install it and return:*/ return theElement->triad=triad; if(theElement->next == 0){ if( hash_cmp(triad, theElement->triad, theTable) ) return theElement->triad; isScratch=0;/*theElement points somewhere into the table*/ }else{ #ifdef DEBUG HASH_INT maxCNew=0; #endif isScratch=1;/*theElement points somewhere into the scratch*/ for(;;){ if( hash_cmp(triad, theElement->triad, theTable) ) return theElement->triad; if(theElement->next == 0) break; theElement= theTable->scratch+theElement->next; #ifdef DEBUG maxCNew++; #endif }/*for(;;)*/ #ifdef DEBUG nC++; avC+=maxCNew; if(maxCNew>maxC) maxC=maxCNew; #endif }/*else*/ /*Install a new element in scratch:*/ if(theTable->free == theTable->max){/*(re)allocate the scratch array:*/ if(theTable->max == 0) hash_alloc(theTable); else{ if(isScratch){/*theElement points somewhere into the scratch*/ /*Store the position:*/ HASH_INT n=theElement-theTable->scratch; hash_realloc(theTable); /*The scratch was changed, restore the position:*/ theElement=theTable->scratch+n; }else/*theElement has no relation to the scratch, just realloc the scratch:*/ hash_realloc(theTable); }/*else*/ }/*if(theTable->free == theTable->max)*/ /*Install the triad and return:*/ theTable->scratch[theTable->free].triad=triad; theElement->next=theTable->free; theTable->scratch[theTable->free].next=0; theTable->free++; return triad; }/*hash_tands*/
int add_hash_entry(struct class_info *truth) { unsigned long n; int i; struct hash_table *ptr, *table; /* calculate the key */ n = truth->addr.a_port + truth->addr.b_port; if (truth->addr.a_addr.version == 4) { n += truth->addr.a_addr.un.ipv4.s_addr + truth->addr.b_addr.un.ipv4.s_addr; } else if (truth->addr.a_addr.version == 6) { for (i = 0; i< 16; i++) { n += truth->addr.a_addr.un.ipv6.s6_addr[i]; n += truth->addr.b_addr.un.ipv6.s6_addr[i]; } } n = n % PRE_SIZE; if (tct_ground[n] == NULL) { /* first item */ table=(struct hash_table *)malloc(sizeof(struct hash_table)); if(table == NULL) { err_sys("malloc for hash_table error"); } table->next = NULL; table->entry = truth; tct_ground[n] = table; } else { ptr = tct_ground[n]; while(ptr != NULL) { if (hash_cmp(&(ptr->entry->addr), &(truth->addr)) == 1) { //if (memcmp(&(ptr->entry->addr), &(truth->addr), sizeof(struct five_tuple)) == 0) { truth->next = ptr->entry; ptr->entry = truth; break; } ptr = ptr->next; } if (ptr == NULL) { /* there is no duplicated */ table=(struct hash_table *)malloc(sizeof(struct hash_table)); if(table == NULL) err_sys("malloc for hash_table error"); table->entry = truth; /* insert to the head */ table->next = tct_ground[n]; tct_ground[n] = table; return 0; } } return 0; }
/*Returns address of a triad, or 0*/ HASH_INT hash_check(HASH_INT triad, hash_table_t *theTable) { HASH_INT theIndex=hash_hash(triad,theTable); hash_cell_t *theElement= theTable->table+theIndex; if(theElement->triad != 0)for(;;){ if( hash_cmp(triad, theElement->triad, theTable) ) return theElement->triad; if(theElement->next == 0) break; theElement= theTable->scratch+theElement->next; }/*if(theElement->triad != 0)for(;;)*/ return 0; }/*hash_check*/
/* * find the class type of the traffic (identified by a 5 tuple) */ struct class_info *find_ground_truth(struct five_tuple key, struct timeval start_time) { unsigned long n; int i; struct hash_table *prev, *table; struct class_info *pclass; /* calculate the key */ n = key.a_port + key.b_port; if (key.a_addr.version == 4) { n += key.a_addr.un.ipv4.s_addr + key.b_addr.un.ipv4.s_addr; } else if (key.a_addr.version == 6) { for (i = 0; i< 16; i++) { n += key.a_addr.un.ipv6.s6_addr[i]; n += key.b_addr.un.ipv6.s6_addr[i]; } } n = n % PRE_SIZE; table = tct_ground[n]; if (table == NULL) { return NULL; } else { while (table != NULL) { prev = table; if (hash_cmp(&(table->entry->addr), &key) == 1) { pclass = table->entry; i = 0; while (pclass != NULL) { if (pclass->time.tv_sec == start_time.tv_sec) { break; } pclass = pclass->next; i++; } if (pclass == NULL) { return table->entry; #if 0 printf("sport:%d, dport:%d, time:%lu.%06lu\n", ntohs(key.a_port), ntohs(key.b_port), start_time.tv_sec, start_time.tv_usec); err_msg("panic, ground truth time stamp wrong"); if (i <= 20) //if (i == 1) return table->entry; else { err_msg("return NULL\n"); return NULL; } #endif } #if 0 // to do some kind of optimization else { /* move entry to header */ if (prev != table) { prev->next = table->next; table->next = tct_ground[n]; tct_ground[n] = table; } } #endif return pclass; } table = table->next; } } return NULL; }