X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Flibtcp-portmon.c;h=5881cc902ad79ba9d3575b4cd47a3e9e9c928aab;hb=6aef55aa00257f61eecf4dde7f9710429b3b082e;hp=9714cd10562c475095ff163f8e3ca6b9fae49842;hpb=257dd33e55862c1b10388117c5a4cbb253f7861d;p=monky diff --git a/src/libtcp-portmon.c b/src/libtcp-portmon.c index 9714cd1..5881cc9 100644 --- a/src/libtcp-portmon.c +++ b/src/libtcp-portmon.c @@ -30,6 +30,28 @@ * functions. Use the "Client interface" functions defined at bottom. * ------------------------------------------------------------------- */ +/* ---------------------------------- + * Copy a tcp_connection_t + * + * Returns 0 on success, -1 otherwise. + * ----------------------------------*/ +int copy_tcp_connection( + tcp_connection_t * p_dest_connection, + const tcp_connection_t * p_source_connection + ) +{ + if ( !p_dest_connection || !p_source_connection ) + return (-1); + + p_dest_connection->local_addr = p_source_connection->local_addr; + p_dest_connection->local_port = p_source_connection->local_port; + p_dest_connection->remote_addr = p_source_connection->remote_addr; + p_dest_connection->remote_port = p_source_connection->remote_port; + p_dest_connection->age = p_source_connection->age; + + return 0; +} + /* ----------------------------------------------------------------------------- * Open-addressed hash implementation requires that we supply two hash functions * and a match function to compare two hash elements for identity. @@ -209,8 +231,8 @@ int monitor_match_function( const void *p_data1, const void *p_data2 ) p_monitor1 = (tcp_port_monitor_t *)p_data1; p_monitor2 = (tcp_port_monitor_t *)p_data2; - return (p_monitor1->port_range_begin == p_monitor1->port_range_begin && - p_monitor2->port_range_end == p_monitor2->port_range_end); + return (p_monitor1->port_range_begin == p_monitor2->port_range_begin && + p_monitor1->port_range_end == p_monitor2->port_range_end); } /* --------------------------------------------------------------------------- @@ -328,7 +350,7 @@ void maintain_tcp_port_monitor_hash( #ifdef HASH_DEBUG fprintf(stderr,"--- num vacated is %d, vacated factor is %.3f\n", p_monitor->hash.vacated, vacated_load ); #endif - if ( vacated_load <= TCP_CONNECIION_HASH_MAX_VACATED_RATIO ) + if ( vacated_load <= TCP_CONNECTION_HASH_MAX_VACATED_RATIO ) { /* hash is fine and needs no rebalancing */ return; @@ -397,6 +419,8 @@ void show_connection_to_tcp_port_monitor( if ( !p_monitor || !p_void ) return; + /* This p_connection is on caller's stack and not the heap. If we are interested, + * we will create a copy of the connection (on the heap) and add it to our list. */ tcp_connection_t *p_connection = (tcp_connection_t *)p_void; /* inspect the local port number of the connection to see if we're interested. */ @@ -413,7 +437,7 @@ void show_connection_to_tcp_port_monitor( /* it's already in the hash. reset the age of the connection. */ if ( p_connection != NULL ) { - p_connection->age = TCP_CONNECIION_STARTING_AGE; + p_connection->age = TCP_CONNECTION_STARTING_AGE; } return; @@ -436,8 +460,15 @@ void show_connection_to_tcp_port_monitor( if ( (p_node = (tcp_connection_node_t *) calloc(1, sizeof(tcp_connection_node_t))) == NULL ) return; - p_node->connection = *p_connection; /* bitwise copy of the struct */ - p_node->connection.age = TCP_CONNECIION_STARTING_AGE; + /* copy the connection data */ + if ( copy_tcp_connection( &p_node->connection, p_connection ) != 0 ) + { + /* error copying the connection data. deallocate p_node to avoid leaks and return. */ + free( p_node ); + return; + } + + p_node->connection.age = TCP_CONNECTION_STARTING_AGE; p_node->p_next = NULL; /* insert it into the monitor's hash table */ @@ -590,7 +621,7 @@ tcp_port_monitor_t * create_tcp_port_monitor( The requested monitor value is copied into a client-supplied char buffer. Returns 0 on success, -1 otherwise. */ int peek_tcp_port_monitor( - tcp_port_monitor_t * p_monitor, + const tcp_port_monitor_t * p_monitor, int item, int connection_index, char * p_buffer, @@ -763,7 +794,7 @@ void update_tcp_port_monitor_collection( FILE *fp; char buf[256]; tcp_connection_t conn; - unsigned long state; + unsigned long inode,uid,state; if ( !p_collection ) return; @@ -785,14 +816,14 @@ void update_tcp_port_monitor_collection( /* read all tcp connections */ while (fgets (buf, sizeof (buf), fp) != NULL) { - if ( sscanf (buf, "%*d: %lx:%lx %lx:%lx %lx %*x:%*x %*x:%*x %*x %lu %*d %lu", - (unsigned long *)&conn.local_addr, (unsigned long *)&conn.local_port, - (unsigned long *)&conn.remote_addr, (unsigned long *)&conn.remote_port, - (unsigned long *)&state, (unsigned long *)&conn.uid, (unsigned long *)&conn.inode) != 7 ) + if ( sscanf (buf, "%*d: %lx:%hx %lx:%hx %lx %*x:%*x %*x:%*x %*x %lu %*d %lu", + (unsigned long *)&conn.local_addr, &conn.local_port, + (unsigned long *)&conn.remote_addr, &conn.remote_port, + (unsigned long *)&state, (unsigned long *)&uid, (unsigned long *)&inode) != 7 ) fprintf( stderr, "/proc/net/tcp: bad file format\n" ); - if ((conn.inode == 0) || (state != TCP_ESTABLISHED)) continue; + if ((inode == 0) || (state != TCP_ESTABLISHED)) continue; /* show the connection to each port monitor. */ for_each_tcp_port_monitor_in_collection( @@ -871,7 +902,7 @@ int insert_tcp_port_monitor_into_collection( /* Clients need a way to find monitors */ tcp_port_monitor_t * find_tcp_port_monitor( - tcp_port_monitor_collection_t * p_collection, + const tcp_port_monitor_collection_t * p_collection, in_port_t port_range_begin, in_port_t port_range_end )