hash key list 哈希表测试(对tcp fragment报文建立会话信息生成哈希表,老化)

来源:互联网 发布:苹果网络电话软件排名 编辑:程序博客网 时间:2024/05/16 14:12
#include <stdio.h>#include <stdlib.h>#include <stdbool.h>#include <stdarg.h>#include <string.h>#include <unistd.h>#include <pthread.h>#include <getopt.h>       #include <pthread.h>       #include <string.h>       #include <stdio.h>       #include <stdlib.h>       #include <unistd.h>       #include <errno.h>       #include <ctype.h>#include <netinet/ip.h>#include <linux/tcp.h>#include <linux/udp.h>/*我们在使用signal和时钟相关的结构体之前,需要包含这两个头文件*/#include <signal.h>#include <sys/time.h>#define HTTP_FRAGMENT_HASH_LEN 1024#define ERROR_OK 0#define ERROR_FAIL -1typedef struct reHttp_fragment_node{unsigned int srcIp;unsigned int destIp;unsigned short sPort;unsigned short dPort;int fragment_num;//ÊÕµ½Á½¸ö°üÒª»ØÒ»¸öacktime_t sec;struct reHttp_fragment_node *next;}reHttp_fragment_node_t;typedef struct reHttp_fragment_hash{reHttp_fragment_node_t list;}reHttp_fragment_hash_t;reHttp_fragment_hash_t *g_reHttp_fragment_list;typedef struct netlib_pkt_desc{unsigned int saddr;unsigned int daddr;unsigned short source;unsigned short dest;}netlib_pkt_desc_s;static inline uint32_t rol32(uint32_t word, unsigned int shift){return (word << shift) | (word >> (32 - shift));}#define __jhash_final(a, b, c)\{\c ^= b; c -= rol32(b, 14);\a ^= c; a -= rol32(c, 11);\b ^= a; b -= rol32(a, 25);\c ^= b; c -= rol32(b, 16);\a ^= c; a -= rol32(c, 4);\b ^= a; b -= rol32(a, 14);\c ^= b; c -= rol32(b, 24);\}#define JHASH_INITVAL0xdeadbeefstatic inline uint32_t jhash_3words(uint32_t a, uint32_t b, uint32_t c,                                    uint32_t initval){  a += JHASH_INITVAL;  b += JHASH_INITVAL;  c += initval;  __jhash_final(a, b, c);  return c;}static unsigned int reHttp_get_hash(unsigned int a, unsigned int b, unsigned short c, unsigned short d, unsigned int mask){  a += c;  b += d;  c = 0;  a = a^b;  b = a;  return (jhash_3words(a,(a^c),(a|(b<<16)),0x5123598) & mask);}int reply_tcp_fragment_create(netlib_pkt_desc_s *pdesc){unsigned int hash_key;reHttp_fragment_hash_t *hash_head;reHttp_fragment_node_t *new_node;reHttp_fragment_node_t *node;reHttp_fragment_node_t *temp_node;hash_key = reHttp_get_hash(pdesc->saddr,pdesc->daddr,pdesc->source,pdesc->dest, HTTP_FRAGMENT_HASH_LEN-1);hash_head = g_reHttp_fragment_list + hash_key;temp_node = &hash_head->list;node = hash_head->list.next;while(node !=NULL){if(node->destIp != pdesc->daddr || node->srcIp != pdesc->saddr ||node->dPort != pdesc->dest || node->sPort != pdesc->source){temp_node = temp_node->next;node = node->next;continue;}return ERROR_OK;}new_node = malloc(sizeof(reHttp_fragment_node_t));if(new_node != NULL && node == NULL){new_node->destIp = pdesc->daddr;new_node->srcIp = pdesc->saddr;new_node->dPort = pdesc->dest;new_node->sPort = pdesc->source;new_node->fragment_num = 1;new_node->next = NULL;time(&new_node->sec);temp_node->next = new_node;printf(" hash_key:%d %x to %x; %x to %x\n",hash_key,new_node->srcIp,new_node->destIp,new_node->sPort,new_node->dPort);printf("%p %p %p\n",node,new_node,hash_head->list.next);}return ERROR_OK;}int reply_tcp_fragment_search_updata(netlib_pkt_desc_s *pdesc){unsigned int hash_key;unsigned int fragment_num;reHttp_fragment_hash_t *hash_head;reHttp_fragment_node_t *node;hash_key = reHttp_get_hash(pdesc->saddr,pdesc->daddr,pdesc->source,pdesc->dest, HTTP_FRAGMENT_HASH_LEN-1);hash_head = g_reHttp_fragment_list + hash_key;node = hash_head->list.next;while(node !=NULL){if(node->destIp != pdesc->daddr || node->srcIp != pdesc->saddr ||node->dPort != pdesc->dest || node->sPort != pdesc->source){printf(" [%x to %x; %x to %x]",node->srcIp,node->destIp,node->sPort,node->dPort);node = node->next;continue;}node->fragment_num++;time(&node->sec);fragment_num = node->fragment_num;printf(" hash_key:%d %x to %x; %x to %x fragment_num:%d\n",hash_key,node->srcIp,node->destIp,node->sPort,node->dPort,fragment_num);if(fragment_num % 2 == 0){return ERROR_OK;}}printf(" hash_key:%d %x to %x; %x to %x find fail\n",hash_key,pdesc->saddr,pdesc->daddr,pdesc->source,pdesc->dest);return ERROR_FAIL;}int reply_tcp_fragment_del(netlib_pkt_desc_s *pdesc){unsigned int hash_key;time_t tem_sec;reHttp_fragment_hash_t *hash_head;reHttp_fragment_node_t *node;reHttp_fragment_node_t *temp_node;hash_key = reHttp_get_hash(pdesc->saddr,pdesc->daddr,pdesc->source,pdesc->dest, HTTP_FRAGMENT_HASH_LEN-1);hash_head = g_reHttp_fragment_list + hash_key;temp_node = &hash_head->list;node = temp_node->next;time(&tem_sec);while(node !=NULL){if(node->destIp != pdesc->daddr || node->srcIp != pdesc->saddr ||node->dPort != pdesc->dest || node->sPort != pdesc->source){temp_node = temp_node->next;node = node->next;continue;}printf(" hash_key:%d %x to %x; %x to %x del\n",hash_key,node->srcIp,node->destIp,node->sPort,node->dPort);temp_node->next = node->next;free(node);break;}return ERROR_OK;}int reply_tcp_fragment_del_overtime(void){unsigned int hash_key;time_t tem_sec;reHttp_fragment_hash_t *hash_head;reHttp_fragment_node_t *node;reHttp_fragment_node_t *temp_node;for(hash_key= 0 ;hash_key <HTTP_FRAGMENT_HASH_LEN; hash_key++){hash_head = g_reHttp_fragment_list + hash_key;temp_node = &hash_head->list;node = temp_node->next;time(&tem_sec);while(node !=NULL){if(tem_sec - node->sec <= 10){temp_node = temp_node->next;node = node->next;continue;}printf(" hash_key:%d %x to %x; %x to %x del\n",hash_key,node->srcIp,node->destIp,node->sPort,node->dPort);temp_node = node->next;free(node);if(temp_node == NULL){node = NULL;}else{node = temp_node->next;}}}return ERROR_OK;}long lastsec,countsec;  /*这两个变量分别用来保存上一秒的时间和总共花去的时间*//*信号处理函数*/static void sig_handler(int signo){          switch(signo)          {                       /*接收到的信号是SIGUSR1,打印One second passed*/                      case SIGUSR1:                                 printf("One second passed %d\n",countsec);                                 break;                       /*定时器定时到达*/                      case SIGALRM:                      {                                  printf("Timer has been zero,elapsed %d seconds\n",countsec);  reply_tcp_fragment_del_overtime();                                  lastsec = countsec;                                  countsec = 0;                                  break;                      }          }}void*  pthread_overtime(void* param){         struct  itimerval v;        /*定时器结构体*/        long nowsec,nowusec;   /*当前时间的秒数和微秒数*/        /*注册SIGUSR1和SIGALARM信号的处理函数为sig_handler*/        if(signal(SIGUSR1,sig_handler)==SIG_ERR)       {                   printf("Unable to create handler for SIGUSR1\n");                   exit(0);       }        if(signal(SIGALRM,sig_handler)==SIG_ERR)       {                   printf("Unable to create handler for SIGALRM\n");                   exit(0);        }        /*初始化定时器初值和当前值*/       v.it_interval.tv_sec=20;       v.it_interval.tv_usec=999999;/* next value */       v.it_value.tv_sec=20;       v.it_value.tv_usec=999999;/* current value */         /*调用setitimer设置定时器,并将其挂到定时器链表上,这个函数的三个参数的含义分        别是设置ITIMER_REAL类型的定时器,要设置的值存放在变量v中,该定时器设置前        的值在设置后保存的地址,如果是这个参数为NULL,那么就放弃保存设置前的值*/        setitimer(ITIMER_REAL,&v,NULL);        lastsec = v.it_value.tv_sec;        countsec = 0;        /*该循环首先调用getitimer读取定时器当前值,再与原来的秒数比较,当发现已经过了        一秒后产生一个SIGUSR1信号,程序就会进入上面注册过的信号处理函数*/         while(1)         {                      getitimer(ITIMER_REAL,&v);                      nowsec = v.it_value.tv_sec;                      nowusec = v.it_value.tv_usec;                      if(nowsec == lastsec-1)                      {                                 /*每过一秒,产生一个SIGUSR1信号*/                                   raise(SIGUSR1);                                     lastsec=nowsec;                                  countsec++;      /*记录总的秒数*/                      }          }      return 0;}int main(){int size;    size = sizeof(reHttp_fragment_hash_t)*HTTP_FRAGMENT_HASH_LEN;    g_reHttp_fragment_list = (reHttp_fragment_hash_t*)malloc(size);    if( NULL == g_reHttp_fragment_list )    {        //return ERROR_FAIL;    }    memset(g_reHttp_fragment_list, 0, size);netlib_pkt_desc_s pdesc;pdesc.saddr = 0x01010101;pdesc.daddr = 0x02020202;pdesc.source = 1234;pdesc.dest = 80;reply_tcp_fragment_create(&pdesc);netlib_pkt_desc_s pdesc2;pdesc2.saddr = 0x03030303;pdesc2.daddr = 0x04040404;pdesc2.source = 1234;pdesc2.dest = 80;reply_tcp_fragment_create(&pdesc2);/*reply_tcp_fragment_search_updata(&pdesc);reply_tcp_fragment_search_updata(&pdesc2);reply_tcp_fragment_del(&pdesc2);reply_tcp_fragment_del(&pdesc);*/pthread_t tidTracer;pthread_create(&tidTracer,NULL,pthread_overtime,NULL);while (1)sched_yield();return 0;}

0 0
原创粉丝点击