/*
* tracker.c -- connection status handler
* Part of the tcpick project
*
* Author: Francesco Stablum <duskdruid @ despammed.com>
*
* Copyright (C) 2003, 2004 Francesco Stablum
* Licensed under the GPL
*
*/
/*
* 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.
*/
#include "tcpick.h"
#include "extern.h"
struct CONN * first_conn = NULL; /*all connections, ends on a 0*/
struct CONN * last_conn = NULL;
int
status_switch(struct CONN * prev, enum STATUS status)
{
#define CURR (prev->next)
display_status( stdout, CURR, status );
if ( status == CLOSED ||
status == RESET ||
status == EXPIRED )
rmconn( prev );
else
CURR->status = status;
}
int
newconn( struct CONN * prev_ring )
/* allocates a new connection */
{
struct CONN * conn;
if( flags.trackonly != -1 ) {
if( flags.trackonly_first &&
( count_conns >= flags.trackonly ) )
return -1;
else if( count_opened >= flags.trackonly )
return -1;
else
count_opened++;
}
count_conns++;
conn = ( struct CONN * )S_calloc( sizeof( struct CONN ), 1 );
prev_ring->next = conn; /* and the chain becomes longer... :)
thank you mainman for this good idea! */
last_conn = conn;
conn->client.side = CLIENT;
conn->server.side = SERVER;
conn->client.ip.s_addr = ippacket->ip_src.s_addr;
conn->server.ip.s_addr = ippacket->ip_dst.s_addr;
conn->client.port = tcppacket->source;
conn->server.port = tcppacket->dest;
conn->client.sip = ntohl(tcppacket->seq) + 1;
conn->client.oth = & (conn->server);
conn->server.oth = & (conn->client);
conn->num = count_conns;
conn->lasttime = time(NULL);
status_switch( prev_ring, SYN_SENT );
}
int rmconn( struct CONN * prev_ring )
/* removes from the linked-list and deallocates a connection
* prev_ring
*/
{
struct CONN * curr = prev_ring->next;
struct CONN * conn;
prev_ring->next = curr->next;
if( curr->next == NULL )
last_conn = prev_ring;
free_desc( &(curr->client) );
free_desc( &(curr->server) );
S_free( curr );
conn = first_conn;
if( flags.exitclosed ) {
if( flags.exitclosed_first ) { /* -Ef */
while( conn->num > flags.exitclosed ) {
if(! (conn->next) )
exit( EXIT_SUCCESS );
conn = conn->next;
}
} else { /* -E */
--flags.exitclosed;
if( flags.exitclosed == 0)
exit( EXIT_SUCCESS );
}
}
if( flags.trackonly &&
(! flags.trackonly_first) )
count_opened--;
}
int free_desc( struct HOST_DESC * desc )
/* frees the host descriptor and closes the file */
{
struct FRAGMENT * tmp;
if( desc->file ) {
fclose( desc->file );
if (flags.writer.type == UNIQUE)
desc->oth->file = NULL;
}
if( desc->filename ) {
S_free( desc->filename );
desc->filename = NULL;
}
if( desc->lockfilename ) {
unlink( desc->lockfilename );
S_free( desc->lockfilename );
desc->lockfilename = NULL;
}
while( desc->unack ) { /* FIXME: desc->unack should be just NULL when closes!
* I should check it! */
S_free( desc->unack->payload );
desc->unack->payload = NULL;
tmp = desc->unack;
desc->unack = desc->unack->next;
S_free( tmp );
}
}
syntax highlighted by Code2HTML, v. 0.9.1