From: venaas Date: Wed, 20 Jun 2007 14:59:20 +0000 (+0000) Subject: using linked lists instead of arrays X-Git-Tag: radsecproxy-1.4-beta1~350 X-Git-Url: http://www.project-moonshot.org/gitweb/?a=commitdiff_plain;ds=sidebyside;h=a30235ad2c9992fba307dedfdb5cdc5e3feaa226;p=radsecproxy.git using linked lists instead of arrays git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@147 e88ac4ed-0b26-0410-9574-a7f39faa03bf --- diff --git a/Makefile b/Makefile index 8fbec05..3ebbe09 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CFLAGS = -g -Wall -pedantic -pthread LDFLAGS = -lssl -OBJ = util.o debug.o radsecproxy.o +OBJ = util.o debug.o list.o radsecproxy.o all: radsecproxy diff --git a/Makefile.am b/Makefile.am index a040ff5..032226e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,8 +3,10 @@ sbin_PROGRAMS = radsecproxy radsecproxy_SOURCES = radsecproxy.c \ util.c \ debug.c \ + list.c \ radsecproxy.h \ - debug.h + debug.h \ + list.h radsecproxy_CFLAGS = -g -Wall -pedantic -pthread @SSL_CFLAGS@ radsecproxy_LDFLAGS = @SSL_LDFLAGS@ diff --git a/list.c b/list.c new file mode 100644 index 0000000..578c61a --- /dev/null +++ b/list.c @@ -0,0 +1,53 @@ +#include +#include +#include "list.h" + +/* allocates and initialises list structure; returns NULL if malloc fails */ +struct list *list_create() { + struct list *list = malloc(sizeof(struct list)); + if (list) + memset(list, 0, sizeof(struct list)); + return list; +} + +/* frees all memory associated with the list */ +void list_destroy(struct list *list) { + struct list_node *node, *next; + + for (node = list->first; node; node = next) { + free(node->data); + next = node->next; + free(node); + } + free(list); +} + +/* appends entry to list; returns 1 if ok, 0 if malloc fails */ +int list_add(struct list *list, void *data) { + struct list_node *node; + + node = malloc(sizeof(struct list_node)); + if (!node) + return 0; + + node->next = NULL; + node->data = data; + + if (list->first) + list->last->next = node; + else + list->first = node; + list->last = node; + + return 1; +} + +/* returns first node */ +struct list_node *list_first(struct list *list) { + return list->first; +} + +/* returns the next node after the argument */ +struct list_node *list_next(struct list_node *node) { + return node->next; +} diff --git a/list.h b/list.h new file mode 100644 index 0000000..876d345 --- /dev/null +++ b/list.h @@ -0,0 +1,23 @@ +struct list_node { + struct list_node *next; + void *data; +}; + +struct list { + struct list_node *first, *last; +}; + +/* allocates and initialises list structure; returns NULL if malloc fails */ +struct list *list_create(); + +/* frees all memory associated with the list */ +void list_destroy(struct list *list); + +/* appends entry to list; returns 1 if ok, 0 if malloc fails */ +int list_add(struct list *list, void *data); + +/* returns first node */ +struct list_node *list_first(struct list *list); + +/* returns the next node after the argument */ +struct list_node *list_next(struct list_node *node); diff --git a/radsecproxy.c b/radsecproxy.c index 63c8c8b..d955654 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -44,22 +44,16 @@ #include #include #include "debug.h" +#include "list.h" #include "radsecproxy.h" static struct options options; -static struct clsrvconf *clconfs = NULL; -static struct clsrvconf *srvconfs = NULL; -static struct realm *realms = NULL; -static struct tls *tls = NULL; +struct list *clconfs, *srvconfs, *realms, *tls; static int client_udp_count = 0; static int client_tls_count = 0; -static int clconf_count = 0; static int server_udp_count = 0; static int server_tls_count = 0; -static int srvconf_count = 0; -static int realm_count = 0; -static int tls_count = 0; static struct clsrvconf *tcp_server_listen; static struct clsrvconf *udp_server_listen; @@ -201,13 +195,13 @@ int bindtoaddr(struct addrinfo *addrinfo) { } /* returns the peer with matching address, or NULL */ -/* if peer argument is not NULL, we only check that one client */ -struct clsrvconf *find_peer(char type, struct sockaddr *addr, struct clsrvconf *confs, int count) { +/* if conf argument is not NULL, we only check that one */ +struct clsrvconf *find_peer(char type, struct sockaddr *addr, struct list *confs, struct clsrvconf *conf) { struct sockaddr_in6 *sa6 = NULL; struct in_addr *a4 = NULL; - int i; struct addrinfo *res; - + struct list_node *entry; + if (addr->sa_family == AF_INET6) { sa6 = (struct sockaddr_in6 *)addr; if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) @@ -215,16 +209,27 @@ struct clsrvconf *find_peer(char type, struct sockaddr *addr, struct clsrvconf * } else a4 = &((struct sockaddr_in *)addr)->sin_addr; - for (i = 0; i < count; i++) { - if (confs->type == type) - for (res = confs->addrinfo; res; res = res->ai_next) + if (conf) { + if (conf->type == type) + for (res = conf->addrinfo; res; res = res->ai_next) if ((a4 && res->ai_family == AF_INET && !memcmp(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4)) || (sa6 && res->ai_family == AF_INET6 && !memcmp(&sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16))) - return confs; - confs++; + return conf; + return NULL; } + + for (entry = list_first(confs); entry; entry = list_next(entry)) { + conf = (struct clsrvconf *)entry->data; + if (conf->type == type) + for (res = conf->addrinfo; res; res = res->ai_next) + if ((a4 && res->ai_family == AF_INET && + !memcmp(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4)) || + (sa6 && res->ai_family == AF_INET6 && + !memcmp(&sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16))) + return conf; + } return NULL; } @@ -233,11 +238,11 @@ struct clsrvconf *find_peer(char type, struct sockaddr *addr, struct clsrvconf * /* if *peer == NULL we return who we received from, else require it to be from peer */ /* return from in sa if not NULL */ unsigned char *radudpget(int s, struct client **client, struct server **server, struct sockaddr_storage *sa) { - int cnt, len, confcount; + int cnt, len; unsigned char buf[65536], *rad; struct sockaddr_storage from; socklen_t fromlen = sizeof(from); - struct clsrvconf *confs, *p; + struct clsrvconf *p; for (;;) { cnt = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen); @@ -266,23 +271,16 @@ unsigned char *radudpget(int s, struct client **client, struct server **server, debug(DBG_DBG, "radudpget: packet was padded with %d bytes", cnt - len); if (client) - if (*client) { - confcount = 1; - confs = (*client)->conf; - } else { - confcount = clconf_count; - confs = clconfs; - } + if (*client) + p = find_peer('U', (struct sockaddr *)&from, NULL, (*client)->conf); + else + p = find_peer('U', (struct sockaddr *)&from, clconfs, NULL); else - if (*server) { - confcount = 1; - confs = (*server)->conf; - } else { - confcount = srvconf_count; - confs = srvconfs; - } + if (*server) + p = find_peer('U', (struct sockaddr *)&from, NULL, (*server)->conf); + else + p = find_peer('U', (struct sockaddr *)&from, srvconfs, NULL); - p = find_peer('U', (struct sockaddr *)&from, confs, confcount); if (!p) { debug(DBG_WARN, "radudpget: got packet from wrong or unknown UDP peer, ignoring"); continue; @@ -927,12 +925,16 @@ int msmppdecrypt(uint8_t *text, uint8_t len, uint8_t *shared, uint8_t sharedlen, } struct realm *id2realm(char *id, uint8_t len) { - int i; - for (i = 0; i < realm_count; i++) - if (!regexec(&realms[i].regex, id, 0, NULL, 0)) { - debug(DBG_DBG, "found matching realm: %s", realms[i].name); - return realms + i; + struct list_node *entry; + struct realm *realm; + + for (entry = list_first(realms); entry; entry = list_next(entry)) { + realm = (struct realm *)entry->data; + if (!regexec(&realm->regex, id, 0, NULL, 0)) { + debug(DBG_DBG, "found matching realm: %s", realm->name); + return realm; } + } return NULL; } @@ -1620,7 +1622,7 @@ int tlslistener() { } debug(DBG_WARN, "incoming TLS connection from %s", addr2string((struct sockaddr *)&from, fromlen)); - conf = find_peer('T', (struct sockaddr *)&from, clconfs, clconf_count); + conf = find_peer('T', (struct sockaddr *)&from, clconfs, NULL); if (!conf) { debug(DBG_WARN, "ignoring request, not a known TLS client"); shutdown(snew, SHUT_RDWR); @@ -1698,12 +1700,11 @@ void tlsadd(char *value, char *cacertfile, char *cacertpath, char *certfile, cha SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb); SSL_CTX_set_verify_depth(ctx, MAX_CERT_DEPTH + 1); - - tls_count++; - tls = realloc(tls, tls_count * sizeof(struct tls)); - if (!tls) + + new = malloc(sizeof(struct tls)); + if (!new || !list_add(tls, new)) debugx(1, DBG_ERR, "malloc failed"); - new = tls + tls_count - 1; + memset(new, 0, sizeof(struct tls)); new->name = stringcopy(value, 0); if (!new->name) @@ -1714,31 +1715,37 @@ void tlsadd(char *value, char *cacertfile, char *cacertpath, char *certfile, cha } void tlsfree() { - int i; - for (i = 0; i < tls_count; i++) - if (!tls[i].count) - SSL_CTX_free(tls[i].ctx); - tls_count = 0; - free(tls); + struct list_node *entry; + struct tls *t; + + for (entry = list_first(tls); entry; entry = list_next(entry)) { + t = (struct tls *)entry->data; + if (!t->count) + SSL_CTX_free(t->ctx); + } + list_destroy(tls); tls = NULL; } SSL_CTX *tlsgetctx(char *alt1, char *alt2) { - int i, c1 = -1, c2 = -1; - for (i = 0; i < tls_count; i++) { - if (!strcasecmp(tls[i].name, alt1)) { - c1 = i; + struct list_node *entry; + struct tls *t, *t1 = NULL, *t2 = NULL; + + for (entry = list_first(tls); entry; entry = list_next(entry)) { + t = (struct tls *)entry->data; + if (!strcasecmp(t->name, alt1)) { + t1 = t; break; } - if (c2 == -1 && alt2 && !strcasecmp(tls[i].name, alt2)) - c2 = i; + if (!t2 && alt2 && !strcasecmp(t->name, alt2)) + t2 = t; } - i = (c1 == -1 ? c2 : c1); - if (i == -1) + t = (t1 ? t1 : t2); + if (!t) return NULL; - tls[i].count++; - return tls[i].ctx; + t->count++; + return t->ctx; } struct replyq *newreplyq(int size) { @@ -1797,15 +1804,19 @@ void addserver(struct clsrvconf *conf) { } void addrealm(char *value, char *server, char *message) { - int i, n; + int n; struct realm *realm; char *s, *regex = NULL; - + struct list_node *entry; + struct clsrvconf *conf; + if (server) { - for (i = 0; i < srvconf_count; i++) - if (!strcasecmp(server, srvconfs[i].host)) + for (entry = list_first(srvconfs); entry; entry = list_next(entry)) { + conf = (struct clsrvconf *)entry->data; + if (!strcasecmp(server, conf->host)) break; - if (i == srvconf_count) + } + if (!entry) debugx(1, DBG_ERR, "addrealm failed, no server %s", server); } @@ -1838,11 +1849,10 @@ void addrealm(char *value, char *server, char *message) { debug(DBG_DBG, "addrealm: constructed regexp %s from %s", regex, value); } - realm_count++; - realms = realloc(realms, realm_count * sizeof(struct realm)); - if (!realms) + realm = malloc(sizeof(struct realm)); + if (!realm || !list_add(realms, realm)) debugx(1, DBG_ERR, "malloc failed"); - realm = realms + realm_count - 1; + memset(realm, 0, sizeof(struct realm)); realm->name = stringcopy(value, 0); if (!realm->name) @@ -1851,7 +1861,7 @@ void addrealm(char *value, char *server, char *message) { debugx(1, DBG_ERR, "ReplyMessage can be at most 253 bytes"); realm->message = message; if (server) - realm->srvconf = srvconfs + i; + realm->srvconf = conf; if (regcomp(&realm->regex, regex ? regex : value + 1, REG_ICASE | REG_NOSUB)) debugx(1, DBG_ERR, "addrealm: failed to compile regular expression %s", regex ? regex : value + 1); if (regex) @@ -2106,11 +2116,9 @@ void confclient_cb(FILE *f, char *block, char *opt, char *val) { "tls", CONF_STR, &tls, NULL ); - clconf_count++; - clconfs = realloc(clconfs, clconf_count * sizeof(struct clsrvconf)); - if (!clconfs) + conf = malloc(sizeof(struct clsrvconf)); + if (!conf || !list_add(clconfs, conf)) debugx(1, DBG_ERR, "malloc failed"); - conf = clconfs + clconf_count - 1; memset(conf, 0, sizeof(struct clsrvconf)); conf->host = stringcopy(val, 0); @@ -2154,11 +2162,9 @@ void confserver_cb(FILE *f, char *block, char *opt, char *val) { "StatusServer", CONF_STR, &statusserver, NULL ); - srvconf_count++; - srvconfs = realloc(srvconfs, srvconf_count * sizeof(struct clsrvconf)); - if (!srvconfs) + conf = malloc(sizeof(struct clsrvconf)); + if (!conf || !list_add(srvconfs, conf)) debugx(1, DBG_ERR, "malloc failed"); - conf = srvconfs + srvconf_count - 1; memset(conf, 0, sizeof(struct clsrvconf)); conf->port = port; @@ -2244,7 +2250,23 @@ void getmainconfig(const char *configfile) { f = openconfigfile(configfile); memset(&options, 0, sizeof(options)); - + + clconfs = list_create(); + if (!clconfs) + debugx(1, DBG_ERR, "malloc failed"); + + srvconfs = list_create(); + if (!srvconfs) + debugx(1, DBG_ERR, "malloc failed"); + + realms = list_create(); + if (!realms) + debugx(1, DBG_ERR, "malloc failed"); + + tls = list_create(); + if (!tls) + debugx(1, DBG_ERR, "malloc failed"); + getgeneralconfig(f, NULL, "ListenUDP", CONF_STR, &options.listenudp, "ListenTCP", CONF_STR, &options.listentcp, @@ -2299,7 +2321,7 @@ void getargs(int argc, char **argv, uint8_t *foreground, uint8_t *loglevel, char int main(int argc, char **argv) { pthread_t udpserverth; - int i; + struct list_node *entry; uint8_t foreground = 0, loglevel = 0; char *configfile = NULL; @@ -2321,23 +2343,23 @@ int main(int argc, char **argv) { debug_set_destination(options.logdestination); } - if (!srvconf_count) - debugx(1, DBG_ERR, "No servers configured, nothing to do, exiting"); - if (!clconf_count) + if (!list_first(clconfs)) debugx(1, DBG_ERR, "No clients configured, nothing to do, exiting"); - if (!realm_count) + if (!list_first(srvconfs)) + debugx(1, DBG_ERR, "No servers configured, nothing to do, exiting"); + if (!list_first(realms)) debugx(1, DBG_ERR, "No realms configured, nothing to do, exiting"); if (!foreground && (daemon(0, 0) < 0)) debugx(1, DBG_ERR, "daemon() failed: %s", strerror(errno)); debug(DBG_INFO, "radsecproxy revision $Rev$ starting"); - - for (i = 0; i < clconf_count; i++) - addclient(clconfs + i); - - for (i = 0; i < srvconf_count; i++) - addserver(srvconfs + i); + + for (entry = list_first(clconfs); entry; entry = list_next(entry)) + addclient((struct clsrvconf *)entry->data); + + for (entry = list_first(srvconfs); entry; entry = list_next(entry)) + addserver((struct clsrvconf *)entry->data); if (client_udp_count) { udp_server_listen = server_create('U'); @@ -2345,8 +2367,9 @@ int main(int argc, char **argv) { debugx(1, DBG_ERR, "pthread_create failed"); } - for (i = 0; i < srvconf_count; i++) - if (pthread_create(&srvconfs[i].servers->clientth, NULL, clientwr, (void *)srvconfs[i].servers)) + for (entry = list_first(srvconfs); entry; entry = list_next(entry)) + if (pthread_create(&((struct clsrvconf *)entry->data)->servers->clientth, NULL, clientwr, + (void *)((struct clsrvconf *)entry->data)->servers)) debugx(1, DBG_ERR, "pthread_create failed"); if (client_tls_count) {