#include "hash.h"
#include "util.h"
#include "radsecproxy.h"
-#include "dtls.h"
+
+static void setprotoopts(struct commonprotoopts *opts);
+static char **getlistenerargs();
+void *udpdtlsserverrd(void *arg);
+int dtlsconnect(struct server *server, struct timeval *when, int timeout, char *text);
+void *dtlsclientrd(void *arg);
+int clientradputdtls(struct server *server, unsigned char *rad);
+void addserverextradtls(struct clsrvconf *conf);
+void dtlssetsrcres();
+void initextradtls();
+
+static const struct protodefs protodefs = {
+ "dtls",
+ "mysecret", /* secretdefault */
+ SOCK_DGRAM, /* socktype */
+ "2083", /* portdefault */
+ REQUEST_RETRY_COUNT, /* retrycountdefault */
+ 10, /* retrycountmax */
+ REQUEST_RETRY_INTERVAL, /* retryintervaldefault */
+ 60, /* retryintervalmax */
+ DUPLICATE_INTERVAL, /* duplicateintervaldefault */
+ setprotoopts, /* setprotoopts */
+ getlistenerargs, /* getlistenerargs */
+ udpdtlsserverrd, /* listener */
+ dtlsconnect, /* connecter */
+ dtlsclientrd, /* clientconnreader */
+ clientradputdtls, /* clientradput */
+ NULL, /* addclient */
+ addserverextradtls, /* addserverextra */
+ dtlssetsrcres, /* setsrcres */
+ initextradtls /* initextra */
+};
static int client4_sock = -1;
static int client6_sock = -1;
+static struct addrinfo *srcres = NULL;
+static uint8_t handle;
+static struct commonprotoopts *protoopts = NULL;
+
+const struct protodefs *dtlsinit(uint8_t h) {
+ handle = h;
+ return &protodefs;
+}
+
+static void setprotoopts(struct commonprotoopts *opts) {
+ protoopts = opts;
+}
+
+static char **getlistenerargs() {
+ return protoopts ? protoopts->listenargs : NULL;
+}
struct sessioncacheentry {
pthread_mutex_t mutex;
struct sockaddr_storage addr;
};
+void dtlssetsrcres() {
+ if (!srcres)
+ srcres = resolve_hostport_addrinfo(handle, protoopts ? protoopts->sourcearg : NULL);
+
+}
+
int udp2bio(int s, struct queue *q, int cnt) {
unsigned char *buf;
BIO *rbio;
pthread_mutex_unlock(&client->replyq->mutex);
debug(DBG_DBG, "dtlsserverrd: waiting for writer to end");
pthread_join(dtlsserverwrth, NULL);
- removeclientrqs(client);
debug(DBG_DBG, "dtlsserverrd: reader for %s exiting", addr2string(client->addr));
}
struct list_node *cur = NULL;
SSL *ssl = NULL;
X509 *cert = NULL;
+ SSL_CTX *ctx = NULL;
uint8_t delay = 60;
debug(DBG_DBG, "dtlsservernew: starting");
- conf = find_clconf(RAD_DTLS, (struct sockaddr *)¶ms->addr, NULL);
+ conf = find_clconf(handle, (struct sockaddr *)¶ms->addr, NULL);
if (conf) {
- ssl = dtlsacccon(1, conf->ssl_ctx, params->sock, (struct sockaddr *)¶ms->addr, params->sesscache->rbios);
+ ctx = tlsgetctx(handle, conf->tlsconf);
+ if (!ctx)
+ goto exit;
+ ssl = dtlsacccon(1, ctx, params->sock, (struct sockaddr *)¶ms->addr, params->sesscache->rbios);
if (!ssl)
goto exit;
cert = verifytlscert(ssl);
}
goto exit;
}
- conf = find_clconf(RAD_DTLS, (struct sockaddr *)¶ms->addr, &cur);
+ conf = find_clconf(handle, (struct sockaddr *)¶ms->addr, &cur);
}
debug(DBG_WARN, "dtlsservernew: ignoring request, no matching TLS client");
struct timeval now;
time_t elapsed;
X509 *cert;
-
+ SSL_CTX *ctx = NULL;
+
debug(DBG_DBG, "dtlsconnect: called from %s", text);
pthread_mutex_lock(&server->lock);
if (when && memcmp(&server->lastconnecttry, when, sizeof(struct timeval))) {
debug(DBG_WARN, "dtlsconnect: trying to open DTLS connection to %s port %s", server->conf->host, server->conf->port);
SSL_free(server->ssl);
- server->ssl = dtlsacccon(0, server->conf->ssl_ctx, server->sock, server->conf->addrinfo->ai_addr, server->rbios);
+ server->ssl = NULL;
+ ctx = tlsgetctx(handle, server->conf->tlsconf);
+ if (!ctx)
+ continue;
+ server->ssl = dtlsacccon(0, ctx, server->sock, server->conf->addrinfo->ai_addr, server->rbios);
if (!server->ssl)
continue;
debug(DBG_DBG, "dtlsconnect: DTLS: ok");
}
X509_free(cert);
debug(DBG_WARN, "dtlsconnect: DTLS connection to %s port %s up", server->conf->host, server->conf->port);
+ server->connectionok = 1;
gettimeofday(&server->lastconnecttry, NULL);
pthread_mutex_unlock(&server->lock);
return 1;
unsigned long error;
struct clsrvconf *conf = server->conf;
- if (!server->ssl)
+ if (!server->connectionok)
return 0;
len = RADLEN(rad);
- while ((cnt = SSL_write(server->ssl, rad, len)) <= 0) {
+ if ((cnt = SSL_write(server->ssl, rad, len)) <= 0) {
while ((error = ERR_get_error()))
debug(DBG_ERR, "clientradputdtls: DTLS: %s", ERR_error_string(error, NULL));
+ return 0;
}
debug(DBG_DBG, "clientradputdtls: Sent %d bytes, Radius packet of length %d to DTLS peer %s", cnt, len, conf->host);
return 1;
continue;
}
- conf = find_srvconf(RAD_DTLS, (struct sockaddr *)&from, NULL);
+ conf = find_srvconf(handle, (struct sockaddr *)&from, NULL);
if (!conf) {
debug(DBG_WARN, "udpdtlsclientrd: got packet from wrong or unknown DTLS peer %s, ignoring", addr2string((struct sockaddr *)&from));
recv(s, buf, 4, 0);
switch (conf->addrinfo->ai_family) {
case AF_INET:
if (client4_sock < 0) {
- client4_sock = bindtoaddr(getsrcprotores(RAD_DTLS), AF_INET, 0, 1);
+ client4_sock = bindtoaddr(srcres, AF_INET, 0, 1);
if (client4_sock < 0)
debugx(1, DBG_ERR, "addserver: failed to create client socket for server %s", conf->host);
}
break;
case AF_INET6:
if (client6_sock < 0) {
- client6_sock = bindtoaddr(getsrcprotores(RAD_DTLS), AF_INET6, 0, 1);
+ client6_sock = bindtoaddr(srcres, AF_INET6, 0, 1);
if (client6_sock < 0)
debugx(1, DBG_ERR, "addserver: failed to create client socket for server %s", conf->host);
}
void initextradtls() {
pthread_t cl4th, cl6th;
+
+ if (srcres) {
+ freeaddrinfo(srcres);
+ srcres = NULL;
+ }
if (client4_sock >= 0)
if (pthread_create(&cl4th, NULL, udpdtlsclientrd, (void *)&client4_sock))