bugtracking mode, performance improvement by earlier caching of inode2pid data

This commit is contained in:
Arnout Engelen
2008-06-24 20:01:10 +00:00
parent eca73fa735
commit 76afed26b7
8 changed files with 96 additions and 23 deletions

View File

@@ -154,18 +154,33 @@ void Connection::add (Packet * packet)
} }
} }
/* finds connection to which this packet belongs. /*
* finds connection to which this packet belongs.
* a packet belongs to a connection if it matches * a packet belongs to a connection if it matches
* to its reference packet */ * to its reference packet
*/
Connection * findConnection (Packet * packet) Connection * findConnection (Packet * packet)
{ {
ConnList * current = connections; ConnList * current = connections;
Packet * invertedPacket = packet->newInverted();
while (current != NULL) while (current != NULL)
{ {
/* the reference packet is always *outgoing* */ /* the reference packet is always *outgoing* */
if ((packet->match(current->val->refpacket)) if (packet->match(current->val->refpacket))
|| (invertedPacket->match(current->val->refpacket))) {
return current->val;
}
current = current->next;
}
// Try again, now with the packet inverted:
current = connections;
Packet * invertedPacket = packet->newInverted();
while (current != NULL)
{
/* the reference packet is always *outgoing* */
if (invertedPacket->match(current->val->refpacket))
{ {
delete invertedPacket; delete invertedPacket;
return current->val; return current->val;
@@ -173,6 +188,7 @@ Connection * findConnection (Packet * packet)
current = current->next; current = current->next;
} }
delete invertedPacket; delete invertedPacket;
return NULL; return NULL;
} }

View File

@@ -2,6 +2,7 @@
#include <string> #include <string>
#include <pwd.h> #include <pwd.h>
#include <sys/types.h> #include <sys/types.h>
#include <stdlib.h>
#include <cstdlib> #include <cstdlib>
#include <algorithm> #include <algorithm>
@@ -386,7 +387,7 @@ void do_refresh()
if (viewMode == VIEWMODE_KBPS) if (viewMode == VIEWMODE_KBPS)
{ {
std::cout << "kbps viemode" << std::endl; //std::cout << "kbps viemode" << std::endl;
getkbps (curproc->getVal(), &value_recv, &value_sent); getkbps (curproc->getVal(), &value_recv, &value_sent);
} }
else if (viewMode == VIEWMODE_TOTAL_KB) else if (viewMode == VIEWMODE_TOTAL_KB)

View File

@@ -15,6 +15,8 @@
#include "inode2prog.h" #include "inode2prog.h"
extern bool bughuntmode;
/* maps from inode to program-struct */ /* maps from inode to program-struct */
std::map <unsigned long, prg_node *> inodeproc; std::map <unsigned long, prg_node *> inodeproc;
@@ -193,11 +195,29 @@ struct prg_node * findPID (unsigned long inode)
struct prg_node * node = inodeproc[inode]; struct prg_node * node = inodeproc[inode];
if (node != NULL) if (node != NULL)
{
if (bughuntmode)
{
std::cout << ":) Found pid in inodeproc table" << std::endl;
}
return node; return node;
}
reread_mapping(); reread_mapping();
return inodeproc[inode]; struct prg_node * retval = inodeproc[inode];
if (bughuntmode)
{
if (retval == NULL)
{
std::cout << ":( No pid after inodeproc refresh" << std::endl;
}
else
{
std::cout << ":) Found pid after inodeproc refresh" << std::endl;
}
}
return retval;
} }
void prg_cache_clear() {}; void prg_cache_clear() {};

View File

