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

#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 -1

typedef struct reHttp_fragment_node
{
	unsigned int srcIp;
	unsigned int destIp;
	unsigned short sPort;
	unsigned short dPort;
	int fragment_num;		//ÊÕµ½Á½¸ö°üÒª»ØÒ»¸öack
	time_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_INITVAL		0xdeadbeef

static 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
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Brickie-liu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值