removed multithreading and c++11 and used a pcap_loop-like api
This commit is contained in:
@@ -14,12 +14,12 @@ ifeq ($(DEBUG),1)
|
|||||||
$(info Bulding debug version)
|
$(info Bulding debug version)
|
||||||
ODIR:=$(ODIR_BASE)/lib/debug
|
ODIR:=$(ODIR_BASE)/lib/debug
|
||||||
CFLAGS?=-Wall -Wextra -O0 -g -fPIC $(VISIBILITY)
|
CFLAGS?=-Wall -Wextra -O0 -g -fPIC $(VISIBILITY)
|
||||||
CXXFLAGS?=-Wall --std=c++0x -Wextra -O0 -g -fPIC $(VISIBILITY) $(CXXINCLUDES)
|
CXXFLAGS?=-Wall -Wextra -O0 -g -fPIC $(VISIBILITY) $(CXXINCLUDES)
|
||||||
else
|
else
|
||||||
# Release mode options
|
# Release mode options
|
||||||
ODIR:=$(ODIR_BASE)/lib/release
|
ODIR:=$(ODIR_BASE)/lib/release
|
||||||
CFLAGS?=-Wall -Wextra -O3 -fPIC $(VISIBILITY)
|
CFLAGS?=-Wall -Wextra -O3 -fPIC $(VISIBILITY)
|
||||||
CXXFLAGS?=-Wall --std=c++0x -Wextra -O3 -fPIC $(VISIBILITY) $(CXXINCLUDES)
|
CXXFLAGS?=-Wall -Wextra -O3 -fPIC $(VISIBILITY) $(CXXINCLUDES)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
OBJ_NAMES= libnethogs.o packet.o connection.o process.o refresh.o decpcap.o inode2prog.o conninode.o devices.o
|
OBJ_NAMES= libnethogs.o packet.o connection.o process.o refresh.o decpcap.o inode2prog.o conninode.o devices.o
|
||||||
|
|||||||
116
libnethogs.cpp
116
libnethogs.cpp
@@ -4,16 +4,12 @@ extern "C"
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include "nethogs.cpp"
|
#include "nethogs.cpp"
|
||||||
#include <pthread.h>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <mutex>
|
|
||||||
#include <condition_variable>
|
|
||||||
#include <atomic>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <thread>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
extern ProcList * processes;
|
extern ProcList * processes;
|
||||||
@@ -22,12 +18,10 @@ extern Process * unknownudp;
|
|||||||
extern Process * unknownip;
|
extern Process * unknownip;
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
|
|
||||||
static std::shared_ptr<std::thread> monitor_thread_ptr;
|
|
||||||
static std::atomic_bool monitor_thread_run_flag(false);
|
|
||||||
|
|
||||||
//The self_pipe is used to interrupt the select() in the main loop
|
//The self_pipe is used to interrupt the select() in the main loop
|
||||||
static std::pair<int,int> self_pipe = std::make_pair(-1, -1);
|
static std::pair<int,int> self_pipe = std::make_pair(-1, -1);
|
||||||
|
|
||||||
|
static bool monitor_run_flag = false;
|
||||||
static NethogsMonitorCallback monitor_udpate_callback;
|
static NethogsMonitorCallback monitor_udpate_callback;
|
||||||
typedef std::map<int, NethogsMonitorUpdate> NethogsAppUpdateMap;
|
typedef std::map<int, NethogsMonitorUpdate> NethogsAppUpdateMap;
|
||||||
static NethogsAppUpdateMap monitor_update_data;
|
static NethogsAppUpdateMap monitor_update_data;
|
||||||
@@ -57,7 +51,7 @@ static std::pair<int, int> create_self_pipe()
|
|||||||
return std::make_pair(pfd[0], pfd[1]);
|
return std::make_pair(pfd[0], pfd[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wait_for_next_trigger()
|
static bool wait_for_next_trigger()
|
||||||
{
|
{
|
||||||
if( pc_loop_use_select )
|
if( pc_loop_use_select )
|
||||||
{
|
{
|
||||||
@@ -71,13 +65,20 @@ static void wait_for_next_trigger()
|
|||||||
FD_SET(fd, &pc_loop_fd_set);
|
FD_SET(fd, &pc_loop_fd_set);
|
||||||
}
|
}
|
||||||
timeval timeout = {monitor_refresh_delay, 0};
|
timeval timeout = {monitor_refresh_delay, 0};
|
||||||
select(nfds, &pc_loop_fd_set, 0, 0, &timeout);
|
if( select(nfds, &pc_loop_fd_set, 0, 0, &timeout) != -1 )
|
||||||
|
{
|
||||||
|
if( FD_ISSET(self_pipe.first, &pc_loop_fd_set) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If select() not possible, pause to prevent 100%
|
// If select() not possible, pause to prevent 100%
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nethogsmonitor_init()
|
static int nethogsmonitor_init()
|
||||||
@@ -178,7 +179,7 @@ static int nethogsmonitor_init()
|
|||||||
return NETHOGS_STATUS_OK;
|
return NETHOGS_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nethogsmonitor_handle_update()
|
static void nethogsmonitor_handle_update(NethogsMonitorCallback cb)
|
||||||
{
|
{
|
||||||
refreshconninode();
|
refreshconninode();
|
||||||
refreshcount++;
|
refreshcount++;
|
||||||
@@ -205,17 +206,14 @@ static void nethogsmonitor_handle_update()
|
|||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
std::cout << "PROC: Deleting process\n";
|
std::cout << "PROC: Deleting process\n";
|
||||||
|
|
||||||
if( monitor_udpate_callback )
|
|
||||||
{
|
|
||||||
NethogsAppUpdateMap::iterator it = monitor_update_data.find(curproc->getVal()->pid);
|
NethogsAppUpdateMap::iterator it = monitor_update_data.find(curproc->getVal()->pid);
|
||||||
if( it != monitor_update_data.end() )
|
if( it != monitor_update_data.end() )
|
||||||
{
|
{
|
||||||
NethogsMonitorUpdate& data = it->second;
|
NethogsMonitorUpdate& data = it->second;
|
||||||
data.action = NETHOGS_APP_ACTION_REMOVE;
|
data.action = NETHOGS_APP_ACTION_REMOVE;
|
||||||
monitor_udpate_callback(&data);
|
(*cb)(&data);
|
||||||
monitor_update_data.erase(curproc->getVal()->pid);
|
monitor_update_data.erase(curproc->getVal()->pid);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ProcList * todelete = curproc;
|
ProcList * todelete = curproc;
|
||||||
Process * p_todelete = curproc->getVal();
|
Process * p_todelete = curproc->getVal();
|
||||||
@@ -244,8 +242,6 @@ static void nethogsmonitor_handle_update()
|
|||||||
curproc->getVal()->getkbps (&recv_kbs, &sent_kbs);
|
curproc->getVal()->getkbps (&recv_kbs, &sent_kbs);
|
||||||
curproc->getVal()->gettotal (&recv_bytes, &sent_bytes);
|
curproc->getVal()->gettotal (&recv_bytes, &sent_bytes);
|
||||||
|
|
||||||
if( monitor_udpate_callback )
|
|
||||||
{
|
|
||||||
//notify update
|
//notify update
|
||||||
bool const new_data = (monitor_update_data.find(pid) == monitor_update_data.end());
|
bool const new_data = (monitor_update_data.find(pid) == monitor_update_data.end());
|
||||||
NethogsMonitorUpdate &data = monitor_update_data[pid];
|
NethogsMonitorUpdate &data = monitor_update_data[pid];
|
||||||
@@ -274,8 +270,7 @@ static void nethogsmonitor_handle_update()
|
|||||||
if( data_change )
|
if( data_change )
|
||||||
{
|
{
|
||||||
data.action = NETHOGS_APP_ACTION_SET;
|
data.action = NETHOGS_APP_ACTION_SET;
|
||||||
monitor_udpate_callback(&data);
|
(*cb)(&data);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//next
|
//next
|
||||||
@@ -285,13 +280,45 @@ static void nethogsmonitor_handle_update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nethogsmonitor_threadproc()
|
static void nethogsmonitor_clean_up()
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Waiting for first packet to arrive (see sourceforge.net bug 1019381)\n");
|
//clean up
|
||||||
|
handle * current_handle = handles;
|
||||||
|
while (current_handle != NULL)
|
||||||
|
{
|
||||||
|
pcap_close(current_handle->content->pcap_handle);
|
||||||
|
current_handle = current_handle->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
//close file descriptors
|
||||||
|
for(std::vector<int>::const_iterator it=pc_loop_fd_list.begin();
|
||||||
|
it != pc_loop_fd_list.end(); ++it)
|
||||||
|
{
|
||||||
|
close(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
procclean();
|
||||||
|
}
|
||||||
|
|
||||||
|
int nethogsmonitor_loop(NethogsMonitorCallback cb)
|
||||||
|
{
|
||||||
|
if( monitor_run_flag )
|
||||||
|
{
|
||||||
|
return NETHOGS_STATUS_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int return_value = nethogsmonitor_init();
|
||||||
|
if( return_value != NETHOGS_STATUS_OK )
|
||||||
|
{
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor_run_flag = true;
|
||||||
|
|
||||||
struct dpargs * userdata = (dpargs *) malloc (sizeof (struct dpargs));
|
struct dpargs * userdata = (dpargs *) malloc (sizeof (struct dpargs));
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
while (monitor_thread_run_flag)
|
while (monitor_run_flag)
|
||||||
{
|
{
|
||||||
bool packets_read = false;
|
bool packets_read = false;
|
||||||
|
|
||||||
@@ -320,50 +347,25 @@ static void nethogsmonitor_threadproc()
|
|||||||
if( monitor_last_refresh_time + monitor_refresh_delay <= now )
|
if( monitor_last_refresh_time + monitor_refresh_delay <= now )
|
||||||
{
|
{
|
||||||
monitor_last_refresh_time = now;
|
monitor_last_refresh_time = now;
|
||||||
nethogsmonitor_handle_update();
|
nethogsmonitor_handle_update(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!packets_read)
|
if (!packets_read)
|
||||||
{
|
{
|
||||||
wait_for_next_trigger();
|
if( !wait_for_next_trigger() )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handle * current_handle = handles;
|
nethogsmonitor_clean_up();
|
||||||
while (current_handle != NULL)
|
|
||||||
{
|
return NETHOGS_STATUS_OK;
|
||||||
pcap_close(current_handle->content->pcap_handle);
|
|
||||||
current_handle = current_handle->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nethogsmonitor_register_callback(NethogsMonitorCallback cb)
|
void nethogsmonitor_breakloop()
|
||||||
{
|
|
||||||
if( !monitor_thread_run_flag )
|
|
||||||
{
|
|
||||||
monitor_udpate_callback = cb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int nethogsmonitor_start()
|
|
||||||
{
|
|
||||||
bool expected = false;
|
|
||||||
int ret = NETHOGS_STATUS_OK;
|
|
||||||
if( monitor_thread_run_flag.compare_exchange_strong(expected, true) )
|
|
||||||
{
|
|
||||||
ret = nethogsmonitor_init();
|
|
||||||
monitor_thread_ptr = std::make_shared<std::thread>(&nethogsmonitor_threadproc);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nethogsmonitor_stop()
|
|
||||||
{
|
|
||||||
bool expected = true;
|
|
||||||
if( monitor_thread_run_flag.compare_exchange_strong(expected, false) )
|
|
||||||
{
|
{
|
||||||
|
monitor_run_flag = false;
|
||||||
write(self_pipe.second, "x", 1);
|
write(self_pipe.second, "x", 1);
|
||||||
monitor_thread_ptr->join();
|
|
||||||
monitor_udpate_callback = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
18
libnethogs.h
18
libnethogs.h
@@ -33,15 +33,19 @@ typedef struct NethogsMonitorUpdate
|
|||||||
|
|
||||||
typedef void(*NethogsMonitorCallback)(NethogsMonitorUpdate const*);
|
typedef void(*NethogsMonitorCallback)(NethogsMonitorUpdate const*);
|
||||||
|
|
||||||
//register async callback to receive updates
|
/**
|
||||||
//have to be called before start
|
* @brief Enter the process monitoring loop and reports updates using the
|
||||||
NETHOGS_DSO_VISIBLE void nethogsmonitor_register_callback(NethogsMonitorCallback);
|
* callback provided as parameter.
|
||||||
|
* This call will block until nethogsmonitor_stop is called or a failure occurs.
|
||||||
|
* @param cb A pointer to a callback function following the NethogsMonitorCallback definition
|
||||||
|
*/
|
||||||
|
|
||||||
//start the monitor (return one of the NETHOGS_STATUS above)
|
NETHOGS_DSO_VISIBLE int nethogsmonitor_loop(NethogsMonitorCallback cb);
|
||||||
NETHOGS_DSO_VISIBLE int nethogsmonitor_start();
|
|
||||||
|
|
||||||
//stop the monitor
|
/**
|
||||||
NETHOGS_DSO_VISIBLE void nethogsmonitor_stop();
|
* @brief Makes the call to nethogsmonitor_loop return.
|
||||||
|
*/
|
||||||
|
NETHOGS_DSO_VISIBLE void nethogsmonitor_breakloop();
|
||||||
|
|
||||||
#undef NETHOGS_DSO_VISIBLE
|
#undef NETHOGS_DSO_VISIBLE
|
||||||
#undef NETHOGS_DSO_HIDDEN
|
#undef NETHOGS_DSO_HIDDEN
|
||||||
|
|||||||
Reference in New Issue
Block a user