📄 snort_stream4_session.c
字号:
/* $Id$ *//*** Copyright (C) 2005 Sourcefire, Inc.** AUTHOR: Steven Sturges <ssturges@sourcefire.com>**** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*//* snort_stream4_session.c * * Purpose: Hash Table implementation of session management functions for * TCP stream preprocessor. * * Arguments: * * Effect: * * Comments: * * Any comments? * */#include "sfxhash.h"#include "ubi_SplayTree.h"#include "decode.h"#include "debug.h"#include "stream.h"#include "log.h"/* splay tree root data */static ubi_trRoot s_cache;static ubi_trRootPtr RootPtr = &s_cache;/* Stuff defined in stream4.c that we use */extern void DeleteSession(Session *, u_int32_t);extern Stream4Data s4data;extern u_int32_t stream4_memory_usage;static SFXHASH *sessionHashTable = NULL;#ifndef WIN32#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#endif#ifdef USE_HASH_TABLEint GetSessionCount(){ if (sessionHashTable) return sessionHashTable->count; else return 0;}int GetSessionKey(Packet *p, SessionHashKey *key){ if (!key) return 0; if (p->iph->ip_src.s_addr < p->iph->ip_dst.s_addr) { key->lowIP = p->iph->ip_src.s_addr; key->port = p->tcph->th_sport; key->highIP = p->iph->ip_dst.s_addr; key->port2 = p->tcph->th_dport; } else if (p->iph->ip_src.s_addr == p->iph->ip_dst.s_addr) { key->lowIP = p->iph->ip_src.s_addr; key->highIP = p->iph->ip_dst.s_addr; if (p->tcph->th_sport < p->tcph->th_dport) { key->port = p->tcph->th_sport; key->port2 = p->tcph->th_dport; } else { key->port = p->tcph->th_sport; key->port2 = p->tcph->th_dport; } } else { key->lowIP = p->iph->ip_dst.s_addr; key->port = p->tcph->th_dport; key->highIP = p->iph->ip_src.s_addr; key->port2 = p->tcph->th_sport; } return 1;}Session *GetSessionFromHashTable(Packet *p){ Session *returned = NULL; SFXHASH_NODE *hnode; SessionHashKey sessionKey; if (!GetSessionKey(p, &sessionKey)) return NULL; hnode = sfxhash_find_node(sessionHashTable, &sessionKey); if (hnode && hnode->data) { /* This is a unique hnode, since the sfxhash finds the * same key before returning this node. */ returned = (Session *)hnode->data; } return returned;}int RemoveSessionFromHashTable(Session *ssn){ return sfxhash_remove(sessionHashTable, &(ssn->hashKey));}int CleanHashTable(u_int32_t thetime, Session *save_me, int memCheck){ Session *idx; u_int32_t pruned = 0; if (thetime != 0) { char got_one; idx = (Session *) sfxhash_lru(sessionHashTable); if(idx == NULL) { return 0; } do { got_one = 0; if(idx == save_me) { SFXHASH_NODE *lastNode = sfxhash_lru_node(sessionHashTable); sfxhash_gmovetofront(sessionHashTable, lastNode); lastNode = sfxhash_lru_node(sessionHashTable); if ((lastNode) && (lastNode->data != idx)) { idx = (Session *)lastNode->data; continue; } else { return pruned; } } if((idx->last_session_time+s4data.timeout) < thetime) { Session *savidx = idx; if(sfxhash_count(sessionHashTable) > 1) { DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "pruning stale session\n");); DeleteSession(savidx, thetime); idx = (Session *) sfxhash_lru(sessionHashTable); pruned++; got_one = 1; } else { DeleteSession(savidx, thetime); pruned++; return pruned; } } else { return pruned; } } while ((idx != NULL) && (got_one == 1)); return pruned; } else if (s4data.cache_clean_percent == 0) { /* Free up xxx sessions at a time until we get under the * memcap or free enough sessions to be able to create * new ones. */ while ( ((memCheck && (stream4_memory_usage > s4data.memcap)) || (sessionHashTable->count > (s4data.max_sessions - s4data.cache_clean_sessions))) && (sfxhash_count(sessionHashTable) > 1)) { int i; idx = (Session *) sfxhash_lru(sessionHashTable); for (i=0;i<s4data.cache_clean_sessions && (sfxhash_count(sessionHashTable) > 1); i++) { if(idx != save_me) { DeleteSession(idx, thetime); pruned++; idx = (Session *) sfxhash_lru(sessionHashTable); } else { SFXHASH_NODE *lastNode = sfxhash_lru_node(sessionHashTable); sfxhash_gmovetofront(sessionHashTable, lastNode); lastNode = sfxhash_lru_node(sessionHashTable); if ((lastNode) && (lastNode->data == idx)) { /* Okay, this session is the only one left */ break; } idx = (Session *) sfxhash_lru(sessionHashTable); i--; /* Didn't clean this one */ } } } } else { /* Free up a percentage of the cache */ u_int32_t smallPercent = (u_int32_t)(s4data.max_sessions * s4data.cache_clean_percent); idx = (Session *) sfxhash_lru(sessionHashTable); while ((stream4_memory_usage > (s4data.memcap - smallPercent)) && (sfxhash_count(sessionHashTable) > 1)) { idx = (Session *) sfxhash_lru(sessionHashTable); if(idx != save_me) { DeleteSession(idx, thetime); pruned++; idx = (Session *) sfxhash_lru(sessionHashTable); } else { SFXHASH_NODE *lastNode = sfxhash_lru_node(sessionHashTable); sfxhash_gmovetofront(sessionHashTable, lastNode); lastNode = sfxhash_lru_node(sessionHashTable); if ((lastNode) && (lastNode->data == idx)) { /* Okay, this session is the only one left */ break; } idx = (Session *) sfxhash_lru(sessionHashTable); } } } return pruned;}Session *GetNewSession(Packet *p){ Session *retSsn = NULL; SessionHashKey sessionKey; SFXHASH_NODE *hnode; if (!GetSessionKey(p, &sessionKey)) return retSsn; hnode = sfxhash_get_node(sessionHashTable, &sessionKey); if (!hnode) { DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "HashTable full, clean it\n");); if (!CleanHashTable(p->pkth->ts.tv_sec, NULL, 0)) { DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "HashTable full, no timeouts, clean it\n");); CleanHashTable(0, NULL, 0); } /* Should have some freed nodes now */ hnode = sfxhash_get_node(sessionHashTable, &sessionKey);#ifdef DEBUG if (!hnode) { DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "Problem, no freed nodes\n");); }#endif } if (hnode && hnode->data) { retSsn = hnode->data; memset(retSsn, 0, sizeof(Session)); /* Save the session key for future use */ memcpy(&(retSsn->hashKey), &sessionKey, sizeof(SessionHashKey));#if 0 retSsn->ttl = 0; retSsn->alert_count = 0; retSsn->http_alert_flags = 0; retSsn->preproc_data = NULL; retSsn->preproc_free = NULL; retSsn->preproc_proto = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -