diff --git a/server/include/cfg.h b/server/include/cfg.h index 8201489ff..8f097c749 100644 --- a/server/include/cfg.h +++ b/server/include/cfg.h @@ -51,7 +51,7 @@ struct settings { * @retval <0 Error. Something went wrong. */ int config_parse(const char *filename, config_t *cfg, struct settings *set, - struct node **nodes, struct path **paths); + struct list *nodes, struct list *paths); /** Parse the global section of a configuration file. * @@ -71,9 +71,9 @@ int config_parse_global(config_setting_t *cfg, struct settings *set); * @retval <0 Error. Something went wrong. */ int config_parse_path(config_setting_t *cfg, - struct path **paths, struct node **nodes); + struct list *paths, struct list *nodes); -int config_parse_nodelist(config_setting_t *cfg, struct list *nodes, struct node **all); +int config_parse_nodelist(config_setting_t *cfg, struct list *nodes, struct list *all); int config_parse_hooks(config_setting_t *cfg, struct list *hooks); @@ -85,7 +85,7 @@ int config_parse_hooks(config_setting_t *cfg, struct list *hooks); * @retval 0 Success. Everything went well. * @retval <0 Error. Something went wrong. */ -int config_parse_node(config_setting_t *cfg, struct node **nodes); +int config_parse_node(config_setting_t *cfg, struct list *nodes); /** Parse node connection details for OPAL type * diff --git a/server/include/if.h b/server/include/if.h index 1abe6e405..551c8f7ad 100644 --- a/server/include/if.h +++ b/server/include/if.h @@ -14,6 +14,8 @@ #include #include +#include "list.h" + #define IF_NAME_MAX IFNAMSIZ /**< Maximum length of an interface name */ #define IF_IRQ_MAX 3 /**< Maxmimal number of IRQs of an interface */ @@ -35,9 +37,7 @@ struct interface { char irqs[IF_IRQ_MAX]; /** Linked list of associated sockets */ - struct socket *sockets; - /** Linked list pointer */ - struct interface *next; + struct list sockets; }; /** Add a new interface to the global list and lookup name, irqs... @@ -106,7 +106,7 @@ int if_getirqs(struct interface *i); */ int if_setaffinity(struct interface *i, int affinity); -/** Search the list of interfaces for a given index. +/** Search the global list of interfaces for a given index. * * @param index The interface index to search for * @param interfaces A linked list of all interfaces diff --git a/server/include/list.h b/server/include/list.h index 269404094..7ddca565b 100644 --- a/server/include/list.h +++ b/server/include/list.h @@ -53,8 +53,9 @@ struct list_elm { struct node *node; struct path *path; struct interface *interface; + struct socket *socket; hook_cb_t hook; - }; + } /* anonymous */; struct list_elm *prev, *next; }; diff --git a/server/include/node.h b/server/include/node.h index d3c186504..f0e42896f 100644 --- a/server/include/node.h +++ b/server/include/node.h @@ -20,6 +20,7 @@ #include "msg.h" #include "tc.h" +#include "list.h" /** Static node initialization */ #define NODE_INIT(n) { \ @@ -81,9 +82,6 @@ struct node /** A pointer to the libconfig object which instantiated this node */ config_setting_t *cfg; - - /** Linked list pointer */ - struct node *next; }; /** Connect and bind the UDP socket of this node. @@ -129,7 +127,7 @@ struct node_vtable const * node_lookup_vtable(const char *str); * @param nodes A linked list of all nodes * @return A pointer to the node or NULL if not found */ -struct node* node_lookup_name(const char *str, struct node *nodes); +struct node * node_lookup_name(const char *str, struct list *nodes); /** Reverse local and remote socket address. * This is usefull for the helper programs: send, receive, test diff --git a/server/include/path.h b/server/include/path.h index 78bc4432f..e49b14e09 100644 --- a/server/include/path.h +++ b/server/include/path.h @@ -64,9 +64,6 @@ struct path pthread_t sent_tid; /** A pointer to the libconfig object which instantiated this path */ config_setting_t *cfg; - - /** Linked list pointer */ - struct path *next; }; /** Start a path. diff --git a/server/include/utils.h b/server/include/utils.h index 90c233e34..dc4d2e8f3 100644 --- a/server/include/utils.h +++ b/server/include/utils.h @@ -126,12 +126,6 @@ struct timespec timespec_rate(double rate); /** A system(2) emulator with popen/pclose(2) and proper output handling */ int system2(const char* cmd, ...); -/** Append an element to a single linked list */ -#define list_add(list, elm) do { \ - elm->next = list; \ - list = elm; \ - } while (0) - /** Check assertion and exit if failed. */ #define assert(exp) do { \ if (EXPECT(!exp, 0)) { \ @@ -179,3 +173,4 @@ int system2(const char* cmd, ...); } while (0) #endif /* _UTILS_H_ */ + diff --git a/server/src/cfg.c b/server/src/cfg.c index 29bf57b1a..326b22d4e 100644 --- a/server/src/cfg.c +++ b/server/src/cfg.c @@ -25,7 +25,7 @@ #endif int config_parse(const char *filename, config_t *cfg, struct settings *set, - struct node **nodes, struct path **paths) + struct list *nodes, struct list *paths) { config_set_auto_convert(cfg, 1); @@ -91,7 +91,7 @@ int config_parse_global(config_setting_t *cfg, struct settings *set) } int config_parse_path(config_setting_t *cfg, - struct path **paths, struct node **nodes) + struct list *paths, struct list *nodes) { const char *in; int enabled = 1; @@ -105,7 +105,7 @@ int config_parse_path(config_setting_t *cfg, cerror(cfg, "Invalid input node for path"); in = config_setting_get_string(cfg_in); - p->in = node_lookup_name(in, *nodes); + p->in = node_lookup_name(in, nodes); if (!p->in) cerror(cfg_in, "Invalid input node '%s'", in); @@ -150,10 +150,10 @@ int config_parse_path(config_setting_t *cfg, r->in->refcnt++; r->out->refcnt++; - list_add(*paths, r); + list_push(paths, r); } - list_add(*paths, p); + list_push(paths, p); } else { char buf[33]; @@ -166,14 +166,14 @@ int config_parse_path(config_setting_t *cfg, return 0; } -int config_parse_nodelist(config_setting_t *cfg, struct list *nodes, struct node **all) { +int config_parse_nodelist(config_setting_t *cfg, struct list *nodes, struct list *all) { const char *str; struct node *node; switch (config_setting_type(cfg)) { case CONFIG_TYPE_STRING: str = config_setting_get_string(cfg); - node = node_lookup_name(str, *all); + node = node_lookup_name(str, all); if (!node) cerror(cfg, "Invalid outgoing node '%s'", str); @@ -183,7 +183,7 @@ int config_parse_nodelist(config_setting_t *cfg, struct list *nodes, struct node case CONFIG_TYPE_ARRAY: for (int i=0; ivt->parse(cfg, n); if (!ret) - list_add(*nodes, n); + list_push(nodes, n); return ret; } diff --git a/server/src/if.c b/server/src/if.c index a8c99207d..6a6750e23 100644 --- a/server/src/if.c +++ b/server/src/if.c @@ -22,8 +22,8 @@ #include "socket.h" #include "utils.h" -/** Linked list of interfaces */ -struct interface *interfaces; +/** Linked list of interfaces. */ +struct list interfaces; struct interface * if_create(int index) { struct interface *i = alloc(sizeof(struct interface)); @@ -33,7 +33,7 @@ struct interface * if_create(int index) { debug(3, "Created interface '%s'", i->name, i->index, i->refcnt); - list_add(interfaces, i); + list_push(&interfaces, i); return i; } @@ -49,7 +49,8 @@ int if_start(struct interface *i, int affinity) { INDENT int mark = 0; - for (struct socket *s = i->sockets; s; s = s->next) { + FOREACH(&i->sockets, it) { + struct socket *s = it->socket; if (s->netem) { s->mark = 1 + mark++; @@ -171,10 +172,9 @@ int if_setaffinity(struct interface *i, int affinity) struct interface * if_lookup_index(int index) { - for (struct interface *i = interfaces; i; i = i->next) { - if (i->index == index) { - return i; - } + FOREACH(&interfaces, it) { + if (it->interface->index == index) + return it->interface; } return NULL; diff --git a/server/src/node.c b/server/src/node.c index c14e5e878..77868a031 100644 --- a/server/src/node.c +++ b/server/src/node.c @@ -36,14 +36,14 @@ static const struct node_vtable vtables[] = { VTABLE(TCPD, "tcpd", socket) }; -/** Linked list of nodes */ -struct node *nodes; +/** Linked list of nodes. */ +struct list nodes; -struct node * node_lookup_name(const char *str, struct node *nodes) +struct node * node_lookup_name(const char *str, struct list *nodes) { - for (struct node *n = nodes; n; n = n->next) { - if (!strcmp(str, n->name)) - return n; + FOREACH(nodes, it) { + if (!strcmp(str, it->node->name)) + return it->node; } return NULL; diff --git a/server/src/path.c b/server/src/path.c index a697ae2a0..7b121a94c 100644 --- a/server/src/path.c +++ b/server/src/path.c @@ -18,8 +18,8 @@ #define sigev_notify_thread_id _sigev_un._tid -/** Linked list of paths */ -struct path *paths; +/** Linked list of paths. */ +struct list paths; /** Send messages asynchronously */ static void * path_send(void *arg) diff --git a/server/src/receive.c b/server/src/receive.c index 18f131c0e..bce4cb900 100644 --- a/server/src/receive.c +++ b/server/src/receive.c @@ -24,7 +24,7 @@ static struct settings set; static struct msg msg = MSG_INIT(0); -extern struct node *nodes; +extern struct list nodes; static struct node *node; void quit(int sig, siginfo_t *si, void *ptr) @@ -76,7 +76,7 @@ int main(int argc, char *argv[]) config_init(&config); config_parse(argv[optind], &config, &set, &nodes, NULL); - node = node_lookup_name(argv[optind+1], nodes); + node = node_lookup_name(argv[optind+1], &nodes); if (!node) error("There's no node with the name '%s'", argv[optind+1]); diff --git a/server/src/send.c b/server/src/send.c index 2dd7bae2a..a9897bb62 100644 --- a/server/src/send.c +++ b/server/src/send.c @@ -27,7 +27,7 @@ static struct settings set; static struct msg msg = MSG_INIT(0); static struct node *node; -extern struct node *nodes; +extern struct list nodes; void quit(int sig, siginfo_t *si, void *ptr) { @@ -79,7 +79,7 @@ int main(int argc, char *argv[]) config_init(&config); config_parse(argv[optind], &config, &set, &nodes, NULL); - node = node_lookup_name(argv[optind+1], nodes); + node = node_lookup_name(argv[optind+1], &nodes); if (!node) error("There's no node with the name '%s'", argv[optind+1]); diff --git a/server/src/server.c b/server/src/server.c index 68d5116b6..f0f41f79f 100644 --- a/server/src/server.c +++ b/server/src/server.c @@ -27,11 +27,11 @@ #endif /** Linked list of nodes */ -extern struct node *nodes; +extern struct list nodes; /** Linked list of paths */ -extern struct path *paths; +extern struct list paths; /** Linked list of interfaces */ -extern struct interface *interfaces; +extern struct list interfaces; /** The global configuration */ struct settings settings; @@ -40,27 +40,25 @@ config_t config; static void quit() { _indent = 0; info("Stopping paths:"); - for (struct path *p = paths; p; p = p->next) { INDENT - path_stop(p); - path_destroy(p); - } + FOREACH(&paths, it) + path_stop(it->path); info("Stopping nodes:"); - for (struct node *n = nodes; n; n = n->next) { INDENT - node_stop(n); - } + FOREACH(&nodes, it) + node_stop(it->node); info("Stopping interfaces:"); - for (struct interface *i = interfaces; i; i = i->next) { INDENT - if_stop(i); - } + FOREACH(&interfaces, it) + if_stop(it->interface); - /** @todo Free nodes */ - #ifdef ENABLE_OPAL_ASYNC opal_deinit(); #endif + /* Freeing dynamically allocated memory */ + list_destroy(&paths); + list_destroy(&nodes); + list_destroy(&interfaces); config_destroy(&config); _exit(EXIT_SUCCESS); @@ -164,35 +162,29 @@ int main(int argc, char *argv[]) /* Connect all nodes and start one thread per path */ info("Starting nodes:"); - for (struct node *n = nodes; n; n = n->next) { INDENT - node_start(n); - } + FOREACH(&nodes, it) + node_start(it->node); info("Starting interfaces:"); - for (struct interface *i = interfaces; i; i = i->next) { INDENT - if_start(i, settings.affinity); - } + FOREACH(&interfaces, it) + if_start(it->interface, settings.affinity); - info("Starting pathes:"); - for (struct path *p = paths; p; p = p->next) { INDENT - path_start(p); - } + info("Starting paths:"); + FOREACH(&paths, it) + path_start(it->path); /* Run! */ if (settings.stats > 0) { - struct path *p = paths; - info("Runtime Statistics:"); info("%-32s : %-8s %-8s %-8s %-8s %-8s", "Source " MAG("=>") " Destination", "#Sent", "#Recv", "#Drop", "#Skip", "#Inval"); info("---------------------------------------------------------------------------"); - while (1) { + do { FOREACH(&paths, it) { usleep(settings.stats * 1e6); - path_stats(p); + path_print_stats(it->path); + } } while (1); - p = (p->next) ? p->next : paths; - } } else pause(); diff --git a/server/src/socket.c b/server/src/socket.c index 0d9271a29..9b6f8fd68 100644 --- a/server/src/socket.c +++ b/server/src/socket.c @@ -86,7 +86,7 @@ int socket_open(struct node *n) if (!i) i = if_create(index); - list_add(i->sockets, s); + list_push(&i->sockets, s); i->refcnt++; /* Set socket priority, QoS or TOS IP options */ diff --git a/server/src/test.c b/server/src/test.c index d7a40021f..58fb410cf 100644 --- a/server/src/test.c +++ b/server/src/test.c @@ -26,7 +26,7 @@ static struct settings set; static struct node *node; -extern struct node *nodes; +extern struct list nodes; /* Test options */ int running = 1; @@ -87,7 +87,7 @@ int main(int argc, char *argv[]) config_init(&config); config_parse(argv[1], &config, &set, &nodes, NULL); - node = node_lookup_name(argv[3], nodes); + node = node_lookup_name(argv[3], &nodes); if (!node) error("There's no node with the name '%s'", argv[3]);