summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvenaas <venaas>2007-06-20 14:59:20 +0000
committervenaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf>2007-06-20 14:59:20 +0000
commita30235ad2c9992fba307dedfdb5cdc5e3feaa226 (patch)
tree643ce6b662f9516a0e781b20c1cf5def4d1a5282
parent9114cdf0d4a0fdd385f7798d0a6686b0551d3a6a (diff)
using linked lists instead of arrays
git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@147 e88ac4ed-0b26-0410-9574-a7f39faa03bf
-rw-r--r--Makefile2
-rw-r--r--Makefile.am4
-rw-r--r--list.c53
-rw-r--r--list.h23
-rw-r--r--radsecproxy.c209
5 files changed, 196 insertions, 95 deletions
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 <stdlib.h>
+#include <string.h>
+#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 <openssl/md5.h>
#include <openssl/hmac.h>
#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) {