diff --git a/server/include/if.h b/server/include/if.h index 551c8f7ad..cca9b5e03 100644 --- a/server/include/if.h +++ b/server/include/if.h @@ -48,6 +48,13 @@ struct interface { */ struct interface * if_create(int index); + +/** Destroy interface by freeing dynamically allocated memory. + * + * @param i A pointer to the interface structure. + */ +void if_destroy(struct interface *i); + /** Start interface. * * This setups traffic controls queue discs, network emulation and diff --git a/server/include/list.h b/server/include/list.h index 7ddca565b..4c9f5d373 100644 --- a/server/include/list.h +++ b/server/include/list.h @@ -40,10 +40,17 @@ struct interface; #define list_last(list) ((list)->head) #define list_length(list) ((list)->count) +/** Callback to destroy list elements. + * + * @param data A pointer to the data which should be freed. + */ +typedef void (*dtor_cb_t)(void *data); + struct list { struct list_elm *head, *tail; int count; + dtor_cb_t destructor; pthread_mutex_t lock; }; @@ -60,7 +67,7 @@ struct list_elm { struct list_elm *prev, *next; }; -void list_init(struct list *l); +void list_init(struct list *l, dtor_cb_t dtor); void list_destroy(struct list *l); diff --git a/server/include/node.h b/server/include/node.h index f0e42896f..60a65241e 100644 --- a/server/include/node.h +++ b/server/include/node.h @@ -135,4 +135,13 @@ struct node * node_lookup_name(const char *str, struct list *nodes); * server and therefore the direction needs to be swapped. */ int node_reverse(struct node *n); +/** Create a node by allocating dynamic memory. */ +struct node * node_create(); + +/** Destroy node by freeing dynamically allocated memory. + * + * @param i A pointer to the interface structure. + */ +void node_destroy(struct node *n); + #endif /* _NODE_H_ */ diff --git a/server/include/path.h b/server/include/path.h index e49b14e09..040dce01a 100644 --- a/server/include/path.h +++ b/server/include/path.h @@ -66,6 +66,15 @@ struct path config_setting_t *cfg; }; +/** Create a path by allocating dynamic memory. */ +struct path * path_create(); + +/** Destroy path by freeing dynamically allocated memory. + * + * @param i A pointer to the path structure. + */ +void path_destroy(struct path *p); + /** Start a path. * * Start a new pthread for receiving/sending messages over this path. diff --git a/server/src/cfg.c b/server/src/cfg.c index 326b22d4e..1e4a0474c 100644 --- a/server/src/cfg.c +++ b/server/src/cfg.c @@ -140,7 +140,7 @@ int config_parse_path(config_setting_t *cfg, warn("Using first destination '%s' as source for reverse path. " "Ignoring remaining nodes", p->out->name); - struct path *r = alloc(sizeof(struct path)); + struct path *r = path_create(); r->in = p->out; /* Swap in/out */ r->out = p->in; @@ -235,7 +235,7 @@ int config_parse_node(config_setting_t *cfg, struct list *nodes) const char *type; int ret; - struct node *n = alloc(sizeof(struct node)); + struct node *n = node_create(); /* Required settings */ n->cfg = cfg; diff --git a/server/src/if.c b/server/src/if.c index 6a6750e23..6d341d41f 100644 --- a/server/src/if.c +++ b/server/src/if.c @@ -33,11 +33,20 @@ struct interface * if_create(int index) { debug(3, "Created interface '%s'", i->name, i->index, i->refcnt); + list_init(&i->sockets, NULL); list_push(&interfaces, i); return i; } +void if_destroy(struct interface *i) +{ + /* List members are freed by their belonging nodes. */ + list_destroy(&i->sockets); + + free(i); +} + int if_start(struct interface *i, int affinity) { INDENT if (!i->refcnt) { diff --git a/server/src/list.c b/server/src/list.c index 1b1a1a935..bfc5882cc 100644 --- a/server/src/list.c +++ b/server/src/list.c @@ -10,10 +10,11 @@ #include "utils.h" #include "list.h" -void list_init(struct list *l) +void list_init(struct list *l, dtor_cb_t dtor) { pthread_mutex_init(&l->lock, NULL); + l->destructor = dtor; l->count = 0; l->head = NULL; l->tail = NULL; @@ -26,9 +27,12 @@ void list_destroy(struct list *l) struct list_elm *elm = l->head; while (elm) { struct list_elm *tmp = elm; - free(tmp); - elm = elm->next; + + if (l->destructor) + l->destructor(tmp->ptr); + + free(tmp); } pthread_mutex_unlock(&l->lock); diff --git a/server/src/node.c b/server/src/node.c index 77868a031..e6252cb9d 100644 --- a/server/src/node.c +++ b/server/src/node.c @@ -121,4 +121,23 @@ int node_reverse(struct node *n) default: { } } return n->vt->open == socket_open; + +struct node * node_create() +{ + return alloc(sizeof(struct node)); +} + +void node_destroy(struct node *n) +{ + switch (n->vt->type) { + case IEEE_802_3: + case IP: + case UDP: + case TCP: + free(n->socket->netem); + default: { } + } + + free(n->socket); + free(n); } diff --git a/server/src/path.c b/server/src/path.c index 7b121a94c..c7f226ae9 100644 --- a/server/src/path.c +++ b/server/src/path.c @@ -215,10 +215,25 @@ int path_print(struct path *p, char *buf, int len) return 0; } -int path_destroy(struct path *p) +struct path * path_create() +{ + struct path *p = alloc(sizeof(struct path)); + + list_init(&p->destinations, NULL); + list_init(&p->hooks, NULL); + + hist_create(&p->histogram, -HIST_SEQ, +HIST_SEQ, 1); + + return p; +} + +void path_destroy(struct path *p) { list_destroy(&p->destinations); list_destroy(&p->hooks); + hist_destroy(&p->histogram); - return 0; + free(p->current); + free(p->previous); + free(p); } diff --git a/server/src/server.c b/server/src/server.c index f0f41f79f..0b56b5d3e 100644 --- a/server/src/server.c +++ b/server/src/server.c @@ -139,9 +139,15 @@ int main(int argc, char *argv[]) if (getuid() != 0) error("The server requires superuser privileges!"); + /* Initialize lists */ + list_init(&nodes, (dtor_cb_t) node_destroy); + list_init(&paths, (dtor_cb_t) path_destroy); + list_init(&interfaces, (dtor_cb_t) if_destroy); + /* Start initialization */ info("Initialize realtime system:"); realtime_init(); + info("Setup signals:"); signals_init(); info("Parsing configuration:");