Commit 60bcf59a authored by Arne Øslebø's avatar Arne Øslebø
Browse files

Fixed pointer errors and memory leaks


git-svn-id: file:///home/svn/mapi/trunk@328 8d5bb341-7cf1-0310-8cf6-ba355fef3186
parent 50b20a45
......@@ -48,6 +48,10 @@ else
CFLAGS := $(CFLAGS) -DDEBUG=$(DEBUG) $(INCLUDE) -DWITH_FUNCT_STATS -DWITH_MODIFY_PKTS -DPRIORITIES=$(PRIORITIES)
endif
ifeq ($(VALGRIND),1)
CFLAGS := $(CFLAGS) -DVALGRIND
endif
all: $(TARGETS) $(DAG) $(COMBOSIX) $(IPFIX_TARGETS) $(ETHEREAL_TARGETS) $(ANONYMIZATION_TARGETS)
mapi.o: mapi.c mapi.h mapiipc.h mapidlib.h mapid.h mapidrv.h mapi_errors.h mapierror.h mapidflib.h parseconf.c $(ADMCTRL_BYTESTREAM_H)
......
......@@ -23,7 +23,7 @@ WITH_DIMAPI=0
WITH_FUNCT_STATS=1
#Support for flow priorities
WITH_PRIORITIES=1
WITH_PRIORITIES=0
PRIORITIES=3
#Support for functions that modifies packets
......@@ -35,6 +35,10 @@ WITH_ANONYMIZATION=0
#Ipfix flow record generation
WITH_IPFIX=0
#Set to 1 for easier debugging using valgrind
#This keeps drivers loaded and causes memory leak when mapid is shut down
VALGRIND=1
#Ethereal filters
#Warning, ethereal-filters could easily kill mapid
#if not handled correctly by the client. This library
......
......@@ -129,8 +129,8 @@ int (*mapidrv_create_flow) (int devid, int fd, char **devtype);
int (*mapidrv_create_offline_flow) (int devid, int format, int fd,
char **devtype);
int (*mapidrv_close_flow) (int devid, int fd);
int (*mapidrv_apply_function) (int devid, int fd,int pid, char *function, ...);
int (*mapidrv_read_results) (int devid, int fd, int fid,int pid, void *result);
int (*mapidrv_apply_function) (int devid, int fd, char *function, ...);
int (*mapidrv_read_results) (int devid, int fd, int fid, void *result);
int (*mapidrv_connect) (int devid, int fd);
int (*mapidrv_start_offline_device) (int devid);
int (*mapidrv_get_errno) (int devid, int fd);
......@@ -156,7 +156,6 @@ static unsigned fdseed = 0; // flow descriptor seed (always increases)
#endif
static flist_t *clientlist = NULL; // registered clients (processes)
static slist_t *functionlist = NULL;
static mapidrv *drvlist = NULL;
static int running_shutdown = 0;
//static char *libpath,*libs;
......@@ -175,10 +174,8 @@ mapid_shutdown (int data)
flist_node_t *cur;
struct client *cl;
mapidrv *drv = drvlist;
#ifdef LEAKS
mapidrv *unloadlist;
int unloading;
#endif
/* espenb TODO: use lock mechanisms instead
* each thread receives signals, only one thread must execute
* shutdown, only one shutdown necessary
......@@ -213,32 +210,16 @@ mapid_shutdown (int data)
while (drv)
{
drvlist = drvlist->next;
mapidrv_delete_device = NULL;
if(drv->active)
{
mapidrv_delete_device = get_drv_funct (drv->handle, "mapidrv_delete_device");
}
mapidrv_delete_device = get_drv_funct (drv->handle, "mapidrv_delete_device");
if (mapidrv_delete_device)
{
if(drv->active)
mapidrv_delete_device (drv->devid);
}
mapidrv_delete_device (drv->devid);
/* if we close, we lose the symbol information associated with drivers
* when running valgrind.
*/
#ifdef LEAKS
unloading = 1;
if(drv->next!=NULL)
{
for(unloadlist = drv->next;unloadlist!=NULL;unloadlist = unloadlist->next)
{
if(unloadlist->handle==drv->handle)
unloading = 0;
}
}
if(unloading)
dlclose (drv->handle);
#ifndef VALGRIND
printf("!!dlclose\n");
dlclose(drv->handle);
#endif
free (drv->device);
if(drv->description!=NULL)
......@@ -252,7 +233,6 @@ mapid_shutdown (int data)
/* //Remove flowlist
flist_destroy (flowlist, FLIST_FREE_DATA);
free (flowlist);
slist_destroy(functionlist,SLIST_LEAVE_DATA);
*/
//Remove flowlist
#ifdef WITH_PRIORITIES
......@@ -280,6 +260,10 @@ mapid_shutdown (int data)
flist_destroy (clientlist, FLIST_FREE_DATA);
free (clientlist);
free(gflist->fflist);
free(gflist);
free(mapidsocket);
/* close error-lookup file */
close_error ();
running_shutdown = 2;
......@@ -733,8 +717,8 @@ cmd_get_libpath (int pid, int sock)
//Copy path to buffer
strncpy ((char *)buf.data, newpath, sizeof (char) * 2048);
pc_close ();
}
pc_close ();
}
else
buf.cmd = GET_LIBPATH_NACK;
......@@ -1650,7 +1634,7 @@ cmd_read_results (int fd, int fid, int pid, int sock)
return;
}
mapidrv_read_results = get_drv_funct (drv->handle, "mapidrv_read_results");
err = mapidrv_read_results (drv->devid, fd, fid,pid, &result);
err = mapidrv_read_results (drv->devid, fd, fid, &result);
if (err != 0)
{
report_error (err, pid, sock);
......@@ -1743,7 +1727,7 @@ cmd_apply_function (struct mapiipcbuf *qbuf, int pid, int sock)
mapidrv_apply_function =
get_drv_funct (drv->handle, "mapidrv_apply_function");
functionid = mapidrv_apply_function (drv->devid, qbuf->fd, pid, qbuf->function, qbuf->data);
functionid = mapidrv_apply_function (drv->devid, qbuf->fd, qbuf->function, qbuf->data);
if (functionid == -1)
{
......@@ -1874,9 +1858,6 @@ mapidcom ()
flist_init(gflist->fflist);
pthread_spin_init(&gflist->lock,PTHREAD_PROCESS_SHARED);
functionlist = malloc(sizeof(slist_t));
slist_init(functionlist);
mapidsocket=strdup(MAPIDSOCKGLOBAL);
if (pc_load (mapid_conf))
......
......@@ -54,10 +54,10 @@ mapidrv_get_errno(int devid,int fd)
}
int
mapidrv_apply_function (int devid,int fd, int pid, char* function, mapiFunctArg *fargs)
mapidrv_apply_function (int devid,int fd, char* function, mapiFunctArg *fargs)
{
dag_instance_t *i=flist_get(devlist,devid);
return mapid_apply_function(&i->mapidlib,fd, pid, function, fargs);
return mapid_apply_function(&i->mapidlib,fd, function, fargs);
}
int mapidrv_add_device(mapi_offline_device_status_t *olstatus,char *devname, int file,int devid, global_function_list_t *gflist)
......@@ -269,10 +269,10 @@ mapidrv_proc_loop (int devid)
}
int
mapidrv_read_results (int devid,int fd, int fid,int pid, mapid_result_t** result)
mapidrv_read_results (int devid,int fd, int fid, mapid_result_t** result)
{
dag_instance_t *i=flist_get(devlist,devid);
return mapid_read_results(&i->mapidlib,fd,fid,pid,result);
return mapid_read_results(&i->mapidlib,fd,fid,result);
}
mapid_funct_info_t* mapidrv_get_flow_functions(int devid,int fd)
......
......@@ -42,7 +42,6 @@ typedef struct mapidflib_function_instance {
typedef struct mapidflib_function {
int fd; //Flow descriptor
int fid; //Function id
int pid; //owner-pid
int ref; //1 if reference to instance in other flow
mapidflib_function_instance_t *instance;
} mapidflib_function_t;
......
......@@ -78,7 +78,7 @@ mapid_init(mapidlib_instance_t *i)
};
//Function that can be used by MAPI functions for adding new functions to the flow
static int mapid_add_funct(mapidlib_instance_t *i, int fd,int pid, char *funct, ...)
static int mapid_add_funct(mapidlib_instance_t *i, int fd, char *funct, ...)
{
// struct mapidlibflow * fl=flist_get(i->flowlist,fd);
#ifdef WITH_PRIORITIES
......@@ -127,10 +127,82 @@ static int mapid_add_funct(mapidlib_instance_t *i, int fd,int pid, char *funct,
}
}
return mapid_apply_function(i,fd,pid,funct,args);
return mapid_apply_function(i,fd,funct,args);
}
//Frees resources allocated by mapidlib, should be called by the drivers somehow
static void fix_funct_ref(global_function_list_t *gflist,mapidflib_function_t *ifunct) {
flist_node_t *flow;
flist_node_t *fnode;
flist_t *functions;
mapidflib_function_t *funct;
//Loop through all flows
for(flow=flist_head(gflist->fflist);flow!=NULL;flow=flist_next(flow)) {
functions=(flist_t*)flist_data(flow);
if(functions==NULL)
continue;
for(fnode=flist_head(functions); fnode!=NULL; fnode=flist_next(fnode)) {
funct=(mapidflib_function_t*)flist_data(fnode);
if(funct->instance==ifunct->instance) {
pthread_spin_lock(&gflist->lock);
funct->ref=0;
ifunct->ref=1;
funct->instance->refcount--;
pthread_spin_unlock(&gflist->lock);
DEBUG_CMD(printf("Fixed reference for function %d [%s:%d]\n",funct->fid,__FILE__,__LINE__));
}
}
}
}
//Deletes a flow and frees all resources allocated by the flow
static void delete_flow(mapidlib_instance_t *i,struct mapidlibflow *flow) {
struct mapidlibflow *f;
flist_t *functions;
flist_node_t *funct_node;
mapidflib_function_t *funct;
pthread_spinlock_t *lock;
DEBUG_CMD(printf("Deleting flow %d [%s:%d]\n",flow->fd,__FILE__,__LINE__));
//global optimization
functions=flist_get(flow->hwinfo->gflist->fflist,flow->fd);
if(functions!=NULL)
for(funct_node=flist_head(functions);funct_node!=NULL;funct_node=flist_next(funct_node)) {
funct=(mapidflib_function_t*)flist_data(funct_node);
if(funct->ref==0 && funct->instance->refcount>0 )
//Check to see if other functions references this function
fix_funct_ref(flow->hwinfo->gflist,funct);
}
lock=&flow->hwinfo->gflist->lock;
pthread_spin_lock(lock);
#ifdef WITH_PRIORITIES
f=flist_priorities_remove(i->flowlist,flow->fd,FLIST_LEAVE_DATA);
#else
f=flist_remove(i->flowlist,flow->fd,FLIST_LEAVE_DATA);
#endif
free_functionlist(f);
free_sharedmem(f);
free(f);
pthread_spin_unlock(lock);
}
//Frees resources allocated by mapidlib, should be called by the drivers when devices are deleted
void mapid_destroy(mapidlib_instance_t *i)
{
flist_node_t *n;
......@@ -147,14 +219,10 @@ void mapid_destroy(mapidlib_instance_t *i)
n=flist_head(i->flowlist);
#endif
while (n) {
while (n!=NULL) {
f=flist_data(n);
if (f->delete!=2) {
free_functionlist(f);
free_sharedmem(f);
f->delete=2;
}
n=flist_next(n);
delete_flow(i,f);
}
// flist_destroy(i->flowlist,FLIST_FREE_DATA);
......@@ -340,25 +408,24 @@ mapid_add_flow(mapidlib_instance_t *i,
static void
free_functionlist (struct mapidlibflow *fl)
{
mapidflib_function_instance_t *fn;
mapidflib_function_t *fn;
mapid_funct_info_t *fi, *fi2;
flist_node_t *cur;
//Remove from ff_list
flist_remove(fl->hwinfo->gflist->fflist,fl->fd,FLIST_LEAVE_DATA);
return;
cur=flist_head(fl->functionlist);
while(cur) {
fn=flist_data(cur);
if(fn->def->cleanup!=NULL && fn->status==MAPIFUNC_INIT)
fn->def->cleanup(fn);
if(fn->instance->def->cleanup!=NULL && fn->instance->status==MAPIFUNC_INIT)
fn->instance->def->cleanup(fn);
free(fn->def);
free(fn->instance->def);
// if(fn->internal_data!=NULL)
// free(fn->internal_data);
free(fn->instance);
free(fn);
cur=cur->next;
}
......@@ -398,33 +465,6 @@ static void free_sharedmem(struct mapidlibflow *f)
static void fix_funct_ref(global_function_list_t *gflist,mapidflib_function_t *ifunct) {
flist_node_t *flow;
flist_node_t *fnode;
flist_t *functions;
mapidflib_function_t *funct;
//Loop through all flows
for(flow=flist_head(gflist->fflist);flow!=NULL;flow=flist_next(flow)) {
functions=(flist_t*)flist_data(flow);
if(functions==NULL)
continue;
for(fnode=flist_head(functions); fnode!=NULL; fnode=flist_next(fnode)) {
funct=(mapidflib_function_t*)flist_data(fnode);
if(funct->instance==ifunct->instance) {
pthread_spin_lock(&gflist->lock);
funct->ref=0;
ifunct->ref=1;
funct->instance->refcount--;
pthread_spin_unlock(&gflist->lock);
DEBUG_CMD(printf("Fixed reference for function %d [%s:%d]\n",funct->fid,__FILE__,__LINE__));
}
}
}
}
int
mapid_close_flow(mapidlib_instance_t *i,int fd)
{
......@@ -440,14 +480,11 @@ mapid_close_flow(mapidlib_instance_t *i,int fd)
#endif
// f=flist_get(i->flowlist,fd);
if(f->status==FLOW_FINISHED) {
//Cleanup functions
free_functionlist(f);
free_sharedmem(f);
if(f->status==FLOW_FINISHED)
f->delete=2;
} else if (f->delete==0) {
else if (f->delete==0)
f->delete=1;
}
f->status=FLOW_CLOSED;
......@@ -478,7 +515,6 @@ int
mapid_read_results(mapidlib_instance_t *i,
int fd,
int fid,
MAPI_UNUSED int pid,
mapid_result_t **result)
//Get pointer to shared memory where results are stored
//fd: flow descriptor
......@@ -598,7 +634,6 @@ static mapidflib_function_instance_t *find_identical_function(mapidlib_instance_
int
mapid_apply_function(mapidlib_instance_t *i,
int fd,
int pid,
char* function,
mapiFunctArg *fargs)
//Apply function to a flow
......@@ -639,7 +674,6 @@ mapid_apply_function(mapidlib_instance_t *i,
funct=malloc(sizeof(mapidflib_function_t));
funct->fd=fd;
funct->fid=i->fcount;
funct->pid = pid;
if(f2->optimize==MAPIOPT_AUTO) {
//Check to see if there is an existing instance of this function that can be used
......@@ -851,6 +885,7 @@ mapid_get_lib_name(int libnumber)
unsigned char modified_packet_buf[NIC_PKTCAP_LEN];
#endif
void mapid_process_pkt(mapidlib_instance_t *i,
const unsigned char* dev_pkt,
const unsigned char* link_pkt,
......@@ -863,9 +898,6 @@ void mapid_process_pkt(mapidlib_instance_t *i,
struct mapidlibflow *flow;
mapidflib_function_t *funct;
char ret;
flist_t *functions;
flist_node_t *funct_node;
#ifdef WITH_PRIORITIES
......@@ -927,42 +959,9 @@ void mapid_process_pkt(mapidlib_instance_t *i,
}
n2 = flist_next(n2);
}
} else if(flow->delete==1) {
struct mapidlibflow *f;
// n = flist_next(n);
DEBUG_CMD(printf("Deleting flow %d [%s:%d]\n",flow->fd,__FILE__,__LINE__));
//Fix global optimization
functions=flist_get(flow->hwinfo->gflist->fflist,flow->fd);
for(funct_node=flist_head(functions);funct_node!=NULL;funct_node=flist_next(funct_node)) {
funct=(mapidflib_function_t*)flist_data(funct_node);
if(funct->ref==0 && funct->instance->refcount>0 )
//Check to see if other functions references this function
fix_funct_ref(flow->hwinfo->gflist,funct);
}
pthread_spin_lock(&flow->hwinfo->gflist->lock);
#ifdef WITH_PRIORITIES
f=flist_priorities_get(i->flowlist,flow->fd);
#else
f=flist_get(i->flowlist,flow->fd);
#endif
} else if(flow->delete==1)
delete_flow(i,flow);
// f=flist_get(i->flowlist,flow->fd);
//TODO: Flow is still stored in flowlist for historical reference but
//should be removed from the flowlist when number of closed flows reach
//a configurable limit.
free_functionlist(f);
free_sharedmem(f);
f->delete=2;
pthread_spin_unlock(&flow->hwinfo->gflist->lock);
}
n = flist_next(n);
}
#ifdef WITH_PRIORITIES
......
......@@ -21,7 +21,7 @@ typedef struct mapidlib_instance {
unsigned fcount; //Number of functions
}mapidlib_instance_t;
typedef int (*mapid_add_function)(mapidlib_instance_t *i, int fd, int pid, char *funct, ...);
typedef int (*mapid_add_function)(mapidlib_instance_t *i, int fd, char *funct, ...);
//Structure used by the to_buffer function
struct mapid_to_buffer {
......@@ -72,11 +72,9 @@ int mapid_close_flow(mapidlib_instance_t *i,int fd);
int mapid_read_results(mapidlib_instance_t *i,
int fd,
int fid,
int pid,
mapid_result_t **result);
int mapid_apply_function(mapidlib_instance_t *i,
int fd,
int pid,
char* function,
mapiFunctArg *fargs);
void mapid_process_pkt(mapidlib_instance_t *i,
......
......@@ -18,18 +18,18 @@ int mapidrv_close_flow(int devid,int fd);
int mapidrv_get_errno(int devid,int fd);
/* These functions are similar to the ones in mapi.h */
int mapidrv_apply_function(int devid,int fd, int pid, char* function, mapiFunctArg *fargs);
int mapidrv_read_results(int devid,int fd,int fid,int pid,mapid_result_t** result);
int mapidrv_apply_function(int devid,int fd, char* function, mapiFunctArg *fargs);
int mapidrv_read_results(int devid,int fd,int fid,mapid_result_t** result);
int mapidrv_connect(int devid,int fd);
mapid_funct_info_t* mapidrv_get_flow_functions(int devid,int fd);
mapid_funct_info_t* mapidrv_get_flow_functions(int devid,int fd); //Deprecated and should be removed
int mapidrv_get_flow_info(int devid,int fd,mapi_flow_info_t *info);
int mapidrv_load_library(int devid,char* lib);
int mapidrv_add_device(mapi_offline_device_status_t *olstatus,char *devname,int file, int devid, global_function_list_t *gflist);
int mapidrv_delete_device(int devid);
int mapidrv_start_offline_device( int devid);
mapi_function_def_mini_t* mapidrv_get_function_info(int libnumber,int functionnumber);
unsigned char* mapidrv_get_lib_name(int libnumber);
mapi_function_def_mini_t* mapidrv_get_function_info(int libnumber,int functionnumber); //Deprecated and should be removed
unsigned char* mapidrv_get_lib_name(int libnumber); //deprecated and should be removed
#endif
......
......@@ -55,10 +55,10 @@ mapidrv_get_errno(int devid,int fd)
}
int
mapidrv_apply_function (int devid,int fd, int pid, char* function, mapiFunctArg *fargs)
mapidrv_apply_function (int devid,int fd, char* function, mapiFunctArg *fargs)
{
nic_instance_t *i=flist_get(devlist,devid);
return mapid_apply_function(&i->mapidlib,fd, pid, function, fargs);
return mapid_apply_function(&i->mapidlib,fd, function, fargs);
}
int mapidrv_add_device(mapi_offline_device_status_t* olstatus,char *devname, int file,int devid, global_function_list_t *gflist)
......@@ -88,10 +88,12 @@ int mapidrv_delete_device(int devid)
if (i!=NULL) {
int err=0;
if (i->th_proc && pthread_equal(i->th_proc, pthread_self())==0) {
DEBUG_CMD(printf("Calling thread != th_proc (%lu != %lu), canceling [%s:%d]\n",i->th_proc,pthread_self(),__FILE__,__LINE__));
// if (i->th_proc && pthread_equal(i->th_proc, pthread_self())==0) {
// DEBUG_CMD(printf("Calling thread != th_proc (%lu != %lu), canceling [%s:%d]\n",i->th_proc,pthread_self(),__FILE__,__LINE__));
fflush(stdout);
if(i->th_proc) {
if ((err=pthread_cancel(i->th_proc))!=0) {
if (!(i->hwinfo.offline>2 && err==ESRCH)) {
WARNING_CMD(printf("Could not cancel thread for devid %d (%s) [%s:%d]\n",devid,strerror(err),__FILE__,__LINE__));
......@@ -105,6 +107,10 @@ int mapidrv_delete_device(int devid)
fflush(stdout);
}
}
if ((err=pthread_attr_destroy(&i->th_attr))!=0)
WARNING_CMD(printf("Could not destroy threads attribute object for devid %d (%s) [%s:%d]\n",devid,strerror(err),__FILE__,__LINE__));
}
if (i->hwinfo.offline==0) {
......@@ -118,7 +124,7 @@ int mapidrv_delete_device(int devid)
DEBUG_CMD(printf("Closed file [%s:%d]\n",__FILE__,__LINE__));
}
}
mapid_destroy(&i->mapidlib);
free(i->name);
if(i->offline_status!=NULL)
......@@ -126,7 +132,6 @@ int mapidrv_delete_device(int devid)
free(i);
}
return 0;
}
......@@ -250,10 +255,10 @@ mapidrv_proc_loop (int devid)
}
int
mapidrv_read_results (int devid,int fd, int fid, int pid, mapid_result_t** result)
mapidrv_read_results (int devid,int fd, int fid, mapid_result_t** result)
{
nic_instance_t *i=flist_get(devlist,devid);
return mapid_read_results(&i->mapidlib,fd,fid,pid,result);
return mapid_read_results(&i->mapidlib,fd,fid,result);
}
mapid_funct_info_t* mapidrv_get_flow_functions(int devid,int fd)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment