From 3f30abb022a5b35a6808e013fe9024b19df3cfbe Mon Sep 17 00:00:00 2001 From: venaas Date: Tue, 19 Jun 2007 12:37:58 +0000 Subject: more restructuring of code git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@145 e88ac4ed-0b26-0410-9574-a7f39faa03bf --- radsecproxy.c | 345 ++++++++++++++++++++++++++-------------------------------- 1 file changed, 156 insertions(+), 189 deletions(-) diff --git a/radsecproxy.c b/radsecproxy.c index 10fae1d..7b7675c 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -63,7 +63,7 @@ static int tls_count = 0; static struct clsrvconf *tcp_server_listen; static struct clsrvconf *udp_server_listen; -static struct replyq udp_server_replyq; +static struct replyq *udp_server_replyq = NULL; static int udp_server_sock = -1; static pthread_mutex_t *ssl_locks; static long *ssl_lock_count; @@ -228,72 +228,6 @@ struct clsrvconf *find_peer(char type, struct sockaddr *addr, struct clsrvconf * return NULL; } -#if 0 -/* returns the client with matching address, or NULL */ -/* if client argument is not NULL, we only check that one client */ -struct client *find_client(char type, struct sockaddr *addr, struct client *client) { - struct sockaddr_in6 *sa6 = NULL; - struct in_addr *a4 = NULL; - struct client *c; - int i; - struct addrinfo *res; - - if (addr->sa_family == AF_INET6) { - sa6 = (struct sockaddr_in6 *)addr; - if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) - a4 = (struct in_addr *)&sa6->sin6_addr.s6_addr[12]; - } else - a4 = &((struct sockaddr_in *)addr)->sin_addr; - - c = (client ? client : clients); - for (i = 0; i < client_count; i++) { - if (c->peer->type == type) - for (res = c->peer->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 c; - if (client) - break; - c++; - } - return NULL; -} - -/* returns the server with matching address, or NULL */ -/* if server argument is not NULL, we only check that one server */ -struct server *find_server(char type, struct sockaddr *addr, struct server *server) { - struct sockaddr_in6 *sa6 = NULL; - struct in_addr *a4 = NULL; - struct server *s; - int i; - struct addrinfo *res; - - if (addr->sa_family == AF_INET6) { - sa6 = (struct sockaddr_in6 *)addr; - if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) - a4 = (struct in_addr *)&sa6->sin6_addr.s6_addr[12]; - } else - a4 = &((struct sockaddr_in *)addr)->sin_addr; - - s = (server ? server : servers); - for (i = 0; i < server_count; i++) { - if (s->peer->type == type) - for (res = s->peer->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 s; - if (server) - break; - s++; - } - return NULL; -} -#endif - /* exactly one of client and server must be non-NULL */ /* should probably take peer list (client(s) or server(s)) as argument instead */ /* if *peer == NULL we return who we received from, else require it to be from peer */ @@ -1529,7 +1463,7 @@ void *clientwr(void *arg) { } void *udpserverwr(void *arg) { - struct replyq *replyq = &udp_server_replyq; + struct replyq *replyq = udp_server_replyq; struct reply *reply = replyq->replies; pthread_mutex_lock(&replyq->count_mutex); @@ -1805,6 +1739,61 @@ SSL_CTX *tlsgetctx(char *alt1, char *alt2) { return tls[i].ctx; } +struct replyq *newreplyq(int size) { + struct replyq *replyq; + + replyq = malloc(sizeof(struct replyq)); + if (!replyq) + debugx(1, DBG_ERR, "malloc failed"); + replyq->replies = calloc(MAX_REQUESTS, sizeof(struct reply)); + if (!replyq->replies) + debugx(1, DBG_ERR, "malloc failed"); + replyq->count = 0; + replyq->size = size; + pthread_mutex_init(&replyq->count_mutex, NULL); + pthread_cond_init(&replyq->count_cond, NULL); + return replyq; +} + +void addclient(struct clsrvconf *conf) { + if (conf->clients) + debugx(1, DBG_ERR, "currently works with just one client per conf"); + + conf->clients = malloc(sizeof(struct client)); + if (!conf->clients) + debugx(1, DBG_ERR, "malloc failed"); + memset(conf->clients, 0, sizeof(struct client)); + conf->clients->conf = conf; + + if (conf->type == 'T') + conf->clients->replyq = newreplyq(MAX_REQUESTS); + else { + if (!udp_server_replyq) + udp_server_replyq = newreplyq(client_udp_count * MAX_REQUESTS); + conf->clients->replyq = udp_server_replyq; + } +} + +void addserver(struct clsrvconf *conf) { + if (conf->servers) + debugx(1, DBG_ERR, "currently works with just one server per conf"); + + conf->servers = malloc(sizeof(struct server)); + if (!conf->servers) + debugx(1, DBG_ERR, "malloc failed"); + memset(conf->servers, 0, sizeof(struct server)); + conf->servers->conf = conf; + + conf->servers->sock = -1; + pthread_mutex_init(&conf->servers->lock, NULL); + conf->servers->requests = calloc(MAX_REQUESTS, sizeof(struct request)); + if (!conf->servers->requests) + debugx(1, DBG_ERR, "malloc failed"); + conf->servers->newrq = 0; + pthread_mutex_init(&conf->servers->newrq_mutex, NULL); + pthread_cond_init(&conf->servers->newrq_cond, NULL); +} + void addrealm(char *value, char *server, char *message) { int i, n; struct realm *realm; @@ -2103,128 +2092,110 @@ void getgeneralconfig(FILE *f, char *block, ...) { } } -void confclsrv_cb(FILE *f, char *block, char *opt, char *val) { - char *type = NULL, *secret = NULL, *port = NULL, *tls = NULL, *statusserver = NULL; - struct clsrvconf *clsrvconf; - - debug(DBG_DBG, "confclsrv_cb called for %s", block); - - /* now create client/server here, later they should be created dynamically - where peer has pointer to clients/servers using its config */ - /* instead of current clients and servers, they would be arrays of struct peer */ - /* or rather linked lists of struct peers */ - - if (!strcasecmp(opt, "client")) { - getgeneralconfig(f, block, - "type", CONF_STR, &type, - "secret", CONF_STR, &secret, - "tls", CONF_STR, &tls, - NULL - ); - clconf_count++; - clconfs = realloc(clconfs, clconf_count * sizeof(struct clsrvconf)); - if (!clconfs) - debugx(1, DBG_ERR, "malloc failed"); - clsrvconf = clconfs + clconf_count - 1; - memset(clsrvconf, 0, sizeof(struct clsrvconf)); - clsrvconf->clients = malloc(sizeof(struct client)); - if (!clsrvconf->clients) - debugx(1, DBG_ERR, "malloc failed"); - memset(clsrvconf->clients, 0, sizeof(struct client)); - clsrvconf->clients->conf = clsrvconf; - } else { - getgeneralconfig(f, block, - "type", CONF_STR, &type, - "secret", CONF_STR, &secret, - "port", CONF_STR, &port, - "tls", CONF_STR, &tls, - "StatusServer", CONF_STR, &statusserver, - NULL - ); - srvconf_count++; - srvconfs = realloc(srvconfs, srvconf_count * sizeof(struct clsrvconf)); - if (!srvconfs) - debugx(1, DBG_ERR, "malloc failed"); - clsrvconf = srvconfs + srvconf_count - 1; - memset(clsrvconf, 0, sizeof(struct clsrvconf)); - clsrvconf->servers = malloc(sizeof(struct server)); - if (!clsrvconf->servers) - debugx(1, DBG_ERR, "malloc failed"); - memset(clsrvconf->servers, 0, sizeof(struct server)); - clsrvconf->servers->conf = clsrvconf; - clsrvconf->port = port; - if (statusserver) { - if (!strcasecmp(statusserver, "on")) - clsrvconf->statusserver = 1; - else if (strcasecmp(statusserver, "off")) - debugx(1, DBG_ERR, "error in block %s, StatusServer is %s, must be on or off", block, statusserver); - free(statusserver); - } - } +void confclient_cb(FILE *f, char *block, char *opt, char *val) { + char *type = NULL, *secret = NULL, *tls = NULL; + struct clsrvconf *conf; - clsrvconf->host = stringcopy(val, 0); + debug(DBG_DBG, "confclient_cb called for %s", block); + + getgeneralconfig(f, block, + "type", CONF_STR, &type, + "secret", CONF_STR, &secret, + "tls", CONF_STR, &tls, + NULL + ); + clconf_count++; + clconfs = realloc(clconfs, clconf_count * sizeof(struct clsrvconf)); + if (!clconfs) + debugx(1, DBG_ERR, "malloc failed"); + conf = clconfs + clconf_count - 1; + memset(conf, 0, sizeof(struct clsrvconf)); + + conf->host = stringcopy(val, 0); if (type && !strcasecmp(type, "udp")) { - clsrvconf->type = 'U'; - if (clsrvconf->clients) - client_udp_count++; - else { - server_udp_count++; - if (!port) - clsrvconf->port = stringcopy(DEFAULT_UDP_PORT, 0); - } + conf->type = 'U'; + client_udp_count++; } else if (type && !strcasecmp(type, "tls")) { - if (clsrvconf->clients) { - clsrvconf->ssl_ctx = tls ? tlsgetctx(tls, NULL) : tlsgetctx("defaultclient", "default"); - client_tls_count++; - } else { - clsrvconf->ssl_ctx = tls ? tlsgetctx(tls, NULL) : tlsgetctx("defaultserver", "default"); - server_tls_count++; - if (!port) - clsrvconf->port = stringcopy(DEFAULT_TLS_PORT, 0); - } - if (!clsrvconf->ssl_ctx) + conf->ssl_ctx = tls ? tlsgetctx(tls, NULL) : tlsgetctx("defaultclient", "default"); + if (!conf->ssl_ctx) debugx(1, DBG_ERR, "error in block %s, no tls context defined", block); - clsrvconf->type = 'T'; + conf->type = 'T'; + client_tls_count++; } else debugx(1, DBG_ERR, "error in block %s, type must be set to UDP or TLS", block); free(type); - if (!resolvepeer(clsrvconf, 0)) - debugx(1, DBG_ERR, "failed to resolve host %s port %s, exiting", clsrvconf->host, clsrvconf->port); + if (!resolvepeer(conf, 0)) + debugx(1, DBG_ERR, "failed to resolve host %s port %s, exiting", conf->host, conf->port); - if (!secret) { - if (clsrvconf->type == 'U') + if (secret) + conf->secret = secret; + else { + if (conf->type == 'U') debugx(1, DBG_ERR, "error in block %s, secret must be specified for UDP", block); - clsrvconf->secret = stringcopy(DEFAULT_TLS_SECRET, 0); - } else { - clsrvconf->secret = secret; + conf->secret = stringcopy(DEFAULT_TLS_SECRET, 0); } +} - if (clsrvconf->clients) { - if (clsrvconf->type == 'U') - clsrvconf->clients->replyq = &udp_server_replyq; - else { - clsrvconf->clients->replyq = malloc(sizeof(struct replyq)); - if (!clsrvconf->clients->replyq) - debugx(1, DBG_ERR, "malloc failed"); - clsrvconf->clients->replyq->replies = calloc(MAX_REQUESTS, sizeof(struct reply)); - if (!clsrvconf->clients->replyq->replies) - debugx(1, DBG_ERR, "malloc failed"); - clsrvconf->clients->replyq->size = MAX_REQUESTS; - clsrvconf->clients->replyq->count = 0; - pthread_mutex_init(&clsrvconf->clients->replyq->count_mutex, NULL); - pthread_cond_init(&clsrvconf->clients->replyq->count_cond, NULL); - } - } else { - pthread_mutex_init(&clsrvconf->servers->lock, NULL); - clsrvconf->servers->sock = -1; - clsrvconf->servers->requests = calloc(MAX_REQUESTS, sizeof(struct request)); - if (!clsrvconf->servers->requests) - debugx(1, DBG_ERR, "malloc failed"); - clsrvconf->servers->newrq = 0; - pthread_mutex_init(&clsrvconf->servers->newrq_mutex, NULL); - pthread_cond_init(&clsrvconf->servers->newrq_cond, NULL); +void confserver_cb(FILE *f, char *block, char *opt, char *val) { + char *type = NULL, *secret = NULL, *port = NULL, *tls = NULL, *statusserver = NULL; + struct clsrvconf *conf; + + debug(DBG_DBG, "confserver_cb called for %s", block); + + getgeneralconfig(f, block, + "type", CONF_STR, &type, + "secret", CONF_STR, &secret, + "port", CONF_STR, &port, + "tls", CONF_STR, &tls, + "StatusServer", CONF_STR, &statusserver, + NULL + ); + srvconf_count++; + srvconfs = realloc(srvconfs, srvconf_count * sizeof(struct clsrvconf)); + if (!srvconfs) + debugx(1, DBG_ERR, "malloc failed"); + conf = srvconfs + srvconf_count - 1; + memset(conf, 0, sizeof(struct clsrvconf)); + + conf->port = port; + if (statusserver) { + if (!strcasecmp(statusserver, "on")) + conf->statusserver = 1; + else if (strcasecmp(statusserver, "off")) + debugx(1, DBG_ERR, "error in block %s, StatusServer is %s, must be on or off", block, statusserver); + free(statusserver); + } + + conf->host = stringcopy(val, 0); + + if (type && !strcasecmp(type, "udp")) { + conf->type = 'U'; + server_udp_count++; + if (!port) + conf->port = stringcopy(DEFAULT_UDP_PORT, 0); + } else if (type && !strcasecmp(type, "tls")) { + conf->ssl_ctx = tls ? tlsgetctx(tls, NULL) : tlsgetctx("defaultserver", "default"); + if (!conf->ssl_ctx) + debugx(1, DBG_ERR, "error in block %s, no tls context defined", block); + if (!port) + conf->port = stringcopy(DEFAULT_TLS_PORT, 0); + conf->type = 'T'; + server_tls_count++; + } else + debugx(1, DBG_ERR, "error in block %s, type must be set to UDP or TLS", block); + free(type); + + if (!resolvepeer(conf, 0)) + debugx(1, DBG_ERR, "failed to resolve host %s port %s, exiting", conf->host, conf->port); + + if (secret) + conf->secret = secret; + else { + if (conf->type == 'U') + debugx(1, DBG_ERR, "error in block %s, secret must be specified for UDP", block); + conf->secret = stringcopy(DEFAULT_TLS_SECRET, 0); } } @@ -2277,8 +2248,8 @@ void getmainconfig(const char *configfile) { "ListenTCP", CONF_STR, &options.listentcp, "LogLevel", CONF_STR, &loglevel, "LogDestination", CONF_STR, &options.logdestination, - "Client", CONF_CBK, confclsrv_cb, - "Server", CONF_CBK, confclsrv_cb, + "Client", CONF_CBK, confclient_cb, + "Server", CONF_CBK, confserver_cb, "Realm", CONF_CBK, confrealm_cb, "TLS", CONF_CBK, conftls_cb, NULL @@ -2292,16 +2263,6 @@ void getmainconfig(const char *configfile) { options.loglevel = *loglevel - '0'; free(loglevel); } - - if (client_udp_count) { - udp_server_replyq.replies = malloc(client_udp_count * MAX_REQUESTS * sizeof(struct reply)); - if (!udp_server_replyq.replies) - debugx(1, DBG_ERR, "malloc failed"); - udp_server_replyq.size = client_udp_count * MAX_REQUESTS; - udp_server_replyq.count = 0; - pthread_mutex_init(&udp_server_replyq.count_mutex, NULL); - pthread_cond_init(&udp_server_replyq.count_cond, NULL); - } } void getargs(int argc, char **argv, uint8_t *foreground, uint8_t *loglevel, char **configfile) { @@ -2370,6 +2331,12 @@ int main(int argc, char **argv) { 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); + if (client_udp_count) { udp_server_listen = server_create('U'); if (pthread_create(&udpserverth, NULL, udpserverrd, NULL)) -- cgit v1.1