using debug() in getconfig()
[radsecproxy.git] / radsecproxy.c
index f6bdc6c..c7d65f5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Stig Venaas <venaas@uninett.no>
+ * Copyright (C) 2006, 2007 Stig Venaas <venaas@uninett.no>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -48,6 +48,7 @@
 #include <openssl/err.h>
 #include <openssl/md5.h>
 #include <openssl/hmac.h>
+#include "debug.h"
 #include "radsecproxy.h"
 
 static struct options options;
@@ -527,7 +528,7 @@ int clientradput(struct server *server, unsigned char *rad) {
     lastconnecttry = server->lastconnecttry;
     while ((cnt = SSL_write(server->peer.ssl, rad, len)) <= 0) {
        while ((error = ERR_get_error()))
-           err("clientwr: TLS: %s", ERR_error_string(error, NULL));
+           err("clientradput: TLS: %s", ERR_error_string(error, NULL));
        tlsconnect(server, &lastconnecttry, "clientradput");
        lastconnecttry = server->lastconnecttry;
     }
@@ -1285,11 +1286,13 @@ void *clientwr(void *arg) {
     struct request *rq;
     pthread_t clientrdth;
     int i;
-    struct timeval now;
+    uint8_t rnd;
+    struct timeval now, lastsend;
     struct timespec timeout;
 
+    memset(&lastsend, 0, sizeof(struct timeval));
     memset(&timeout, 0, sizeof(struct timespec));
-    
+
     if (server->peer.type == 'U') {
        if ((server->sock = connecttoserver(server->peer.addrinfo)) < 0) {
            printf("clientwr: connecttoserver failed\n");
@@ -1304,10 +1307,18 @@ void *clientwr(void *arg) {
     for (;;) {
        pthread_mutex_lock(&server->newrq_mutex);
        if (!server->newrq) {
-           if (timeout.tv_nsec) {
-               printf("clientwr: waiting up to %ld secs for new request\n", timeout.tv_nsec);
+           gettimeofday(&now, NULL);
+           if (timeout.tv_sec) {
+               printf("clientwr: waiting up to %ld secs for new request\n", timeout.tv_sec - now.tv_sec);
                pthread_cond_timedwait(&server->newrq_cond, &server->newrq_mutex, &timeout);
-               timeout.tv_nsec = 0;
+               timeout.tv_sec = 0;
+           } else if (options.statusserver) {
+               timeout.tv_sec = now.tv_sec + STATUS_SERVER_PERIOD;
+               /* add random 0-7 seconds to timeout */
+               RAND_bytes(&rnd, 1);
+               timeout.tv_sec += rnd / 32;
+               pthread_cond_timedwait(&server->newrq_cond, &server->newrq_mutex, &timeout);
+               timeout.tv_sec = 0;
            } else {
                printf("clientwr: waiting for new request\n");
                pthread_cond_wait(&server->newrq_cond, &server->newrq_mutex);
@@ -1363,10 +1374,17 @@ void *clientwr(void *arg) {
                timeout.tv_sec = rq->expiry.tv_sec;
            rq->tries++;
            clientradput(server, server->requests[i].buf);
+           gettimeofday(&lastsend, NULL);
            usleep(200000);
        }
+       if (options.statusserver) {
+           gettimeofday(&now, NULL);
+           if (now.tv_sec - lastsend.tv_sec >= STATUS_SERVER_PERIOD) {
+               lastsend.tv_sec = now.tv_sec;
+               printf("clientwr: should send status to %s here\n", server->peer.host);
+           }
+       }
     }
-    /* should do more work to maintain TLS connections, keepalives etc */
 }
 
 void *udpserverwr(void *arg) {
@@ -1663,9 +1681,9 @@ FILE *openconfigfile(const char *filename) {
     }
 
     if (!f)
-       err("could not read config file %s nor %s\n", filename, base);
-
-    printf("reading config file %s\n", base);
+       debug(DBG_ERR, "could not read config file %s nor %s\n%s", filename, base, strerror(errno));
+    
+    debug(DBG_INFO, "reading config file %s", base);
     return f;
 }
 
@@ -1700,8 +1718,7 @@ void getconfig(const char *serverfile, const char *clientfile) {
            (*ucount)++;
            break;
        default:
-           printf("type must be U or T, got %c\n", *p);
-           exit(1);
+           debug(DBG_ERR, "type must be U or T, got %c", *p);
        }
     }
 
@@ -1709,18 +1726,18 @@ void getconfig(const char *serverfile, const char *clientfile) {
        count = server_count = server_udp_count + server_tls_count;
        servers = calloc(count, sizeof(struct server));
        if (!servers)
-           errx("malloc failed");
+           debug(DBG_ERR, "malloc failed");
     } else {
        count = client_count = client_udp_count + client_tls_count;
        clients = calloc(count, sizeof(struct client));
        if (!clients)
-           errx("malloc failed");
+           debug(DBG_ERR, "malloc failed");
     }
     
     if (client_udp_count) {
        udp_server_replyq.replies = malloc(client_udp_count * MAX_REQUESTS * sizeof(struct reply));
        if (!udp_server_replyq.replies)
-           errx("malloc failed");
+           debug(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);
@@ -1751,33 +1768,27 @@ void getconfig(const char *serverfile, const char *clientfile) {
        for (; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++);
        if (field == p) {
            /* no secret set and end of line, line is complete if TLS */
-           if (peer->type == 'U') {
-               printf("secret must be specified for UDP\n");
-               exit(1);
-           }
+           if (peer->type == 'U')
+               debug(DBG_ERR, "secret must be specified for UDP");
            peer->secret = stringcopy(DEFAULT_TLS_SECRET, 0);
        } else {
            peer->secret = stringcopy(field, p - field);
            /* check that rest of line only white space */
            for (; *p == ' ' || *p == '\t'; p++);
-           if (*p && *p != '\n') {
-               printf("max 4 fields per line, found a 5th\n");
-               exit(1);
-           }
+           if (*p && *p != '\n')
+               debug(DBG_ERR, "max 4 fields per line, found a 5th");
        }
 
        if ((serverfile && !resolvepeer(&server->peer, 0)) ||
-           (clientfile && !resolvepeer(&client->peer, 0))) {
-           printf("failed to resolve host %s port %s, exiting\n", peer->host, peer->port);
-           exit(1);
-       }
+           (clientfile && !resolvepeer(&client->peer, 0)))
+           debug(DBG_ERR, "failed to resolve host %s port %s, exiting", peer->host, peer->port);
 
        if (serverfile) {
            pthread_mutex_init(&server->lock, NULL);
            server->sock = -1;
            server->requests = calloc(MAX_REQUESTS, sizeof(struct request));
            if (!server->requests)
-               errx("malloc failed");
+               debug(DBG_ERR, "malloc failed");
            server->newrq = 0;
            pthread_mutex_init(&server->newrq_mutex, NULL);
            pthread_cond_init(&server->newrq_cond, NULL);
@@ -1787,22 +1798,21 @@ void getconfig(const char *serverfile, const char *clientfile) {
            else {
                client->replyq = malloc(sizeof(struct replyq));
                if (!client->replyq)
-                   errx("malloc failed");
+                   debug(DBG_ERR, "malloc failed");
                client->replyq->replies = calloc(MAX_REQUESTS, sizeof(struct reply));
                if (!client->replyq->replies)
-                   errx("malloc failed");
+                   debug(DBG_ERR, "malloc failed");
                client->replyq->size = MAX_REQUESTS;
                client->replyq->count = 0;
                pthread_mutex_init(&client->replyq->count_mutex, NULL);
                pthread_cond_init(&client->replyq->count_cond, NULL);
            }
        }
-       printf("got type %c, host %s, port %s, secret %s\n", peer->type, peer->host, peer->port, peer->secret);
+       debug(DBG_INFO, "got type %c, host %s, port %s, secret %s", peer->type, peer->host, peer->port, peer->secret);
        if (serverfile) {
-           printf("    with realms:");
+           debug(DBG_INFO, "    with realms:");
            for (r = server->realms; *r; r++)
-               printf(" %s", *r);
-           printf("\n");
+               debug(DBG_INFO, "\t%s", *r);
        }
        i++;
     }
@@ -1852,8 +1862,7 @@ void getmainconfig(const char *configfile) {
        for (; *p == ' ' || *p == '\t'; p++);
        if (!*p || *p == '\n') {
            endopt[1] = '\0';
-           printf("error in %s, option %s has no value\n", configfile, opt);
-           exit(1);
+           debug(DBG_ERR, "error in %s, option %s has no value", configfile, opt);
        }
        val = p;
        for (; *p && *p != '\n'; p++)
@@ -1861,7 +1870,7 @@ void getmainconfig(const char *configfile) {
                endval = p;
        endopt[1] = '\0';
        endval[1] = '\0';
-       printf("getmainconfig: %s = %s\n", opt, val);
+       debug(DBG_INFO, "getmainconfig: %s = %s", opt, val);
        
        if (!strcasecmp(opt, "TLSCACertificateFile")) {
            options.tlscacertificatefile = stringcopy(val, 0);
@@ -1891,51 +1900,32 @@ void getmainconfig(const char *configfile) {
            options.listentcp = stringcopy(val, 0);
            continue;
        }
-       printf("error in %s, unknown option %s\n", configfile, opt);
-       exit(1);
-    }
-    fclose(f);
-}
-
-#if 0
-void parseargs(int argc, char **argv) {
-    int c;
-
-    while ((c = getopt(argc, argv, "p:")) != -1) {
-       switch (c) {
-       case 'p':
-           udp_server_port = optarg;
-           break;
-       default:
-           goto usage;
+       if (!strcasecmp(opt, "StatusServer")) {
+           if (!strcasecmp(val, "on"))
+               options.statusserver = 1;
+           else if (strcasecmp(val, "off")) {
+               debug(DBG_ERR, "error in %s, value of option %s is %s, must be on or off", configfile, opt, val);
+           }
+           continue;
        }
+       debug(DBG_ERR, "error in %s, unknown option %s", configfile, opt);
     }
-
-    return;
-
- usage:
-    printf("radsecproxy [ -p UDP-port ]\n");
-    exit(1);
+    fclose(f);
 }
-#endif
 
 int main(int argc, char **argv) {
     pthread_t udpserverth;
-    /*    pthread_attr_t joinable; */
     int i;
-    
-    /*    parseargs(argc, argv); */
+
+    debug_set_level(DEBUG_LEVEL);
     getmainconfig(CONFIG_MAIN);
     getconfig(CONFIG_SERVERS, NULL);
     getconfig(NULL, CONFIG_CLIENTS);
 
-    /*    pthread_attr_init(&joinable); */
-    /*    pthread_attr_setdetachstate(&joinable, PTHREAD_CREATE_JOINABLE); */
-   
     if (client_udp_count) {
        udp_server_listen = server_create('U');
-       if (pthread_create(&udpserverth, NULL /*&joinable*/, udpserverrd, NULL))
-           errx("pthread_create failed");
+       if (pthread_create(&udpserverth, NULL, udpserverrd, NULL))
+           debug(DBG_ERR, "pthread_create failed");
     }
     
     if (client_tls_count || server_tls_count)
@@ -1943,7 +1933,7 @@ int main(int argc, char **argv) {
     
     for (i = 0; i < server_count; i++)
        if (pthread_create(&servers[i].clientth, NULL, clientwr, (void *)&servers[i]))
-           errx("pthread_create failed");
+           debug(DBG_ERR, "pthread_create failed");
 
     if (client_tls_count) {
        tcp_server_listen = server_create('T');