[SIGAR-4] Move to walk version of net_stat

This commit is contained in:
Doug MacEachern 2007-04-06 12:14:38 +00:00
parent 86deb1a2d9
commit 614fd63728
2 changed files with 33 additions and 97 deletions

View File

@ -66,7 +66,8 @@
char *ifconf_buf; \ char *ifconf_buf; \
int ifconf_len; \ int ifconf_len; \
char *self_path; \ char *self_path; \
sigar_cache_t *proc_cpu sigar_cache_t *proc_cpu; \
sigar_cache_t *net_listen
#if defined(WIN32) #if defined(WIN32)
# define SIGAR_INLINE __inline # define SIGAR_INLINE __inline

View File

@ -38,6 +38,7 @@ SIGAR_DECLARE(int) sigar_open(sigar_t **sigar)
(*sigar)->ptql_re_data = NULL; (*sigar)->ptql_re_data = NULL;
(*sigar)->self_path = NULL; (*sigar)->self_path = NULL;
(*sigar)->proc_cpu = NULL; (*sigar)->proc_cpu = NULL;
(*sigar)->net_listen = NULL;
} }
return status; return status;
@ -54,6 +55,9 @@ SIGAR_DECLARE(int) sigar_close(sigar_t *sigar)
if (sigar->proc_cpu) { if (sigar->proc_cpu) {
sigar_cache_destroy(sigar->proc_cpu); sigar_cache_destroy(sigar->proc_cpu);
} }
if (sigar->net_listen) {
sigar_cache_destroy(sigar->net_listen);
}
return sigar_os_close(sigar); return sigar_os_close(sigar);
} }
@ -843,7 +847,6 @@ sigar_net_connection_list_get(sigar_t *sigar,
typedef struct { typedef struct {
sigar_net_stat_t *netstat; sigar_net_stat_t *netstat;
sigar_cache_t *listen_ports;
sigar_net_connection_list_t *connlist; sigar_net_connection_list_t *connlist;
} net_stat_getter_t; } net_stat_getter_t;
@ -856,21 +859,23 @@ static int net_stat_walker(sigar_net_connection_walker_t *walker,
sigar_net_connection_t *conn) sigar_net_connection_t *conn)
{ {
int state = conn->state; int state = conn->state;
sigar_cache_t *listen_ports = walker->sigar->net_listen;
net_stat_getter_t *getter = net_stat_getter_t *getter =
(net_stat_getter_t *)walker->data; (net_stat_getter_t *)walker->data;
if (conn->type == SIGAR_NETCONN_TCP) { if (conn->type == SIGAR_NETCONN_TCP) {
getter->netstat->tcp_states[state]++; getter->netstat->tcp_states[state]++;
/* XXX listen_ports may get stale */
if (state == SIGAR_TCP_LISTEN) { if (state == SIGAR_TCP_LISTEN) {
sigar_cache_entry_t *entry = sigar_cache_entry_t *entry =
sigar_cache_get(getter->listen_ports, sigar_cache_get(listen_ports,
conn->local_port); conn->local_port);
entry->value = (void*)conn->local_port; entry->value = (void*)conn->local_port;
} }
else { else {
if (sigar_cache_find(getter->listen_ports, if (sigar_cache_find(listen_ports,
conn->local_port)) conn->local_port))
{ {
getter->netstat->tcp_inbound_total++; getter->netstat->tcp_inbound_total++;
@ -884,109 +889,39 @@ static int net_stat_walker(sigar_net_connection_walker_t *walker,
/*XXX*/ /*XXX*/
} }
getter->netstat->all_inbound_total =
getter->netstat->tcp_inbound_total;
getter->netstat->all_outbound_total =
getter->netstat->tcp_outbound_total;
return SIGAR_OK; return SIGAR_OK;
} }
static int sigar_net_stat_get_walk(sigar_t *sigar,
sigar_net_stat_t *netstat,
int flags)
{
int status;
sigar_net_connection_walker_t walker;
net_stat_getter_t getter;
getter.netstat = netstat;
getter.listen_ports = sigar_cache_new(32);
getter.listen_ports->free_value = listen_port_free;
walker.sigar = sigar;
walker.data = &getter;
walker.add_connection = net_stat_walker;
walker.flags = flags;
status = sigar_net_connection_walk(&walker);
sigar_cache_destroy(getter.listen_ports);
return status;
}
static int sigar_net_stat_get_list(sigar_t *sigar,
sigar_net_stat_t *netstat,
int flags)
{
int status, i;
sigar_net_connection_list_t connlist;
sigar_cache_t *listen_ports;
status = sigar_net_connection_list_get(sigar, &connlist, flags);
if (status != SIGAR_OK) {
return status;
}
listen_ports = sigar_cache_new(32);
listen_ports->free_value = listen_port_free;
/* first pass, get states and listening port numbers */
for (i=0; i<connlist.number; i++) {
sigar_net_connection_t *conn = &connlist.data[i];
int state = conn->state;
netstat->tcp_states[state]++;
if (state == SIGAR_TCP_LISTEN) {
sigar_cache_entry_t *entry =
sigar_cache_get(listen_ports,
conn->local_port);
entry->value = (void*)conn->local_port;
}
}
/* second pass, get addresses connected to listening ports */
for (i=0; i<connlist.number; i++) {
sigar_net_connection_t *conn = &connlist.data[i];
if (conn->state != SIGAR_TCP_LISTEN) {
if (sigar_cache_find(listen_ports,
conn->local_port))
{
netstat->tcp_inbound_total++;
}
else {
netstat->tcp_outbound_total++;
}
}
}
sigar_cache_destroy(listen_ports);
sigar_net_connection_list_destroy(sigar, &connlist);
return status;
}
SIGAR_DECLARE(int) SIGAR_DECLARE(int)
sigar_net_stat_get(sigar_t *sigar, sigar_net_stat_get(sigar_t *sigar,
sigar_net_stat_t *netstat, sigar_net_stat_t *netstat,
int flags) int flags)
{ {
sigar_net_connection_walker_t walker;
net_stat_getter_t getter;
if (!sigar->net_listen) {
sigar->net_listen = sigar_cache_new(32);
sigar->net_listen->free_value = listen_port_free;
}
SIGAR_ZERO(netstat); SIGAR_ZERO(netstat);
if (getenv("SIGAR_NETSTAT_WALK")) { getter.netstat = netstat;
/* XXX only for testing atm
* The 'walk' version is faster that the 'list' version, walker.sigar = sigar;
* however the 'walk' version depends on the underlying walker.data = &getter;
* OS to return connections in the LISTEN state before walker.add_connection = net_stat_walker;
* those which are connected to the given LISTEN port.
* Seems this is the case in Linux at least, but that walker.flags = flags;
* is likely subject to change.
*/ return sigar_net_connection_walk(&walker);
return sigar_net_stat_get_walk(sigar, netstat, flags);
}
else {
return sigar_net_stat_get_list(sigar, netstat, flags);
}
} }
typedef struct { typedef struct {