@@ -14,3 +14,6 @@ struct prg_node {
struct prg_node * findPID (unsigned long inode); struct prg_node * findPID (unsigned long inode);
void prg_cache_clear(); void prg_cache_clear();
// reread the inode-to-prg_node-mapping
void reread_mapping ();

View File

@@ -31,6 +31,7 @@ extern Process * unknownudp;
unsigned refreshdelay = 1; unsigned refreshdelay = 1;
bool tracemode = false; bool tracemode = false;
bool bughuntmode = false;
bool needrefresh = true; bool needrefresh = true;
//packet_type packettype = packet_ethernet; //packet_type packettype = packet_ethernet;
//dp_link_type linktype = dp_link_ethernet; //dp_link_type linktype = dp_link_ethernet;
@@ -89,7 +90,7 @@ int process_tcp (u_char * userdata, const dp_header * header, const u_char * m_p
curtime = header->ts; curtime = header->ts;
/* TODO get info from userdata, then call getPacket */ /* get info from userdata, then call getPacket */
Packet * packet; Packet * packet;
switch (args->sa_family) switch (args->sa_family)
{ {
@@ -101,9 +102,6 @@ int process_tcp (u_char * userdata, const dp_header * header, const u_char * m_p
break; break;
} }
//if (DEBUG)
// std::cout << "Got packet from " << packet->gethashstring() << std::endl;
Connection * connection = findConnection(packet); Connection * connection = findConnection(packet);
if (connection != NULL) if (connection != NULL)
@@ -229,12 +227,13 @@ static void versiondisplay(void)
static void help(void) static void help(void)
{ {
//std::cerr << "usage: nethogs [-V] [-d seconds] [-t] [-p] [-f (eth|ppp))] [device [device [device ...]]]\n"; //std::cerr << "usage: nethogs [-V] [-b] [-d seconds] [-t] [-p] [-f (eth|ppp))] [device [device [device ...]]]\n";
std::cerr << "usage: nethogs [-V] [-d seconds] [-t] [-p] [device [device [device ...]]]\n"; std::cerr << "usage: nethogs [-V] [-b] [-d seconds] [-t] [-p] [device [device [device ...]]]\n";
std::cerr << " -V : prints version.\n"; std::cerr << " -V : prints version.\n";
std::cerr << " -d : delay for update refresh rate in seconds. default is 1.\n"; std::cerr << " -d : delay for update refresh rate in seconds. default is 1.\n";
std::cerr << " -t : tracemode.\n"; std::cerr << " -t : tracemode.\n";
//std::cerr << " -f : format of packets on interface, default is eth.\n"; //std::cerr << " -f : format of packets on interface, default is eth.\n";
std::cerr << " -b : bughunt mode - implies tracemode.\n";
std::cerr << " -p : sniff in promiscious mode (not recommended).\n"; std::cerr << " -p : sniff in promiscious mode (not recommended).\n";
std::cerr << " device : device(s) to monitor. default is eth0\n"; std::cerr << " device : device(s) to monitor. default is eth0\n";
std::cerr << std::endl; std::cerr << std::endl;
@@ -284,6 +283,9 @@ int main (int argc, char** argv)
exit(0); exit(0);
case 'h': help(); case 'h': help();
exit(0); exit(0);
case 'b': bughuntmode = true;
tracemode = true;
break;
case 't': tracemode = true; case 't': tracemode = true;
break; break;
case 'p': promisc = 1; case 'p': promisc = 1;
@@ -324,7 +326,7 @@ int main (int argc, char** argv)
} }
if (NEEDROOT && (getuid() != 0)) if (NEEDROOT && (getuid() != 0))
forceExit("You need to be root to run NetHogs !"); forceExit("You need to be root to run NetHogs!");
char errbuf[PCAP_ERRBUF_SIZE]; char errbuf[PCAP_ERRBUF_SIZE];

View File

@@ -43,7 +43,7 @@ void getLocal (const char *device, bool tracemode)
} }
strcpy(iFreq.ifr_name, device); strcpy(iFreq.ifr_name, device);
if(ioctl(sock, SIOCGIFADDR, &iFreq)<0){ if(ioctl(sock, SIOCGIFADDR, &iFreq)<0){
forceExit("ioctl failed while establishing local IP for device ", device); forceExit("ioctl failed while establishing local IP for selected device ", device);
} }
saddr=(struct sockaddr_in*)&iFreq.ifr_addr; saddr=(struct sockaddr_in*)&iFreq.ifr_addr;
local_addrs = new local_addr (saddr->sin_addr.s_addr, local_addrs); local_addrs = new local_addr (saddr->sin_addr.s_addr, local_addrs);

View File

@@ -238,7 +238,11 @@ Process * findProcess (unsigned long inode)
} }
/* check if we have identified any previously unknown /* check if we have identified any previously unknown
* connections are now known */ * connections are now known
*
* When this is the case, something weird is going on.
* This function is only called in bughunt-mode
*/
void reviewUnknown () void reviewUnknown ()
{ {
ConnList * curr_conn = unknowntcp->connections; ConnList * curr_conn = unknowntcp->connections;
@@ -251,8 +255,8 @@ void reviewUnknown ()
Process * proc = findProcess (inode); Process * proc = findProcess (inode);
if (proc != unknowntcp && proc != NULL) if (proc != unknowntcp && proc != NULL)
{ {
if (DEBUG) if (DEBUG || bughuntmode)
std::cout << "ITP: WARNING: Previously unknown inode " << inode << " now got process...??\n"; std::cout << "FIXME: Previously unknown inode " << inode << " now got process - apparently it makes sense to review unknown connections\n";
/* Yay! - but how can this happen? */ /* Yay! - but how can this happen? */
if (!ROBUST) if (!ROBUST)
assert(false); assert(false);
@@ -327,7 +331,7 @@ Process * getProcess (unsigned long inode, char * devicename)
if (node == NULL) if (node == NULL)
{ {
if (DEBUG) if (DEBUG || bughuntmode)
std::cout << "No PID information for inode " << inode << std::endl; std::cout << "No PID information for inode " << inode << std::endl;
return unknowntcp; return unknowntcp;
} }
@@ -386,11 +390,28 @@ Process * getProcess (Connection * connection, char * devicename)
if (inode == 0) if (inode == 0)
{ {
// no? refresh and check conn/inode table // no? refresh and check conn/inode table
#if DEBUG if (bughuntmode)
std::cout << "LOC: new connection not in connection-to-inode table.\n"; {
#endif std::cout << "? new connection not in connection-to-inode table before refresh.\n";
}
// refresh the inode->pid table first. Presumably processing the renewed connection->inode table
// is slow, making this worthwhile.
// We take the fact for granted that we might already know the inode->pid (unlikely anyway if we
// haven't seen the connection->inode yet though).
reread_mapping();
refreshconninode(); refreshconninode();
inode = conninode[connection->refpacket->gethashstring()]; inode = conninode[connection->refpacket->gethashstring()];
if (bughuntmode)
{
if (inode == 0)
{
std::cout << ":( inode for connection not found after refresh.\n";
}
else
{
std::cout << ":) inode for connection found after refresh.\n";
}
}
#if REVERSEHACK #if REVERSEHACK
if (inode == 0) if (inode == 0)
{ {
@@ -406,7 +427,7 @@ Process * getProcess (Connection * connection, char * devicename)
if (inode == 0) if (inode == 0)
{ {
delete reversepacket; delete reversepacket;
if (DEBUG) if (bughuntmode || DEBUG)
std::cout << "LOC: " << connection->refpacket->gethashstring() << " STILL not in connection-to-inode table - adding to the unknown process\n"; std::cout << "LOC: " << connection->refpacket->gethashstring() << " STILL not in connection-to-inode table - adding to the unknown process\n";
unknowntcp->connections = new ConnList (connection, unknowntcp->connections); unknowntcp->connections = new ConnList (connection, unknowntcp->connections);
return unknowntcp; return unknowntcp;
@@ -417,6 +438,15 @@ Process * getProcess (Connection * connection, char * devicename)
} }
#endif #endif
} }
else if (bughuntmode)
{
std::cout << ";) new connection in connection-to-inode table before refresh.\n";
}
if (bughuntmode)
{
std::cout << " inode # " << inode << std::endl;
}
Process * proc; Process * proc;
if (inode == 0) { if (inode == 0) {

View File

@@ -6,6 +6,7 @@
#include "connection.h" #include "connection.h"
extern bool tracemode; extern bool tracemode;
extern bool bughuntmode;
void check_all_procs (); void check_all_procs ();