#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;
}
hash key list 哈希表测试(对tcp fragment报文建立会话信息生成哈希表,老化)
最新推荐文章于 2023-02-06 13:27:16 发布