Merge pull request #2 from wllm-rbnt/master

Fixes for 2 memory leaks and in flight structure cleaning
This commit is contained in:
Alexandre Dulaunoy 2015-04-22 13:42:03 +02:00
commit f195ab149a
6 changed files with 73 additions and 8 deletions

View file

@ -87,6 +87,13 @@ RETSIGTYPE sig_handler PROTO_LIST((void));
void pcap_cb PROTO_LIST((u_char *ptr,struct pcap_pkthdr *hdr,u_char *data)); void pcap_cb PROTO_LIST((u_char *ptr,struct pcap_pkthdr *hdr,u_char *data));
int main PROTO_LIST((int argc,char **argv)); int main PROTO_LIST((int argc,char **argv));
int packet_cnt = 0; // Packet counter used for connection pool cleaning
int conn_freq = 100; // Number of packets after which a connection pool
// cleaning is performed
int conn_ttl = 100; // TTL of inactive connections in connection pool
struct timeval last_packet_seen_time; // Timestamp of the last packet of the
// last block of conn_freq packets seen
int err_exit(str,num) int err_exit(str,num)
char *str; char *str;
int num; int num;
@ -128,7 +135,7 @@ void pcap_cb(ptr,hdr,data)
n_handler *n; n_handler *n;
int len; int len;
struct ether_header *e_hdr=(struct ether_header *)data; struct ether_header *e_hdr=(struct ether_header *)data;
int type; int type, cleaned_conn;
n=(n_handler *)ptr; n=(n_handler *)ptr;
if(hdr->caplen!=hdr->len) err_exit("Length mismatch",-1); if(hdr->caplen!=hdr->len) err_exit("Length mismatch",-1);
@ -231,6 +238,15 @@ void pcap_cb(ptr,hdr,data)
#endif #endif
} }
network_process_packet(n,&hdr->ts,data,len); network_process_packet(n,&hdr->ts,data,len);
if(packet_cnt == conn_freq) {
packet_cnt = 0;
memcpy(&last_packet_seen_time,&hdr->ts,sizeof(struct timeval));
if(cleaned_conn = clean_old_conn())
printf("%d inactive connection(s) cleaned from connection pool\n", cleaned_conn);
} else {
packet_cnt++;
}
} }
typedef struct module_def_ { typedef struct module_def_ {
@ -277,7 +293,7 @@ int main(argc,argv)
signal(SIGINT,sig_handler); signal(SIGINT,sig_handler);
while((c=getopt(argc,argv,"vr:f:S:yTtai:k:p:nsAxXhHVNdqem:P"))!=EOF){ while((c=getopt(argc,argv,"vr:F:f:S:yTt:ai:k:p:nsAxXhHVNdqem:P"))!=EOF){
switch(c){ switch(c){
case 'v': case 'v':
print_version(); print_version();
@ -319,6 +335,12 @@ int main(argc,argv)
case 'n': case 'n':
NET_print_flags |= NET_PRINT_NO_RESOLVE; NET_print_flags |= NET_PRINT_NO_RESOLVE;
break; break;
case 't':
conn_ttl=atoi(optarg);
break;
case 'F':
conn_freq=atoi(optarg);
break;
case 'm': case 'm':
for(m=modules;m->name!=0;m++){ for(m=modules;m->name!=0;m++){
if(!strcmp(m->name,optarg)){ if(!strcmp(m->name,optarg)){
@ -428,6 +450,7 @@ int main(argc,argv)
if(NET_print_flags & NET_PRINT_TYPESET) if(NET_print_flags & NET_PRINT_TYPESET)
printf("\n.ps\n.fi\n"); printf("\n.ps\n.fi\n");
printf("Cleaning %d remaining connection(s) from connection pool\n", destroy_all_conn());
exit(0); exit(0);
} }

View file

@ -59,6 +59,9 @@ int conn_number=1;
static conn_struct *first_conn=0; static conn_struct *first_conn=0;
extern struct timeval last_packet_seen_time;
extern int conn_ttl;
static int zero_conn PROTO_LIST((tcp_conn *conn)); static int zero_conn PROTO_LIST((tcp_conn *conn));
static int zero_conn(conn) static int zero_conn(conn)
@ -158,10 +161,38 @@ int tcp_destroy_conn(conn)
free_tcp_segment_queue(conn->i2r.oo_queue); free_tcp_segment_queue(conn->i2r.oo_queue);
free_tcp_segment_queue(conn->r2i.oo_queue); free_tcp_segment_queue(conn->r2i.oo_queue);
zero_conn(conn); zero_conn(conn);
free(conn);
return(0); return(0);
} }
int clean_old_conn() {
conn_struct *conn;
tcp_conn *tcpconn;
struct timeval dt;
int i = 0;
for(conn=first_conn;conn;conn=conn->next) {
i++;
tcpconn = &conn->conn;
timestamp_diff(&last_packet_seen_time, &tcpconn->last_seen_time, &dt);
if(dt.tv_sec > conn_ttl) {
tcp_destroy_conn(&(first_conn->conn));
}
}
return i;
}
int destroy_all_conn() {
conn_struct *conn;
int i = 0,r;
while(first_conn) {
i++;
tcp_destroy_conn(&first_conn->conn);
}
return i;
}
int free_tcp_segment_queue(seg) int free_tcp_segment_queue(seg)
segment *seg; segment *seg;
{ {

View file

@ -83,6 +83,7 @@ typedef struct tcp_conn_ {
stream_data r2i; /*The stream from responder to initiator*/ stream_data r2i; /*The stream from responder to initiator*/
struct timeval start_time; struct timeval start_time;
struct timeval last_seen_time;
proto_handler *analyzer; /*The analyzer to call with new data*/ proto_handler *analyzer; /*The analyzer to call with new data*/
struct conn_struct_ *backptr; struct conn_struct_ *backptr;
} tcp_conn; } tcp_conn;

View file

@ -108,6 +108,8 @@ int process_tcp_packet(handler,ctx,p)
stream=direction==DIR_R2I?&conn->r2i:&conn->i2r; stream=direction==DIR_R2I?&conn->r2i:&conn->i2r;
memcpy(&conn->last_seen_time,&p->ts,sizeof(struct timeval));
switch(conn->state){ switch(conn->state){
case TCP_STATE_SYN1: case TCP_STATE_SYN1:
if(direction != DIR_R2I) if(direction != DIR_R2I)
@ -182,6 +184,7 @@ static int new_connection(handler,ctx,p,connp)
conn->state=TCP_STATE_SYN1; conn->state=TCP_STATE_SYN1;
memcpy(&conn->start_time,&p->ts,sizeof(struct timeval)); memcpy(&conn->start_time,&p->ts,sizeof(struct timeval));
memcpy(&conn->last_seen_time,&p->ts,sizeof(struct timeval));
if(r=create_proto_handler(handler,ctx,&conn->analyzer,conn,&p->ts)) if(r=create_proto_handler(handler,ctx,&conn->analyzer,conn,&p->ts))
ABORT(r); ABORT(r);

View file

@ -260,8 +260,9 @@ int ssl_set_client_session_id(d,msg,len)
#ifdef OPENSSL #ifdef OPENSSL
int r; int r;
if(r=r_data_create(&d->session_id,msg,len)) if(len>0)
ERETURN(r); if(r=r_data_create(&d->session_id,msg,len))
ERETURN(r);
#endif #endif
return(0); return(0);
} }

View file

@ -181,6 +181,12 @@ Print the TCP headers.
.B \-v .B \-v
Display version and copyright information. Display version and copyright information.
.TP .TP
.B \-t
Specify the TTL for inactive connections referenced in the connection pool (in seconds, default: 100).
.TP
.B \-F
Specify the number of packets after which a connection pool cleaning is performed (in packets, default: 100).
.TP
.B \-x .B \-x
Print each record in hex, as well as decoding it. Print each record in hex, as well as decoding it.
.TP .TP