/*
- * 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
#include <openssl/err.h>
#include <openssl/md5.h>
#include <openssl/hmac.h>
+#include "debug.h"
#include "radsecproxy.h"
static struct options options;
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;
}
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");
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);
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) {
}
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;
}
(*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);
}
}
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);
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);
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++;
}
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++)
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);
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)
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');