[packages/radsecproxy] - up to 1.10.1

adwol adwol at pld-linux.org
Wed Jun 5 12:13:41 CEST 2024


commit ac1e65a99fcdf1c7f1bd2c119024ed6f4ddc12bf
Author: Adam Osuchowski <adwol at pld-linux.org>
Date:   Wed Jun 5 12:13:06 2024 +0200

    - up to 1.10.1

 git.patch | 2058 -------------------------------------------------------------
 1 file changed, 2058 deletions(-)
---
diff --git a/git.patch b/git.patch
deleted file mode 100644
index a0fdca1..0000000
--- a/git.patch
+++ /dev/null
@@ -1,2058 +0,0 @@
-diff --git a/ChangeLog b/ChangeLog
-index c1943fb..d6552db 100644
---- a/ChangeLog
-+++ b/ChangeLog
-@@ -1,3 +1,20 @@
-+unreleased changes
-+	New features:
-+	- Optionally log accounting requests when respoinding directly (#72)
-+	- SNI support for outgoing connections (#90)
-+
-+	Misc:
-+	- Don't require server type to be set by dyndisc scripts
-+	- OpenSSL 3.0 compatibility (#70)
-+	
-+	Bug Fixes:
-+	- Fix refused startup with openssl <1.1 (#82)
-+	- Fix compiler issue for Fedora 33 on s390x (#84)
-+	- Fix small memory leak in config parser
-+	- Fix lazy certificate check when connecting to TLS servers
-+	- Fix connect is aborted if first host in list has invalid certificate
-+	- Fix setstacksize for glibc 2.34 (#91)
-+
- 2021-05-28 1.9.0
- 	New features:
- 	- Accept multiple source* configs for IPv4/v6
-diff --git a/README b/README
-index 20700fa..5074c77 100644
---- a/README
-+++ b/README
-@@ -8,11 +8,12 @@ flexible, while at the same time to be small, efficient and easy to configure.
- Official packages are available:
- 
- Debian: apt-get install radsecproxy
-+CentOS/RHEL/Rocky: yum install epel-release; yum install radsecproxy
- Fedora: dnf install radsecproxy
- FreeBSD: pkg install radsecproxy
- NetBSD: pkgin install radsecproxy
- 
--Or built it from this rouce on most Unix like systems by simply typing
-+Or built it from this source on most Unix like systems by simply typing
- 
-     ./configure && make
- 
-diff --git a/configure.ac b/configure.ac
-index 630fcac..d486e47 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -11,6 +11,12 @@ AC_PROG_RANLIB
- AC_CHECK_FUNCS([mallopt])
- AC_REQUIRE_AUX_FILE([tap-driver.sh])
- 
-+m4_version_prereq(2.70, [], [AC_PROG_CC_C99])
-+if test "$ac_cv_prog_cc_c99" = "no"; then
-+  echo "requires C99 compatible compiler"
-+  exit -1
-+fi
-+
- udp=yes
- AC_ARG_ENABLE(udp,
-   [  --enable-udp whether to enable UDP transport: yes/no; default yes ],
-diff --git a/dtls.c b/dtls.c
-index 09aa9ee..15835d6 100644
---- a/dtls.c
-+++ b/dtls.c
-@@ -142,6 +142,7 @@ int dtlsread(SSL *ssl, unsigned char *buf, int num, int timeout, pthread_mutex_t
-                     continue;
-                 case SSL_ERROR_ZERO_RETURN:
-                     debug(DBG_DBG, "dtlsread: got ssl shutdown");
-+                    /* fallthrough */
-                 default:
-                     while ((error = ERR_get_error()))
-                         debug(DBG_ERR, "dtlsread: SSL: %s", ERR_error_string(error, NULL));
-@@ -305,10 +306,11 @@ void *dtlsservernew(void *arg) {
-     struct timeval timeout;
-     struct addrinfo tmpsrvaddr;
-     char tmp[INET6_ADDRSTRLEN], *subj;
-+    struct hostportres *hp;
- 
-     debug(DBG_WARN, "dtlsservernew: incoming DTLS connection from %s", addr2string((struct sockaddr *)&params->addr, tmp, sizeof(tmp)));
- 
--    conf = find_clconf(handle, (struct sockaddr *)&params->addr, NULL);
-+    conf = find_clconf(handle, (struct sockaddr *)&params->addr, NULL, &hp);
-     if (!conf)
-         goto exit;
- 
-@@ -342,7 +344,7 @@ void *dtlsservernew(void *arg) {
-     accepted_tls = conf->tlsconf;
- 
-     while (conf) {
--        if (accepted_tls == conf->tlsconf && verifyconfcert(cert, conf)) {
-+        if (accepted_tls == conf->tlsconf && verifyconfcert(cert, conf, NULL)) {
-             subj = getcertsubject(cert);
-             if(subj) {
-                 debug(DBG_WARN, "dtlsservernew: DTLS connection from %s, client %s, subject %s up",
-@@ -362,9 +364,10 @@ void *dtlsservernew(void *arg) {
-             }
-             goto exit;
-         }
--        conf = find_clconf(handle, (struct sockaddr *)&params->addr, &cur);
-+        conf = find_clconf(handle, (struct sockaddr *)&params->addr, &cur, &hp);
-     }
--    debug(DBG_WARN, "dtlsservernew: ignoring request, no matching TLS client");
-+    debug(DBG_WARN, "dtlsservernew: ignoring request, no matching TLS client for %s", 
-+        addr2string((struct sockaddr *)&params->addr, tmp, sizeof(tmp)));
- 
-     if (cert)
-     X509_free(cert);
-@@ -467,7 +470,7 @@ void *dtlslistener(void *arg) {
-             continue;
-         }
- 
--        conf = find_clconf(handle, (struct sockaddr *)&from, NULL);
-+        conf = find_clconf(handle, (struct sockaddr *)&from, NULL, NULL);
-         if (!conf) {
-             debug(DBG_INFO, "dtlslistener: got UDP from unknown peer %s, ignoring", addr2string((struct sockaddr *)&from, tmp, sizeof(tmp)));
-             if (recv(s, buf, 4, 0) == -1)
-@@ -486,6 +489,7 @@ void *dtlslistener(void *arg) {
-             ssl = SSL_new(ctx);
-             if (!ssl) {
-                 pthread_mutex_unlock(&conf->tlsconf->lock);
-+                debug(DBG_ERR, "dtlslistener: failed to create SSL connection");
-                 continue;
-             }
-             bio = BIO_new_dgram(s, BIO_NOCLOSE);
-@@ -514,12 +518,28 @@ void *dtlslistener(void *arg) {
-             } else {
-                 free(params);
-             }
-+        } else {
-+            unsigned long error;
-+            while ((error = ERR_get_error()))
-+                debug(DBG_ERR, "dtlslistener: DTLS_listen failed: %s", ERR_error_string(error, NULL));
-+            debug(DBG_ERR, "dtlslistener: DTLS_listen failed from %s", addr2string((struct sockaddr *)&from, tmp, sizeof(tmp)));
-         }
-         pthread_mutex_unlock(&conf->tlsconf->lock);
-     }
-     return NULL;
- }
- 
-+static void cleanup_connection(struct server *server) {
-+    if (server->ssl)
-+        SSL_shutdown(server->ssl);
-+    if (server->sock >= 0)
-+        close(server->sock);
-+    server->sock = -1;
-+    if (server->ssl)
-+        SSL_free(server->ssl);
-+    server->ssl = NULL;
-+}
-+
- int dtlsconnect(struct server *server, int timeout, char *text) {
-     struct timeval socktimeout, now, start;
-     time_t wait;
-@@ -531,6 +551,7 @@ int dtlsconnect(struct server *server, int timeout, char *text) {
-     BIO *bio;
-     struct addrinfo *source = NULL;
-     char *subj;
-+    struct list_node *entry;
- 
-     debug(DBG_DBG, "dtlsconnect: called from %s", text);
-     pthread_mutex_lock(&server->lock);
-@@ -540,8 +561,6 @@ int dtlsconnect(struct server *server, int timeout, char *text) {
- 
-     pthread_mutex_unlock(&server->lock);
- 
--    hp = (struct hostportres *)list_first(server->conf->hostports)->data;
--
-     if(server->conf->source) {
-         source = resolvepassiveaddrinfo(server->conf->source, AF_UNSPEC, NULL, protodefs.socktype);
-         if(!source)
-@@ -552,13 +571,7 @@ int dtlsconnect(struct server *server, int timeout, char *text) {
- 
-     for (;;) {
-         /* ensure previous connection is properly closed */
--        if (server->ssl)
--            SSL_shutdown(server->ssl);
--        if (server->sock >= 0)
--            close(server->sock);
--        if (server->ssl)
--            SSL_free(server->ssl);
--        server->ssl = NULL;
-+        cleanup_connection(server);
- 
-         wait = connect_wait(start, server->connecttime, firsttry);
-         gettimeofday(&now, NULL);
-@@ -567,55 +580,84 @@ int dtlsconnect(struct server *server, int timeout, char *text) {
-             if (source) freeaddrinfo(source);
-             return 0;
-         }
--        debug(DBG_INFO, "Next connection attempt to %s in %lds", server->conf->name, wait);
-+        if (wait) debug(DBG_INFO, "Next connection attempt to %s in %lds", server->conf->name, wait);
-         sleep(wait);
-         firsttry = 0;
- 
--        debug(DBG_INFO, "dtlsconnect: connecting to %s port %s", hp->host, hp->port);
-+        for (entry = list_first(server->conf->hostports); entry; entry = list_next(entry)) {
-+            hp = (struct hostportres *)entry->data;
-+            debug(DBG_INFO, "dtlsconnect: trying to open DTLS connection to server %s (%s port %s)", server->conf->name, hp->host, hp->port);
-+            if ((server->sock = bindtoaddr(source ? source : srcres, hp->addrinfo->ai_family, 0)) < 0) {
-+                debug(DBG_ERR, "dtlsconnect: faild to bind socket for server %s (%s port %s)", server->conf->name, hp->host, hp->port);
-+                goto concleanup;
-+            }
-+            if (connect(server->sock, hp->addrinfo->ai_addr, hp->addrinfo->ai_addrlen)) {
-+                debug(DBG_ERR, "dtlsconnect: faild to connect socket for server %s (%s port %s)", server->conf->name, hp->host, hp->port);
-+                goto concleanup;
-+            }
- 
--        if ((server->sock = bindtoaddr(source ? source : srcres, hp->addrinfo->ai_family, 0)) < 0)
--            continue;
--        if (connect(server->sock, hp->addrinfo->ai_addr, hp->addrinfo->ai_addrlen))
--            continue;
-+            pthread_mutex_lock(&server->conf->tlsconf->lock);
-+            if (!(ctx = tlsgetctx(handle, server->conf->tlsconf))){
-+                pthread_mutex_unlock(&server->conf->tlsconf->lock);
-+                debug(DBG_ERR, "dtlsconnect: failed to get TLS context for server %s", server->conf->name);
-+                goto concleanup;
-+            }
- 
--        pthread_mutex_lock(&server->conf->tlsconf->lock);
--        if (!(ctx = tlsgetctx(handle, server->conf->tlsconf))){
-+            server->ssl = SSL_new(ctx);
-             pthread_mutex_unlock(&server->conf->tlsconf->lock);
--            continue;
--        }
-+            if (!server->ssl) {
-+                debug(DBG_ERR, "dtlsconnect: failed to create SSL conneciton for server %s", server->conf->name);
-+                goto concleanup;
-+            }
- 
--        server->ssl = SSL_new(ctx);
--        pthread_mutex_unlock(&server->conf->tlsconf->lock);
--        if (!server->ssl)
--            continue;
-+            if (server->conf->sni) {
-+                struct in6_addr tmp;
-+                char *servername = server->conf->sniservername ? server->conf->sniservername : 
-+                    (inet_pton(AF_INET, hp->host, &tmp) || inet_pton(AF_INET6, hp->host, &tmp)) ? NULL : hp->host;
-+                if (servername && !tlssetsni(server->ssl, servername)) {
-+                    debug(DBG_ERR, "tlsconnect: set SNI %s failed", servername);
-+                    goto concleanup;
-+                }
-+            }
- 
--        bio = BIO_new_dgram(server->sock, BIO_CLOSE);
--        BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, hp->addrinfo->ai_addr);
--        SSL_set_bio(server->ssl, bio, bio);
--        if (sslconnecttimeout(server->ssl, 5) <= 0) {
--            while ((error = ERR_get_error()))
--                debug(DBG_ERR, "dtlsconnect: SSL connect to %s failed: %s", server->conf->name, ERR_error_string(error, NULL));
--            debug(DBG_ERR, "dtlsconnect: SSL connect to %s failed", server->conf->name);
--            continue;
--        }
--        socktimeout.tv_sec = 5;
--        socktimeout.tv_usec = 0;
--        if (BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &socktimeout) == -1)
--            debug(DBG_WARN, "dtlsconnect: BIO_CTRL_DGRAM_SET_RECV_TIMEOUT failed");
-+            bio = BIO_new_dgram(server->sock, BIO_CLOSE);
-+            BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, hp->addrinfo->ai_addr);
-+            SSL_set_bio(server->ssl, bio, bio);
-+            if (sslconnecttimeout(server->ssl, 5) <= 0) {
-+                while ((error = ERR_get_error()))
-+                    debug(DBG_ERR, "dtlsconnect: SSL connect to %s failed: %s", server->conf->name, ERR_error_string(error, NULL));
-+                debug(DBG_ERR, "dtlsconnect: SSL connect to %s (%s port %s) failed", server->conf->name, hp->host, hp->port);
-+                goto concleanup;
-+            }
-+            socktimeout.tv_sec = 5;
-+            socktimeout.tv_usec = 0;
-+            if (BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &socktimeout) == -1)
-+                debug(DBG_WARN, "dtlsconnect: BIO_CTRL_DGRAM_SET_RECV_TIMEOUT failed");
-+
-+            cert = verifytlscert(server->ssl);
-+            if (!cert) {
-+                debug(DBG_ERR, "tlsconnect: certificate verification failed for %s (%s port %s)", server->conf->name, hp->host, hp->port);
-+                goto concleanup;
-+            }
- 
--        cert = verifytlscert(server->ssl);
--        if (!cert)
--            continue;
--        if (verifyconfcert(cert, server->conf)) {
--            subj = getcertsubject(cert);
--            if(subj) {
--                debug(DBG_WARN, "dtlsconnect: DTLS connection to %s, subject %s up", server->conf->name, subj);
--                free(subj);
-+            if (verifyconfcert(cert, server->conf, hp)) {
-+                subj = getcertsubject(cert);
-+                if(subj) {
-+                    debug(DBG_WARN, "dtlsconnect: DTLS connection to %s (%s port %s), subject %s up", server->conf->name, hp->host, hp->port, subj);
-+                    free(subj);
-+                }
-+                X509_free(cert);
-+                break;
-+            } else {
-+                debug(DBG_ERR, "tlsconnect: certificate verification failed for %s (%s port %s)", server->conf->name, hp->host, hp->port);
-             }
-             X509_free(cert);
--            break;
-+
-+concleanup:
-+            /* ensure previous connection is properly closed */
-+            cleanup_connection(server);
-         }
--        X509_free(cert);
-+        if (server->ssl) break;
-     }
- 
-     pthread_mutex_lock(&server->lock);
-diff --git a/hostport.c b/hostport.c
-index 6408505..d0651d4 100644
---- a/hostport.c
-+++ b/hostport.c
-@@ -222,7 +222,7 @@ int resolvehostports(struct list *hostports, int af, int socktype) {
- }
- 
- struct addrinfo *resolvepassiveaddrinfo(char **hostport, int af, char *default_port, int socktype) {
--    struct addrinfo *ai = NULL, *last_ai;
-+    struct addrinfo *ai = NULL, *last_ai = NULL;
-     int i;
-     char *any[2] = {"*", NULL};
- 
-@@ -258,7 +258,7 @@ static int prefixmatch(void *a1, void *a2, uint8_t len) {
-     return (((uint8_t *)a1)[l] & mask[r]) == (((uint8_t *)a2)[l] & mask[r]);
- }
- 
--int _internal_addressmatches(struct list *hostports, struct sockaddr *addr, uint8_t prefixlen, uint8_t checkport) {
-+int _internal_addressmatches(struct list *hostports, struct sockaddr *addr, uint8_t prefixlen, uint8_t checkport, struct hostportres **hpreturn) {
-     struct sockaddr_in6 *sa6 = NULL;
-     struct in_addr *a4 = NULL;
-     struct addrinfo *res;
-@@ -287,16 +287,20 @@ int _internal_addressmatches(struct list *hostports, struct sockaddr *addr, uint
-                     !memcmp(&sa6->sin6_addr,
-                     &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16) &&
-                     (!checkport || ((struct sockaddr_in6 *)res->ai_addr)->sin6_port ==
--                    ((struct sockaddr_in6 *)addr)->sin6_port)))
-+                    ((struct sockaddr_in6 *)addr)->sin6_port))) {
- 
-+                    if (hpreturn) *hpreturn = hp;
-                     return 1;
-+                }
-             } else if (hp->prefixlen <= prefixlen) {
-                 if ((a4 && res->ai_family == AF_INET &&
-                     prefixmatch(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, hp->prefixlen)) ||
-                     (sa6 && res->ai_family == AF_INET6 &&
--                    prefixmatch(&sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, hp->prefixlen)))
-+                    prefixmatch(&sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, hp->prefixlen))) {
- 
-+                    if (hpreturn) *hpreturn = hp;
-                     return 1;
-+                }
-             }
-         }
-     }
-@@ -312,18 +316,18 @@ int hostportmatches(struct list *hostports, struct list *matchhostports, uint8_t
-         match = (struct hostportres *)entry->data;
- 
-         for (res = match->addrinfo; res; res = res->ai_next) {
--            if (_internal_addressmatches(hostports, res->ai_addr, match->prefixlen, checkport))
-+            if (_internal_addressmatches(hostports, res->ai_addr, match->prefixlen, checkport, NULL))
-                 return 1;
-         }
-     }
-     return 0;
- }
- 
--int addressmatches(struct list *hostports, struct sockaddr *addr, uint8_t checkport) {
--    return _internal_addressmatches(hostports, addr, 255, checkport);
-+int addressmatches(struct list *hostports, struct sockaddr *addr, uint8_t checkport, struct hostportres **hp) {
-+    return _internal_addressmatches(hostports, addr, 255, checkport, hp);
- }
- 
--int connecttcphostlist(struct list *hostports,  struct addrinfo *src) {
-+int connecttcphostlist(struct list *hostports,  struct addrinfo *src, struct hostportres** hpreturn) {
-     int s;
-     struct list_node *entry;
-     struct hostportres *hp = NULL;
-@@ -333,6 +337,7 @@ int connecttcphostlist(struct list *hostports,  struct addrinfo *src) {
- 	debug(DBG_WARN, "connecttcphostlist: trying to open TCP connection to %s port %s", hp->host, hp->port);
- 	if ((s = connecttcp(hp->addrinfo, src, list_count(hostports) > 1 ? 5 : 30)) >= 0) {
- 	    debug(DBG_WARN, "connecttcphostlist: TCP connection to %s port %s up", hp->host, hp->port);
-+        if (hpreturn) *hpreturn = hp;
- 	    return s;
- 	}
-     }
-diff --git a/hostport.h b/hostport.h
-index 9069ecd..a554a77 100644
---- a/hostport.h
-+++ b/hostport.h
-@@ -2,6 +2,9 @@
-  * Copyright (c) 2012, NORDUnet A/S */
- /* See LICENSE for licensing information. */
- 
-+#ifndef _HOSTPORT_H
-+#define _HOSTPORT_H
-+
- struct hostportres {
-     char *host;
-     char *port;
-@@ -17,9 +20,10 @@ int resolvehostport(struct hostportres *hp, int af, int socktype, uint8_t passiv
- int resolvehostports(struct list *hostports, int af, int socktype);
- struct addrinfo *resolvepassiveaddrinfo(char **hostport, int af, char *default_port, int socktype);
- int hostportmatches(struct list *hostports, struct list *matchhostports, uint8_t checkport);
--int addressmatches(struct list *hostports, struct sockaddr *addr, uint8_t checkport);
--int connecttcphostlist(struct list *hostports,  struct addrinfo *src);
-+int addressmatches(struct list *hostports, struct sockaddr *addr, uint8_t checkport, struct hostportres **hp);
-+int connecttcphostlist(struct list *hostports,  struct addrinfo *src, struct hostportres **hpreturn);
- 
-+#endif /* _HOSTPORT_H */
- /* Local Variables: */
- /* c-file-style: "stroustrup" */
- /* End: */
-diff --git a/list.h b/list.h
-index f015b9d..c8c4531 100644
---- a/list.h
-+++ b/list.h
-@@ -35,7 +35,7 @@ int list_push(struct list *list, void *data);
- /* removes first entry from list and returns data */
- void *list_shift(struct list *list);
- 
--/* removes first entry with matching data pointer */
-+/* removes all entries with matching data pointer */
- void list_removedata(struct list *list, void *data);
- 
- /* returns first node */
-diff --git a/raddict.h b/raddict.h
-new file mode 100644
-index 0000000..8a9c598
---- /dev/null
-+++ b/raddict.h
-@@ -0,0 +1,42 @@
-+#ifndef _RADDICT_H
-+#define _RADDICT_H
-+
-+const char* RAD_Attr_Acct_Terminate_Cause_Dict[] = {
-+        [1] = "User-Request",
-+        "Lost-Carrier",
-+        "Lost-Service",
-+        "Idle-Timeout",
-+        "Session-Timeout",
-+        "Admin-Reset",
-+        "Admin-Reboot",
-+        "Port-Error",
-+        "NAS-Error",
-+        "NAS-Request",
-+        "NAS-Reboot",
-+        "Port-Unneeded",
-+        "Port-Preempted",
-+        "Port-Suspended",
-+        "Service-Unavailable",
-+        "Callback",
-+        "User-Error",
-+        "Host-Request",
-+};
-+
-+const char* RAD_Attr_Acct_Status_Type_Dict[] = {
-+        [1] = "Start",
-+        [2] = "Stop",
-+        [3] = "Interim-Update",
-+        [7] = "Accounting-On",
-+        [8] = "Accounting-Off",
-+        [9] = "Tunnel-Start",
-+        [10] = "Tunnel-Stop",
-+        [11] = "Tunnel-Reject",
-+        [12] = "Tunnel-Link-Start",
-+        [13] = "Tunnel-Link-Stop",
-+        [14] = "Tunnel-Link-Reject",
-+        [15] = "Failed",
-+};
-+
-+#define RAD_Attr_Dict_Undef "UNKNOWN"
-+
-+#endif /*_RADDICT_H*/
-diff --git a/radmsg.c b/radmsg.c
-index 5f49237..afd7c60 100644
---- a/radmsg.c
-+++ b/radmsg.c
-@@ -15,6 +15,8 @@
- #include <pthread.h>
- #include <nettle/hmac.h>
- #include <openssl/rand.h>
-+#include "raddict.h"
-+#include "util.h"
- 
- #define RADLEN(x) ntohs(((uint16_t *)(x))[1])
- 
-@@ -414,6 +416,28 @@ int resizeattr(struct tlv *attr, uint8_t newlen) {
-     return 0;
- }
- 
-+const char* attrval2strdict(struct tlv *attr) {
-+    uint32_t val;
-+
-+    if(!attr) return NULL;
-+    val = tlv2longint(attr);
-+    switch (attr->t) {
-+        case RAD_Attr_Acct_Status_Type:
-+            if(val < sizeof(RAD_Attr_Acct_Status_Type_Dict)/sizeof(RAD_Attr_Acct_Status_Type_Dict[0]))
-+                return RAD_Attr_Acct_Status_Type_Dict[val] ? RAD_Attr_Acct_Status_Type_Dict[val] : RAD_Attr_Dict_Undef;
-+            break;
-+
-+        case RAD_Attr_Acct_Terminate_Cause:
-+            if(val < sizeof(RAD_Attr_Acct_Terminate_Cause_Dict)/sizeof(RAD_Attr_Acct_Terminate_Cause_Dict[0]))
-+                return RAD_Attr_Acct_Terminate_Cause_Dict[val] ? RAD_Attr_Acct_Terminate_Cause_Dict[val] : RAD_Attr_Dict_Undef;
-+            break;
-+
-+        default:
-+            break;
-+    }
-+    return NULL;
-+}
-+
- /* Local Variables: */
- /* c-file-style: "stroustrup" */
- /* End: */
-diff --git a/radmsg.h b/radmsg.h
-index 1738c8e..634cf13 100644
---- a/radmsg.h
-+++ b/radmsg.h
-@@ -21,16 +21,37 @@
- #define RAD_Attr_User_Name 1
- #define RAD_Attr_User_Password 2
- #define RAD_Attr_CHAP_Password 3
-+#define RAD_Attr_NAS_IP_Address 4
-+#define RAD_Attr_Framed_IP_Address 8
- #define RAD_Attr_Reply_Message 18
- #define RAD_Attr_Vendor_Specific 26
-+#define RAD_Attr_Called_Station_Id 30
- #define RAD_Attr_Calling_Station_Id 31
- #define RAD_Attr_Proxy_State 33
-+#define RAD_Attr_Acct_Status_Type 40
-+#define RAD_Attr_Acct_Input_Octets 42
-+#define RAD_Attr_Acct_Output_Octets 43
-+#define RAD_Attr_Acct_Session_Id 44
-+#define RAD_Attr_Acct_Session_Time 46
-+#define RAD_Attr_Acct_Input_Packets 47
-+#define RAD_Attr_Acct_Output_Packets 48
-+#define RAD_Attr_Acct_Terminate_Cause 49
-+#define RAD_Attr_Event_Timestamp 55
- #define RAD_Attr_CHAP_Challenge 60
- #define RAD_Attr_Tunnel_Password 69
- #define RAD_Attr_Message_Authenticator 80
- #define RAD_Attr_CUI 89
- #define RAD_Attr_Operator_Name 126
- 
-+#define RAD_Acct_Status_Start 1
-+#define RAD_Acct_Status_Stop 2
-+#define RAD_Acct_Status_Alive 3
-+#define RAD_Acct_Status_Interim_Update 3
-+#define RAD_Acct_Status_Accounting_On 7
-+#define RAD_Acct_Status_Accounting_Off 8
-+#define RAD_Acct_Status_Failed 15
-+
-+
- #define RAD_VS_ATTR_MS_MPPE_Send_Key 16
- #define RAD_VS_ATTR_MS_MPPE_Recv_Key 17
- 
-@@ -63,6 +84,16 @@ int attrvalidate(unsigned char *attrs, int length);
- struct tlv *makevendortlv(uint32_t vendor, struct tlv *attr);
- int resizeattr(struct tlv *attr, uint8_t newlen);
- 
-+/**
-+ * convert the attribute value to its string representation form the dictionary 
-+ * (see raddict.h)
-+ * 
-+ * @param attr the attribute to convert
-+ * @return the string representation or NULL, if the attribute/value is not in the 
-+ * dictionary
-+ */
-+const char* attrval2strdict(struct tlv *attr);
-+
- #endif /*_RADMSG_H*/
- 
- /* Local Variables: */
-diff --git a/radsecproxy.c b/radsecproxy.c
-index c755acb..75f5ef3 100644
---- a/radsecproxy.c
-+++ b/radsecproxy.c
-@@ -121,13 +121,13 @@ int prefixmatch(void *a1, void *a2, uint8_t len) {
- }
- 
- /* returns next config with matching address, or NULL */
--struct clsrvconf *find_conf(uint8_t type, struct sockaddr *addr, struct list *confs, struct list_node **cur, uint8_t server_p) {
-+struct clsrvconf *find_conf(uint8_t type, struct sockaddr *addr, struct list *confs, struct list_node **cur, uint8_t server_p, struct hostportres **hp) {
-     struct list_node *entry;
-     struct clsrvconf *conf;
- 
-     for (entry = (cur && *cur ? list_next(*cur) : list_first(confs)); entry; entry = list_next(entry)) {
- 	conf = (struct clsrvconf *)entry->data;
--	if (conf->type == type && addressmatches(conf->hostports, addr, server_p)) {
-+	if (conf->type == type && addressmatches(conf->hostports, addr, server_p, hp)) {
- 	    if (cur)
- 		*cur = entry;
- 	    return conf;
-@@ -136,12 +136,12 @@ struct clsrvconf *find_conf(uint8_t type, struct sockaddr *addr, struct list *co
-     return NULL;
- }
- 
--struct clsrvconf *find_clconf(uint8_t type, struct sockaddr *addr, struct list_node **cur) {
--    return find_conf(type, addr, clconfs, cur, 0);
-+struct clsrvconf *find_clconf(uint8_t type, struct sockaddr *addr, struct list_node **cur, struct hostportres **hp) {
-+    return find_conf(type, addr, clconfs, cur, 0, hp);
- }
- 
- struct clsrvconf *find_srvconf(uint8_t type, struct sockaddr *addr, struct list_node **cur) {
--    return find_conf(type, addr, srvconfs, cur, 1);
-+    return find_conf(type, addr, srvconfs, cur, 1, NULL);
- }
- 
- /* returns next config of given type, or NULL */
-@@ -1241,6 +1241,49 @@ void rmclientrq(struct request *rq, uint8_t id) {
-     }
- }
- 
-+static void log_accounting_resp(struct client *from, struct radmsg *msg, char *user) {
-+    char tmp[INET6_ADDRSTRLEN];
-+    const char* status_type = attrval2strdict(radmsg_gettype(msg, RAD_Attr_Acct_Status_Type));
-+    char* nas_ip_address = tlv2ipv4addr(radmsg_gettype(msg, RAD_Attr_NAS_IP_Address));
-+    char* framed_ip_address = tlv2ipv4addr(radmsg_gettype(msg, RAD_Attr_Framed_IP_Address));
-+
-+    time_t event_timestamp_i = tlv2longint(radmsg_gettype(msg, RAD_Attr_Event_Timestamp));
-+    char event_timestamp[32]; /* timestamp should be at most 21 bytes, leave a few spare */
-+
-+    uint8_t *session_id = radattr2ascii(radmsg_gettype(msg, RAD_Attr_Acct_Session_Id));
-+    uint8_t *called_station_id = radattr2ascii(radmsg_gettype(msg, RAD_Attr_Called_Station_Id));
-+    uint8_t *calling_station_id = radattr2ascii(radmsg_gettype(msg, RAD_Attr_Calling_Station_Id));
-+    const char* terminate_cause = attrval2strdict(radmsg_gettype(msg, RAD_Attr_Acct_Terminate_Cause));
-+
-+    strftime(event_timestamp, sizeof(event_timestamp), "%FT%TZ", gmtime(&event_timestamp_i));
-+
-+    debug(DBG_NOTICE, "Accounting %s (id %d) at %s from client %s (%s): { SID=%s, User-Name=%s, Ced-S-Id=%s, Cing-S-Id=%s, NAS-IP=%s, Framed-IP=%s, Sess-Time=%u, In-Packets=%u, In-Octets=%u, Out-Packets=%u, Out-Octets=%u, Terminate-Cause=%s }",
-+        status_type ? status_type : "UNKNOWN",
-+        msg->id,
-+        event_timestamp_i ? event_timestamp : "UNKNOWN",
-+        from->conf->name,
-+        addr2string(from->addr, tmp, sizeof(tmp)),
-+
-+        session_id ? session_id : (uint8_t*)"",
-+        user,
-+        called_station_id ? called_station_id : (uint8_t*)"",
-+        calling_station_id ? calling_station_id : (uint8_t*)"",
-+        nas_ip_address ? nas_ip_address : "0.0.0.0",
-+        framed_ip_address ? framed_ip_address : "0.0.0.0",
-+        tlv2longint(radmsg_gettype(msg, RAD_Attr_Acct_Session_Time)),
-+        tlv2longint(radmsg_gettype(msg, RAD_Attr_Acct_Input_Packets)),
-+        tlv2longint(radmsg_gettype(msg, RAD_Attr_Acct_Input_Octets)),
-+        tlv2longint(radmsg_gettype(msg, RAD_Attr_Acct_Output_Packets)),
-+        tlv2longint(radmsg_gettype(msg, RAD_Attr_Acct_Output_Octets)),
-+        terminate_cause ? terminate_cause : ""
-+    );
-+    free(framed_ip_address);
-+    free(nas_ip_address);
-+    free(session_id);
-+    free(called_station_id);
-+    free(calling_station_id);
-+}
-+
- /* Called from server readers, handling incoming requests from
-  * clients. */
- /* returns 0 if validation/authentication fails, else 1 */
-@@ -1321,13 +1364,15 @@ int radsrv(struct request *rq) {
-     }
- 
-     if (!to) {
--	if (realm->message && msg->code == RAD_Access_Request) {
--	    debug(DBG_INFO, "radsrv: sending %s (id %d) to %s (%s) for %s", radmsgtype2string(RAD_Access_Reject), msg->id, from->conf->name, addr2string(from->addr, tmp, sizeof(tmp)), userascii);
--	    respond(rq, RAD_Access_Reject, realm->message, 1, 1);
--	} else if (realm->accresp && msg->code == RAD_Accounting_Request) {
--	    respond(rq, RAD_Accounting_Response, NULL, 1, 0);
--	}
--	goto exit;
-+        if (realm->message && msg->code == RAD_Access_Request) {
-+            debug(DBG_INFO, "radsrv: sending %s (id %d) to %s (%s) for %s", radmsgtype2string(RAD_Access_Reject), msg->id, from->conf->name, addr2string(from->addr, tmp, sizeof(tmp)), userascii);
-+            respond(rq, RAD_Access_Reject, realm->message, 1, 1);
-+        } else if (realm->accresp && msg->code == RAD_Accounting_Request) {
-+            if (realm->acclog) 
-+                log_accounting_resp(from, msg, (char *)userascii);
-+            respond(rq, RAD_Accounting_Response, NULL, 1, 0);
-+        }
-+        goto exit;
-     }
- 
-     if ((to->conf->loopprevention == 1
-@@ -1592,7 +1637,7 @@ void *clientwr(void *arg) {
-     if (server->dynamiclookuparg && !dynamicconfig(server)) {
-         dynconffail = 1;
-         server->state = RSP_SERVER_STATE_FAILING;
--        debug(DBG_WARN, "%s: dynamicconfig(%s: %s) failed, sleeping %ds",
-+        debug(DBG_WARN, "%s: dynamicconfig(%s: %s) failed, Not trying again for %ds",
-               __func__, server->conf->name, server->dynamiclookuparg, ZZZ);
-         goto errexitwait;
-     }
-@@ -1600,7 +1645,7 @@ void *clientwr(void *arg) {
-      * either as part of static configuration setup or by
-      * dynamicconfig() above?  */
-     if (!resolvehostports(conf->hostports, conf->hostaf, conf->pdef->socktype)) {
--        debug(DBG_WARN, "%s: resolve failed, sleeping %ds", __func__, ZZZ);
-+        debug(DBG_WARN, "%s: resolve failed, Not trying again for %ds", __func__, ZZZ);
-         server->state = RSP_SERVER_STATE_FAILING;
-         goto errexitwait;
-     }
-@@ -1615,7 +1660,7 @@ void *clientwr(void *arg) {
-         if (!conf->pdef->connecter(server, server->dynamiclookuparg ? 5 : 0, "clientwr")) {
-             server->state = RSP_SERVER_STATE_FAILING;
-             if (server->dynamiclookuparg) {
--                debug(DBG_WARN, "%s: connect failed, sleeping %ds", __func__, ZZZ);
-+                debug(DBG_WARN, "%s: connect failed, giving up. Not trying again for %ds", __func__, ZZZ);
-                 goto errexitwait;
-             }
-             goto errexit;
-@@ -1927,7 +1972,7 @@ void freerealm(struct realm *realm) {
-     free(realm);
- }
- 
--struct realm *addrealm(struct list *realmlist, char *value, char **servers, char **accservers, char *message, uint8_t accresp) {
-+struct realm *addrealm(struct list *realmlist, char *value, char **servers, char **accservers, char *message, uint8_t accresp, uint8_t acclog) {
-     int n;
-     struct realm *realm;
-     char *s, *regex = NULL;
-@@ -1991,6 +2036,7 @@ struct realm *addrealm(struct list *realmlist, char *value, char **servers, char
-     }
-     realm->message = message;
-     realm->accresp = accresp;
-+    realm->acclog = acclog;
- 
-     if (regcomp(&realm->regex, regex ? regex : value + 1, REG_EXTENDED | REG_ICASE | REG_NOSUB)) {
- 	debug(DBG_ERR, "addrealm: failed to compile regular expression %s", regex ? regex : value + 1);
-@@ -2111,7 +2157,7 @@ struct realm *adddynamicrealmserver(struct realm *realm, char *id) {
-     if (!realm->subrealms)
- 	return NULL;
- 
--    newrealm = addrealm(realm->subrealms, realmname, NULL, NULL, stringcopy(realm->message, 0), realm->accresp);
-+    newrealm = addrealm(realm->subrealms, realmname, NULL, NULL, stringcopy(realm->message, 0), realm->accresp, realm->acclog);
-     if (!newrealm) {
- 	list_destroy(realm->subrealms);
- 	realm->subrealms = NULL;
-@@ -2223,6 +2269,7 @@ void freeclsrvconf(struct clsrvconf *conf) {
-     freematchcertattr(conf);
-     free(conf->confrewritein);
-     free(conf->confrewriteout);
-+    free(conf->sniservername);
-     if (conf->rewriteusername) {
- 	if (conf->rewriteusername->regex)
- 	    regfree(conf->rewriteusername->regex);
-@@ -2316,7 +2363,8 @@ int mergesrvconf(struct clsrvconf *dst, struct clsrvconf *src) {
- 	!mergeconfstring(&dst->confrewriteusername, &src->confrewriteusername) ||
- 	!mergeconfstring(&dst->dynamiclookupcommand, &src->dynamiclookupcommand) ||
- 	!mergeconfstring(&dst->fticks_viscountry, &src->fticks_viscountry) ||
--	!mergeconfstring(&dst->fticks_visinst, &src->fticks_visinst))
-+	!mergeconfstring(&dst->fticks_visinst, &src->fticks_visinst) ||
-+    !mergeconfstring(&dst->sniservername, &src->sniservername))
- 	return 0;
-     if (src->pdef)
- 	dst->pdef = src->pdef;
-@@ -2327,6 +2375,7 @@ int mergesrvconf(struct clsrvconf *dst, struct clsrvconf *src) {
-     if (src->retrycount != 255)
- 	dst->retrycount = src->retrycount;
-     dst->blockingstartup = src->blockingstartup;
-+    dst->sni = src->sni;
-     return 1;
- }
- 
-@@ -2416,7 +2465,7 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
-                 ? tlsgettls(conf->tls, NULL)
-                 : tlsgettls("defaultClient", "default");
-         if (!conf->tlsconf)
--            debugx(1, DBG_ERR, "error in block %s, no tls context defined", block);
-+            debugx(1, DBG_ERR, "error in block %s, tls context not defined", block);
-         if (matchcertattrs) {
-             for (i=0; matchcertattrs[i]; i++){
-                 if (!addmatchcertattr(conf, matchcertattrs[i])) {
-@@ -2485,7 +2534,7 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
-                 existing->tlsconf != conf->tlsconf &&
-                 hostportmatches(existing->hostports, conf->hostports, 0)) {
- 
--                debugx(1, DBG_ERR, "error in block %s, overlapping clients must reference the same tls block", block);
-+                debugx(1, DBG_ERR, "error in block %s, masked by overlapping (equal or less specific IP/prefix) client %s with different tls block", block, existing->name);
-             }
-         }
-     }
-@@ -2573,8 +2622,12 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
-     if (resconf) {
-         conf->statusserver = resconf->statusserver;
-         conf->certnamecheck = resconf->certnamecheck;
-+        conf->blockingstartup = resconf->blockingstartup;
-+        conf->type = resconf->type;
-+        conf->sni = resconf->sni;
-     } else {
-         conf->certnamecheck = 1;
-+        conf->sni = options.sni;
-     }
- 
-     if (!getgenericconfig(cf, block,
-@@ -2601,6 +2654,8 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
-             "DynamicLookupCommand", CONF_STR, &conf->dynamiclookupcommand,
-             "LoopPrevention", CONF_BLN, &conf->loopprevention,
-             "BlockingStartup", CONF_BLN, &conf->blockingstartup,
-+            "SNI", CONF_BLN, &conf->sni,
-+            "SNIservername", CONF_STR, &conf->sniservername,
-             NULL
- 	    )) {
- 	debug(DBG_ERR, "configuration error");
-@@ -2621,16 +2676,20 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
-     }
- 
-     if (!conftype) {
--	debug(DBG_ERR, "error in block %s, option type missing", block);
--	goto errexit;
--    }
--    conf->type = protoname2int(conftype);
--    if (conf->type == 255) {
--	debug(DBG_ERR, "error in block %s, unknown transport %s", block, conftype);
--	goto errexit;
-+        if (!resconf) {
-+            debug(DBG_ERR, "error in block %s, option type missing", block);
-+            goto errexit;
-+        }
-+    } else {
-+        conf->type = protoname2int(conftype);
-+        if (conf->type == 255) {
-+            debug(DBG_ERR, "error in block %s, unknown transport %s", block, conftype);
-+            goto errexit;
-+        }
-+        free(conftype);
-+        conftype = NULL;
-+        conf->pdef = protodefs[conf->type];
-     }
--    free(conftype);
--    conftype = NULL;
- 
-     conf->hostaf = AF_UNSPEC;
-     if (config_hostaf("top level", options.ipv4only, options.ipv6only, &conf->hostaf))
-@@ -2638,8 +2697,6 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
-     if (config_hostaf(block, ipv4only, ipv6only, &conf->hostaf))
-         goto errexit;
- 
--    conf->pdef = protodefs[conf->type];
--
-     if (!conf->confrewritein)
- 	conf->confrewritein = rewriteinalias;
-     else
-@@ -2683,8 +2740,12 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
-             conf->statusserver = RSP_STATSRV_AUTO;
-         else
-             debugx(1, DBG_ERR, "config error in blocck %s: invalid StatusServer value: %s", block, statusserver);
-+        free(statusserver);
-     }
- 
-+    if(conf->sniservername)
-+        conf->sni = 1;
-+
-     if (resconf) {
-         if (!mergesrvconf(resconf, conf))
-             goto errexit;
-@@ -2769,7 +2830,7 @@ int confrewrite_cb(struct gconffile **cf, void *arg, char *block, char *opt, cha
- 
- int confrealm_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) {
-     char **servers = NULL, **accservers = NULL, *msg = NULL;
--    uint8_t accresp = 0;
-+    uint8_t accresp = 0, acclog = 0;
- 
-     debug(DBG_DBG, "confrealm_cb called for %s", block);
- 
-@@ -2778,11 +2839,12 @@ int confrealm_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
- 			  "accountingServer", CONF_MSTR, &accservers,
- 			  "ReplyMessage", CONF_STR, &msg,
- 			  "AccountingResponse", CONF_BLN, &accresp,
-+              "AccountingLog", CONF_BLN, &acclog,
- 			  NULL
- 	    ))
- 	debugx(1, DBG_ERR, "configuration error");
- 
--    addrealm(realms, val, servers, accservers, msg, accresp);
-+    addrealm(realms, val, servers, accservers, msg, accresp, acclog);
-     return 1;
- }
- 
-@@ -2871,6 +2933,7 @@ void getmainconfig(const char *configfile) {
-         "FTicksPrefix", CONF_STR, &options.fticksprefix,
-         "IPv4Only", CONF_BLN, &options.ipv4only,
-         "IPv6Only", CONF_BLN, &options.ipv6only,
-+        "SNI", CONF_BLN, &options.sni,
- 	    NULL
- 	    ))
- 	debugx(1, DBG_ERR, "configuration error");
-@@ -3031,6 +3094,7 @@ int createpidfile(const char *pidfile) {
- int radsecproxy_main(int argc, char **argv) {
-     pthread_t sigth;
-     sigset_t sigset;
-+    size_t stacksize;
-     struct list_node *entry;
-     uint8_t foreground = 0, pretend = 0, loglevel = 0;
-     char *configfile = NULL, *pidfile = NULL;
-@@ -3042,8 +3106,13 @@ int radsecproxy_main(int argc, char **argv) {
- 
-     if (pthread_attr_init(&pthread_attr))
- 	debugx(1, DBG_ERR, "pthread_attr_init failed");
--    if (pthread_attr_setstacksize(&pthread_attr, PTHREAD_STACK_SIZE))
--	debugx(1, DBG_ERR, "pthread_attr_setstacksize failed");
-+#if defined(PTHREAD_STACK_MIN)
-+    stacksize = THREAD_STACK_SIZE > PTHREAD_STACK_MIN ? THREAD_STACK_SIZE : PTHREAD_STACK_MIN;
-+#else
-+    stacksize = THREAD_STACK_SIZE;
-+#endif
-+    if (pthread_attr_setstacksize(&pthread_attr, stacksize))
-+        debug(DBG_WARN, "pthread_attr_setstacksize failed! Using system default. Memory footprint might be increased!");
- #if defined(HAVE_MALLOPT)
-     if (mallopt(M_TRIM_THRESHOLD, 4 * 1024) != 1)
- 	debugx(1, DBG_ERR, "mallopt failed");
-diff --git a/radsecproxy.conf-example b/radsecproxy.conf-example
-index 1730e55..3b2dd64 100644
---- a/radsecproxy.conf-example
-+++ b/radsecproxy.conf-example
-@@ -203,6 +203,8 @@ server radius.example.com {
- # statusserver is optional, can be on or off. Off is default
- 	tcpKeepalive on
- # tcp and tls connections also support TCP keepalives.
-+# Optionally specify the SNI for the outgoing connection
-+#       sni www.example.com
- }
- #server radius.example.com {
- #	type	dtls
-diff --git a/radsecproxy.conf.5.in b/radsecproxy.conf.5.in
-index 87482c1..ebedd6c 100644
---- a/radsecproxy.conf.5.in
-+++ b/radsecproxy.conf.5.in
-@@ -297,6 +297,15 @@ clients and servers. At most one of IPv4Only and IPv6Only can be enabled.
- Note that this can be overridden in client and server blocks, see below.
- .RE
- 
-+.BR "SNI (" on | off )
-+.RS
-+Server Name Indication (SNI) is an extension to the TLS protocol.  It allows a
-+client to indicate which hostname it is trying to connect to at the start of
-+the TLS handshake. Enabling this will use the extension for all TLS and DTLS
-+servers which specify a hostname (not IP address). This can be overridden in 
-+server blocks, see below.
-+.RE
-+
- .BI "Include " file
- .RS
- This is not a normal configuration option; it can be specified multiple times.
-@@ -350,10 +359,11 @@ this might mask clients defined later, which then will never be matched.
- 
- In the case of TLS/DTLS, the name of the client must match the FQDN or IP
- address in the client certificate (CN or SubectAltName:DNS or SubjectAltName:IP
--respectively). Note that this is not required when the client name is an IP
--prefix. If overlapping clients are defined (see section above), they will be
--searched for matching \fBMatchCertificateAttribute\fR, but they must reference
--the same tls block.
-+respectively) and any \fBMatchCertificateAttribute\fR to be positively identified. 
-+Note that no FQDN/IP is checked when using an IP prefix. 
-+If overlapping clients are defined (see section above), they will be searched for 
-+positive identification, but only among clients referencing the same tls block
-+(selected by the first matching IP address or prefix).
- 
- The allowed options in a client block are:
- 
-@@ -620,6 +630,19 @@ Warning: when the dynamic lookup and connection process is slow, this wil block
- respective realm for that time.
- .RE
- 
-+.BR "SNI (" on | off )
-+
-+.RS
-+Override gobal SNI setting (see above). This is implicitly enabled if \fBSNIservername\fR
-+is set.
-+.RE
-+
-+.BI "SNIservername " sni
-+.RS
-+Explicitly set the \fIsni\fR to request from the server, in case the server is specified
-+by IP address or to override the hostname. Implicitly enables \fBSNI\fR for this server.
-+.RE
-+
- The meaning and syntax of the following options are exactly the same as for the client
- block. The details are not repeated here. Please refer to the definitions in the \fBCLIENT BLOCK\fR section.
- 
-@@ -679,6 +702,12 @@ Enable sending Accounting-Response instead of ignoring Accounting-Requests when
- no \fBaccoutingServer\fR are configured.
- .RE
- 
-+.BR "AccountingLog (" on | off )
-+.RS
-+When responding to Accounting-Requests (\fBAccountingResponse on\fR), log the 
-+accounting data.
-+.RE
-+
- .BI "ReplyMessage " message
- .RS
- Specify a message to be sent back to the client if a Access-Request is denied
-@@ -852,7 +881,8 @@ for DTLS.
- .BI "DhFile " file
- .RS
- DH parameter \fIfile\fR to use. See \fBopenssl-dhparam\fR(1)
--
-+.br
-+Note: starting with OpenSSL 3.0, use of custom DH parameters is discouraged.
- 
- .SH "REWRITE BLOCK"
- .nf
-diff --git a/radsecproxy.h b/radsecproxy.h
-index cf493b4..8844415 100644
---- a/radsecproxy.h
-+++ b/radsecproxy.h
-@@ -11,6 +11,7 @@
- #include "radmsg.h"
- #include "gconfig.h"
- #include "rewrite.h"
-+#include "hostport.h"
- 
- #include <openssl/asn1.h>
- 
-@@ -28,15 +29,9 @@
- #define STATUS_SERVER_PERIOD 25
- #define IDLE_TIMEOUT 300
- 
--/* We want PTHREAD_STACK_SIZE to be 32768, but some platforms
-- * have a higher minimum value defined in PTHREAD_STACK_MIN. */
--#define PTHREAD_STACK_SIZE 32768
--#if defined(PTHREAD_STACK_MIN)
--#if PTHREAD_STACK_MIN > PTHREAD_STACK_SIZE
--#undef PTHREAD_STACK_SIZE
--#define PTHREAD_STACK_SIZE PTHREAD_STACK_MIN
--#endif
--#endif
-+/* Target value for stack size.
-+ * Some platforms might define higher minimums in PTHREAD_STACK_MIN. */
-+#define THREAD_STACK_SIZE 32768
- 
- /* For systems that only support RFC 2292 Socket API, but not RFC 3542
-  * like Cygwin */
-@@ -103,6 +98,7 @@ struct options {
-     uint8_t *fticks_key;
-     uint8_t ipv4only;
-     uint8_t ipv6only;
-+    uint8_t sni;
- };
- 
- struct commonprotoopts {
-@@ -176,6 +172,8 @@ struct clsrvconf {
-     struct server *servers;
-     char *fticks_viscountry;
-     char *fticks_visinst;
-+    uint8_t sni;
-+    char *sniservername;
- };
- 
- #include "tlscommon.h"
-@@ -216,6 +214,7 @@ struct realm {
-     char *name;
-     char *message;
-     uint8_t accresp;
-+    uint8_t acclog;
-     regex_t regex;
-     uint32_t refcount;
-     pthread_mutex_t refmutex;
-@@ -250,7 +249,7 @@ struct protodefs {
- 
- #define RADLEN(x) ntohs(((uint16_t *)(x))[1])
- 
--struct clsrvconf *find_clconf(uint8_t type, struct sockaddr *addr, struct list_node **cur);
-+struct clsrvconf *find_clconf(uint8_t type, struct sockaddr *addr, struct list_node **cur, struct hostportres **hp);
- struct clsrvconf *find_srvconf(uint8_t type, struct sockaddr *addr, struct list_node **cur);
- struct clsrvconf *find_clconf_type(uint8_t type, struct list_node **cur);
- struct client *addclient(struct clsrvconf *conf, uint8_t lock);
-diff --git a/tcp.c b/tcp.c
-index ffb2f4c..e148ed0 100644
---- a/tcp.c
-+++ b/tcp.c
-@@ -22,6 +22,7 @@
- #include <pthread.h>
- #include "radsecproxy.h"
- #include "hostport.h"
-+#include "list.h"
- 
- #ifdef RADPROT_TCP
- #include "debug.h"
-@@ -84,6 +85,8 @@ int tcpconnect(struct server *server, int timeout, char *text) {
-     int firsttry = 1;
-     time_t wait;
-     struct addrinfo *source = NULL;
-+    struct list_node *entry;
-+    struct hostportres *hp;
- 
-     debug(DBG_DBG, "tcpconnect: called from %s", text);
-     pthread_mutex_lock(&server->lock);
-@@ -112,16 +115,25 @@ int tcpconnect(struct server *server, int timeout, char *text) {
-             if (source) freeaddrinfo(source);
-             return 0;
-         }
--        debug(DBG_INFO, "Next connection attempt to %s in %lds", server->conf->name, wait);
-+        if (wait) debug(DBG_INFO, "Next connection attempt to %s in %lds", server->conf->name, wait);
-         sleep(wait);
-         firsttry = 0;
- 
--        
-         pthread_mutex_lock(&server->lock);
- 
--        debug(DBG_INFO, "tcpconnect: connecting to %s", server->conf->name);
--        if ((server->sock = connecttcphostlist(server->conf->hostports, source ? source : srcres)) < 0)
-+        for (entry = list_first(server->conf->hostports); entry; entry = list_next(entry)) {
-+            hp = (struct hostportres *)entry->data;
-+            debug(DBG_INFO, "tcpconnect: trying to open TCP connection to server %s (%s port %s)", server->conf->name, hp->host, hp->port);
-+            if ((server->sock = connecttcp(hp->addrinfo, source ? source : srcres, list_count(server->conf->hostports) > 1 ? 5 : 30)) >= 0) {
-+                debug(DBG_WARN, "tcpconnect: TCP connection to server %s (%s port %s) up", hp->host, hp->port);
-+                break;
-+            }
-+        }
-+        if (server->sock < 0) {
-+            debug(DBG_ERR, "tcpconnect: TCP connection to server %s failed", server->conf->name);
-             continue;
-+        }
-+
-         if (server->conf->keepalive)
-             enable_keepalive(server->sock);
-         break;
-@@ -339,7 +351,7 @@ void *tcpservernew(void *arg) {
-     }
-     debug(DBG_WARN, "tcpservernew: incoming TCP connection from %s", addr2string((struct sockaddr *)&from, tmp, sizeof(tmp)));
- 
--    conf = find_clconf(handle, (struct sockaddr *)&from, NULL);
-+    conf = find_clconf(handle, (struct sockaddr *)&from, NULL, NULL);
-     if (conf) {
-         client = addclient(conf, 1);
-         if (client) {
-diff --git a/tests/t_verify_cert.c b/tests/t_verify_cert.c
-index ca0d47e..b52a990 100644
---- a/tests/t_verify_cert.c
-+++ b/tests/t_verify_cert.c
-@@ -234,7 +234,7 @@ vY/uPjA=\n\
-         hp.prefixlen = 255;
-         list_push(conf.hostports, &hp);
- 
--        ok(1, verifyconfcert(certsimple, &conf), "check disabled");
-+        ok(1, verifyconfcert(certsimple, &conf, &hp), "check disabled");
- 
-         while(list_shift(conf.hostports));
-     }
-@@ -249,7 +249,7 @@ vY/uPjA=\n\
-         hp.prefixlen = 0;
-         list_push(conf.hostports, &hp);
- 
--        ok(1,verifyconfcert(certsimple, &conf),"cidr prefix");
-+        ok(1,verifyconfcert(certsimple, &conf, &hp),"cidr prefix");
- 
-         while(list_shift(conf.hostports));
-     }
-@@ -264,11 +264,11 @@ vY/uPjA=\n\
-         hp.prefixlen = 255;
-         list_push(conf.hostports, &hp);
- 
--        ok(1,verifyconfcert(certsimple, &conf), "simple cert cn");
--        ok(0,verifyconfcert(certsimpleother, &conf), "negative simple cert cn");
-+        ok(1,verifyconfcert(certsimple, &conf, &hp), "simple cert cn");
-+        ok(0,verifyconfcert(certsimpleother, &conf, &hp), "negative simple cert cn");
- 
-         /* as per RFC 6125 6.4.4: CN MUST NOT be matched if SAN is present */
--        ok(0,verifyconfcert(certsandns, &conf), "simple cert cn vs san dns, RFC6125");
-+        ok(0,verifyconfcert(certsandns, &conf, &hp), "simple cert cn vs san dns, RFC6125");
- 
-         while(list_shift(conf.hostports));
-     }
-@@ -284,11 +284,11 @@ vY/uPjA=\n\
-         hp.prefixlen = 255;
-         list_push(conf.hostports, &hp);
- 
--        ok(1,verifyconfcert(certsanip, &conf),"san ip");
--        ok(0,verifyconfcert(certsanipother, &conf),"wrong san ip");
--        ok(0,verifyconfcert(certsimple, &conf), "negative san ip");
--        ok(1,verifyconfcert(certsanipindns, &conf),"san ip in dns");
--        ok(1,verifyconfcert(certcomplex,&conf),"san ip in complex cert");
-+        ok(1,verifyconfcert(certsanip, &conf, &hp),"san ip");
-+        ok(0,verifyconfcert(certsanipother, &conf, &hp),"wrong san ip");
-+        ok(0,verifyconfcert(certsimple, &conf, &hp), "negative san ip");
-+        ok(1,verifyconfcert(certsanipindns, &conf, &hp),"san ip in dns");
-+        ok(1,verifyconfcert(certcomplex,&conf, &hp),"san ip in complex cert");
- 
-         freeaddrinfo(hp.addrinfo);
-         while(list_shift(conf.hostports));
-@@ -306,11 +306,11 @@ vY/uPjA=\n\
-         hp.prefixlen = 255;
-         list_push(conf.hostports, &hp);
- 
--        ok(1,verifyconfcert(certsanipv6, &conf),"san ipv6");
--        ok(0,verifyconfcert(certsanipother, &conf),"wrong san ipv6");
--        ok(0,verifyconfcert(certsimple, &conf),"negative san ipv6");
--        ok(1,verifyconfcert(certsanipv6indns, &conf),"san ipv6 in dns");
--        ok(1,verifyconfcert(certcomplex,&conf),"san ipv6 in complex cert");
-+        ok(1,verifyconfcert(certsanipv6, &conf, &hp),"san ipv6");
-+        ok(0,verifyconfcert(certsanipother, &conf, &hp),"wrong san ipv6");
-+        ok(0,verifyconfcert(certsimple, &conf, &hp),"negative san ipv6");
-+        ok(1,verifyconfcert(certsanipv6indns, &conf, &hp),"san ipv6 in dns");
-+        ok(1,verifyconfcert(certcomplex,&conf, &hp),"san ipv6 in complex cert");
- 
-         freeaddrinfo(hp.addrinfo);
-         while(list_shift(conf.hostports));
-@@ -326,10 +326,10 @@ vY/uPjA=\n\
-         hp.prefixlen = 255;
-         list_push(conf.hostports, &hp);
- 
--        ok(1,verifyconfcert(certsandns, &conf),"san dns");
--        ok(0,verifyconfcert(certsandnsother, &conf),"negative san dns");
--        ok(1,verifyconfcert(certcomplex,&conf),"san dns in complex cert");
--        ok(0,verifyconfcert(certsimple, &conf),"missing san dns");
-+        ok(1,verifyconfcert(certsandns, &conf, &hp),"san dns");
-+        ok(0,verifyconfcert(certsandnsother, &conf, &hp),"negative san dns");
-+        ok(1,verifyconfcert(certcomplex,&conf, &hp),"san dns in complex cert");
-+        ok(0,verifyconfcert(certsimple, &conf, &hp),"missing san dns");
- 
-         while(list_shift(conf.hostports));
-     }
-@@ -347,8 +347,8 @@ vY/uPjA=\n\
-         hp2.prefixlen = 255;
-         list_push(conf.hostports, &hp2);
- 
--        ok(1,verifyconfcert(certsimple, &conf),"multi hostport cn");
--        ok(0,verifyconfcert(certsimpleother, &conf),"negative multi hostport cn");
-+        ok(1,verifyconfcert(certsimple, &conf, NULL),"multi hostport cn");
-+        ok(0,verifyconfcert(certsimpleother, &conf, NULL),"negative multi hostport cn");
- 
-         while(list_shift(conf.hostports));
-     }
-@@ -366,9 +366,14 @@ vY/uPjA=\n\
-         hp2.prefixlen = 255;
-         list_push(conf.hostports, &hp2);
- 
--        ok(1,verifyconfcert(certsandns, &conf),"multi hostport san dns");
--        ok(0,verifyconfcert(certsandnsother, &conf),"negative multi hostport san dns");
--        ok(1,verifyconfcert(certcomplex,&conf),"multi hostport san dns in complex cert");
-+        ok(1,verifyconfcert(certsandns, &conf, NULL),"multi hostport san dns");
-+        ok(0,verifyconfcert(certsandnsother, &conf, NULL),"negative multi hostport san dns");
-+        ok(1,verifyconfcert(certcomplex,&conf, NULL),"multi hostport san dns in complex cert");
-+
-+        ok(0,verifyconfcert(certsandns, &conf, &hp1),"multi hostport explicit wrong cert");
-+        ok(1,verifyconfcert(certsandns, &conf, &hp2),"multi hostport explicit matching cert");
-+        ok(0,verifyconfcert(certcomplex, &conf, &hp1),"multi hostport explicit wrong complex cert");
-+        ok(1,verifyconfcert(certcomplex, &conf, &hp2),"multi hostport explicit matching complex cert");
- 
-         while(list_shift(conf.hostports));
-     }
-@@ -380,9 +385,9 @@ vY/uPjA=\n\
- 
-         ok(1,addmatchcertattr(&conf, "CN:/t..t/"),"explicit cn regex config");
- 
--        ok(1,verifyconfcert(certsimple, &conf),"explicit cn regex");
--        ok(0,verifyconfcert(certsimpleother, &conf),"negative explicit cn regex");
--        ok(1,verifyconfcert(certsandns, &conf), "explicit cn regex with SAN DNS");
-+        ok(1,verifyconfcert(certsimple, &conf, NULL),"explicit cn regex");
-+        ok(0,verifyconfcert(certsimpleother, &conf, NULL),"negative explicit cn regex");
-+        ok(1,verifyconfcert(certsandns, &conf, NULL), "explicit cn regex with SAN DNS");
- 
-         freematchcertattr(&conf);
-     }
-@@ -394,10 +399,10 @@ vY/uPjA=\n\
- 
-         ok(1,addmatchcertattr(&conf, "SubjectAltName:IP:192.0.2.1"),"explicit san ip config");
- 
--        ok(1,verifyconfcert(certsanip, &conf),"explicit san ip");
--        ok(0,verifyconfcert(certsanipother, &conf),"wrong explicit san ip");
--        ok(0,verifyconfcert(certsimple, &conf), "missing explicit san ip");
--        ok(1,verifyconfcert(certcomplex,&conf),"explicit san ip in complex cert");
-+        ok(1,verifyconfcert(certsanip, &conf, NULL),"explicit san ip");
-+        ok(0,verifyconfcert(certsanipother, &conf, NULL),"wrong explicit san ip");
-+        ok(0,verifyconfcert(certsimple, &conf, NULL), "missing explicit san ip");
-+        ok(1,verifyconfcert(certcomplex,&conf, NULL),"explicit san ip in complex cert");
- 
-         freematchcertattr(&conf);
-     }
-@@ -409,10 +414,10 @@ vY/uPjA=\n\
- 
-         ok(1,addmatchcertattr(&conf, "SubjectAltName:IP:2001:db8::1"),"explicit san ipv6 config");
- 
--        ok(1,verifyconfcert(certsanipv6, &conf),"explicit san ipv6");
--        ok(0,verifyconfcert(certsanipother, &conf),"wrong explicit san ipv6");
--        ok(0,verifyconfcert(certsimple, &conf),"missing explicitsan ipv6");
--        ok(1,verifyconfcert(certcomplex,&conf),"explicit san ipv6 in complex cert");
-+        ok(1,verifyconfcert(certsanipv6, &conf, NULL),"explicit san ipv6");
-+        ok(0,verifyconfcert(certsanipother, &conf, NULL),"wrong explicit san ipv6");
-+        ok(0,verifyconfcert(certsimple, &conf, NULL),"missing explicitsan ipv6");
-+        ok(1,verifyconfcert(certcomplex,&conf, NULL),"explicit san ipv6 in complex cert");
- 
-         freematchcertattr(&conf);
-     }
-@@ -424,10 +429,10 @@ vY/uPjA=\n\
- 
-         ok(1,addmatchcertattr(&conf, "SubjectAltName:DNS:/t..t\\.local/"),"explicit san dns regex config");
- 
--        ok(1,verifyconfcert(certsandns, &conf),"explicit san dns");
--        ok(0,verifyconfcert(certsandnsother, &conf),"negative explicit san dns");
--        ok(0,verifyconfcert(certsimple,&conf),"missing explicit san dns");
--        ok(1,verifyconfcert(certcomplex,&conf),"explicit san dns in complex cert");
-+        ok(1,verifyconfcert(certsandns, &conf, NULL),"explicit san dns");
-+        ok(0,verifyconfcert(certsandnsother, &conf, NULL),"negative explicit san dns");
-+        ok(0,verifyconfcert(certsimple,&conf, NULL),"missing explicit san dns");
-+        ok(1,verifyconfcert(certcomplex,&conf, NULL),"explicit san dns in complex cert");
- 
-         freematchcertattr(&conf);
-     }
-@@ -439,9 +444,9 @@ vY/uPjA=\n\
- 
-         ok(1,addmatchcertattr(&conf, "SubjectAltName:URI:/https:\\/\\/test.local\\/profile#me/"),"explicit cn regex config");
- 
--        ok(1,verifyconfcert(certsanuri, &conf),"explicit san uri regex");
--        ok(0,verifyconfcert(certsanuriother, &conf),"negative explicit san uri");
--        ok(0,verifyconfcert(certsimple, &conf), "missing explicit san uri");
-+        ok(1,verifyconfcert(certsanuri, &conf, NULL),"explicit san uri regex");
-+        ok(0,verifyconfcert(certsanuriother, &conf, NULL),"negative explicit san uri");
-+        ok(0,verifyconfcert(certsimple, &conf, NULL), "missing explicit san uri");
- 
-         freematchcertattr(&conf);
-     }
-@@ -453,9 +458,9 @@ vY/uPjA=\n\
- 
-         ok(1,addmatchcertattr(&conf, "SubjectAltName:rID:1.2.3.4"),"explicit san rid config");
- 
--        ok(1,verifyconfcert(certsanrid, &conf),"explicit san rid");
--        ok(0,verifyconfcert(certsanridother, &conf),"negative explicit san rid");
--        ok(0,verifyconfcert(certsimple, &conf), "missing explicit san rid");
-+        ok(1,verifyconfcert(certsanrid, &conf, NULL),"explicit san rid");
-+        ok(0,verifyconfcert(certsanridother, &conf, NULL),"negative explicit san rid");
-+        ok(0,verifyconfcert(certsimple, &conf, NULL), "missing explicit san rid");
- 
-         freematchcertattr(&conf);
-     }
-@@ -467,9 +472,9 @@ vY/uPjA=\n\
- 
-         ok(1,addmatchcertattr(&conf, "SubjectAltName:otherName:1.3.6.1.5.5.7.8.8:/test.local/"),"explicit san otherName config");
- 
--        ok(1,verifyconfcert(certsanothername, &conf),"explicit san otherName");
--        ok(0,verifyconfcert(certsanothernameother, &conf),"negative explicit san otherName");
--        ok(0,verifyconfcert(certsimple, &conf), "missing explicit san otherName");
-+        ok(1,verifyconfcert(certsanothername, &conf, NULL),"explicit san otherName");
-+        ok(0,verifyconfcert(certsanothernameother, &conf, NULL),"negative explicit san otherName");
-+        ok(0,verifyconfcert(certsimple, &conf, NULL), "missing explicit san otherName");
- 
-         freematchcertattr(&conf);
-     }
-@@ -480,7 +485,7 @@ vY/uPjA=\n\
-         conf.certnamecheck = 0;
- 
-         ok(1,addmatchcertattr(&conf, "CN:/t..t"),"test regex config syntax");
--        ok(1,verifyconfcert(certsimple, &conf),"test regex config syntax execution");
-+        ok(1,verifyconfcert(certsimple, &conf, NULL),"test regex config syntax execution");
- 
-         freematchcertattr(&conf);
-     }
-@@ -518,10 +523,10 @@ vY/uPjA=\n\
- 
-         ok(1,addmatchcertattr(&conf, "CN:/t..t"),"combined config");
- 
--        ok(1,verifyconfcert(certsandns, &conf),"combined san dns");
--        ok(0,verifyconfcert(certsandnsother, &conf),"negative combined san dns");
--        ok(1,verifyconfcert(certcomplex,&conf),"combined san dns in complex cert");
--        ok(0,verifyconfcert(certsimple, &conf),"combined missing san dns");
-+        ok(1,verifyconfcert(certsandns, &conf, &hp),"combined san dns");
-+        ok(0,verifyconfcert(certsandnsother, &conf, &hp),"negative combined san dns");
-+        ok(1,verifyconfcert(certcomplex,&conf, &hp),"combined san dns in complex cert");
-+        ok(0,verifyconfcert(certsimple, &conf, &hp),"combined missing san dns");
- 
-         while(list_shift(conf.hostports));
-         freematchcertattr(&conf);
-@@ -540,12 +545,12 @@ vY/uPjA=\n\
-         ok(1,addmatchcertattr(&conf, "SubjectAltName:DNS:/test\\.local/"),"multiple check 1");
-         ok(1,addmatchcertattr(&conf, "SubjectAltName:rID:1.2.3.4"),"multiple check 2");
- 
--        ok(0,verifyconfcert(certsandns, &conf),"multiple missing rID");
--        ok(0,verifyconfcert(certsanrid, &conf), "multiple missing DNS");
--        ok(1,verifyconfcert(certmulti, &conf),"multiple SANs");
--        ok(0,verifyconfcert(certmultiother, &conf),"multiple negative match");
--        ok(0,verifyconfcert(certcomplex, &conf),"multiple missing rID in complex cert");
--        ok(0,verifyconfcert(certsimple, &conf),"multiple missing everything");
-+        ok(0,verifyconfcert(certsandns, &conf, &hp),"multiple missing rID");
-+        ok(0,verifyconfcert(certsanrid, &conf, &hp), "multiple missing DNS");
-+        ok(1,verifyconfcert(certmulti, &conf, &hp),"multiple SANs");
-+        ok(0,verifyconfcert(certmultiother, &conf, &hp),"multiple negative match");
-+        ok(0,verifyconfcert(certcomplex, &conf, &hp),"multiple missing rID in complex cert");
-+        ok(0,verifyconfcert(certsimple, &conf, &hp),"multiple missing everything");
- 
-         while(list_shift(conf.hostports));
-         freematchcertattr(&conf);
-diff --git a/tls.c b/tls.c
-index 87bbe2c..049f3a9 100644
---- a/tls.c
-+++ b/tls.c
-@@ -23,11 +23,11 @@
- #include <assert.h>
- #include "radsecproxy.h"
- #include "hostport.h"
--
--#ifdef RADPROT_TLS
- #include "debug.h"
- #include "util.h"
- 
-+#ifdef RADPROT_TLS
-+
- static void setprotoopts(struct commonprotoopts *opts);
- static char **getlistenerargs();
- void *tlslistener(void *arg);
-@@ -82,6 +82,17 @@ void tlssetsrcres() {
-                                    AF_UNSPEC, NULL, protodefs.socktype);
- }
- 
-+static void cleanup_connection(struct server *server) {
-+    if (server->ssl)
-+        SSL_shutdown(server->ssl);
-+    if (server->sock >= 0)
-+        close(server->sock);
-+    server->sock = -1;
-+    if (server->ssl)
-+        SSL_free(server->ssl);
-+    server->ssl = NULL;
-+}
-+
- int tlsconnect(struct server *server, int timeout, char *text) {
-     struct timeval now, start;
-     time_t wait;
-@@ -92,6 +103,8 @@ int tlsconnect(struct server *server, int timeout, char *text) {
-     int origflags;
-     struct addrinfo *source = NULL;
-     char *subj;
-+    struct list_node *entry;
-+    struct hostportres *hp;
- 
-     debug(DBG_DBG, "tlsconnect: called from %s", text);
-     pthread_mutex_lock(&server->lock);
-@@ -108,15 +121,7 @@ int tlsconnect(struct server *server, int timeout, char *text) {
-     gettimeofday(&start, NULL);
- 
-     for (;;) {
--        /* ensure previous connection is properly closed */
--        if (server->ssl)
--            SSL_shutdown(server->ssl);
--        if (server->sock >= 0)
--            close(server->sock);
--        if (server->ssl)
--            SSL_free(server->ssl);
--        server->ssl = NULL;
--
-+        cleanup_connection(server);
-         wait = connect_wait(start, server->connecttime, firsttry);
-         gettimeofday(&now, NULL);
-         if (timeout && (now.tv_sec - start.tv_sec) + wait > timeout) {
-@@ -124,7 +129,7 @@ int tlsconnect(struct server *server, int timeout, char *text) {
-             if (source) freeaddrinfo(source);
-             return 0;
-         }
--        debug(DBG_INFO, "Next connection attempt to %s in %lds", server->conf->name, wait);
-+        if (wait) debug(DBG_INFO, "Next connection attempt to %s in %lds", server->conf->name, wait);
-         sleep(wait);
-         firsttry = 0;
- 
-@@ -135,46 +140,76 @@ int tlsconnect(struct server *server, int timeout, char *text) {
-             return 0;
-         }
- 
--        debug(DBG_INFO, "tlsconnect: connecting to %s", server->conf->name);
--        if ((server->sock = connecttcphostlist(server->conf->hostports, source ? source : srcres)) < 0)
--            continue;
--        if (server->conf->keepalive)
--            enable_keepalive(server->sock);
-+        for (entry = list_first(server->conf->hostports); entry; entry = list_next(entry)) {
-+            hp = (struct hostportres *)entry->data;
-+            debug(DBG_INFO, "tlsconnect: trying to open TLS connection to server %s (%s port %s)", server->conf->name, hp->host, hp->port);
-+            if ((server->sock = connecttcp(hp->addrinfo, source ? source : srcres, list_count(server->conf->hostports) > 1 ? 5 : 30)) < 0 ) {
-+                debug(DBG_ERR, "tlsconnect: TLS connection to %s (%s port %s) failed: TCP connect failed", server->conf->name, hp->host, hp->port);
-+                goto concleanup;
-+            }
-+
-+            if (server->conf->keepalive)
-+                enable_keepalive(server->sock);
-+
-+            pthread_mutex_lock(&server->conf->tlsconf->lock);
-+            if (!(ctx = tlsgetctx(handle, server->conf->tlsconf))) {
-+                pthread_mutex_unlock(&server->conf->tlsconf->lock);
-+                debug(DBG_ERR, "tlsconnect: failed to get TLS context for server %s", server->conf->name);
-+                goto concleanup;
-+            }
- 
--        pthread_mutex_lock(&server->conf->tlsconf->lock);
--        if (!(ctx = tlsgetctx(handle, server->conf->tlsconf))){
-+            server->ssl = SSL_new(ctx);
-             pthread_mutex_unlock(&server->conf->tlsconf->lock);
--            continue;
--        }
-+            if (!server->ssl) {
-+                debug(DBG_ERR, "tlsconnect: failed to create SSL conneciton for server %s", server->conf->name);
-+                goto concleanup;
-+            }
- 
--        server->ssl = SSL_new(ctx);
--        pthread_mutex_unlock(&server->conf->tlsconf->lock);
--        if (!server->ssl)
--            continue;
-+            if (server->conf->sni) {
-+                struct in6_addr tmp;
-+                char *servername = server->conf->sniservername ? server->conf->sniservername : 
-+                    (inet_pton(AF_INET, hp->host, &tmp) || inet_pton(AF_INET6, hp->host, &tmp)) ? NULL : hp->host;
-+                if (servername && !tlssetsni(server->ssl, servername)) {
-+                    debug(DBG_ERR, "tlsconnect: set SNI %s failed", servername);
-+                    goto concleanup;
-+                }
-+            }
-+            
-+            SSL_set_fd(server->ssl, server->sock);
-+            if (sslconnecttimeout(server->ssl, 5) <= 0) {
-+                while ((error = ERR_get_error()))
-+                    debug(DBG_ERR, "tlsconnect: SSL connect to %s failed: %s", server->conf->name, ERR_error_string(error, NULL));
-+                debug(DBG_ERR, "tlsconnect: SSL connect to %s (%s port %s) failed", server->conf->name, hp->host, hp->port);
-+                goto concleanup;
-+            }
- 
--        SSL_set_fd(server->ssl, server->sock);
--        if (sslconnecttimeout(server->ssl, 5) <= 0) {
--            while ((error = ERR_get_error()))
--                debug(DBG_ERR, "tlsconnect: SSL connect to %s failed: %s", server->conf->name, ERR_error_string(error, NULL));
--            debug(DBG_ERR, "tlsconnect: SSL connect to %s failed", server->conf->name);
--            continue;
--        }
-+            cert = verifytlscert(server->ssl);
-+            if (!cert) {
-+                debug(DBG_ERR, "tlsconnect: certificate verification failed for %s (%s port %s)", server->conf->name, hp->host, hp->port);
-+                goto concleanup;
-+            }
- 
--        cert = verifytlscert(server->ssl);
--        if (!cert)
--            continue;
--        if (verifyconfcert(cert, server->conf)) {
--            subj = getcertsubject(cert);
--            if(subj) {
--                debug(DBG_WARN, "tlsconnect: TLS connection to %s, subject %s up", server->conf->name, subj);
--                free(subj);
-+            if (verifyconfcert(cert, server->conf, hp)) {
-+                subj = getcertsubject(cert);
-+                if(subj) {
-+                    debug(DBG_WARN, "tlsconnect: TLS connection to %s (%s port %s), subject %s, %s with cipher %s up",
-+                        server->conf->name, hp->host, hp->port, subj,
-+                        SSL_get_version(server->ssl), SSL_CIPHER_get_name(SSL_get_current_cipher(server->ssl)));
-+                    free(subj);
-+                }
-+                X509_free(cert);
-+                break;
-+            } else {
-+                debug(DBG_ERR, "tlsconnect: certificate verification failed for %s (%s port %s)", server->conf->name, hp->host, hp->port);
-             }
-             X509_free(cert);
--            break;
-+
-+concleanup:
-+            /* ensure previous connection is properly closed */
-+            cleanup_connection(server);
-         }
--        X509_free(cert);
-+        if (server->ssl) break;
-     }
--    debug(DBG_WARN, "tlsconnect: TLS connection to %s up", server->conf->name);
- 
-     origflags = fcntl(server->sock, F_GETFL, 0);
-     if (origflags == -1) {
-@@ -251,6 +286,7 @@ int sslreadtimeout(SSL *ssl, unsigned char *buf, int num, int timeout, pthread_m
-                     continue;
-                 case SSL_ERROR_ZERO_RETURN:
-                     debug(DBG_DBG, "sslreadtimeout: got ssl shutdown");
-+                    /* fallthrough */
-                 default:
-                     while ((error = ERR_get_error()))
-                         debug(DBG_ERR, "sslreadtimeout: SSL: %s", ERR_error_string(error, NULL));
-@@ -505,6 +541,7 @@ void *tlsservernew(void *arg) {
-     struct client *client;
-     struct tls *accepted_tls = NULL;
-     char tmp[INET6_ADDRSTRLEN], *subj;
-+    struct hostportres *hp;
- 
-     s = *(int *)arg;
-     free(arg);
-@@ -514,7 +551,7 @@ void *tlsservernew(void *arg) {
-     }
-     debug(DBG_WARN, "tlsservernew: incoming TLS connection from %s", addr2string((struct sockaddr *)&from, tmp, sizeof(tmp)));
- 
--    conf = find_clconf(handle, (struct sockaddr *)&from, &cur);
-+    conf = find_clconf(handle, (struct sockaddr *)&from, &cur, &hp);
-     if (conf) {
-         pthread_mutex_lock(&conf->tlsconf->lock);
-         ctx = tlsgetctx(handle, conf->tlsconf);
-@@ -549,11 +586,12 @@ void *tlsservernew(void *arg) {
-     }
- 
-     while (conf) {
--        if (accepted_tls == conf->tlsconf && verifyconfcert(cert, conf)) {
-+        if (accepted_tls == conf->tlsconf && verifyconfcert(cert, conf, NULL)) {
-             subj = getcertsubject(cert);
-             if(subj) {
--                debug(DBG_WARN, "tlsservernew: TLS connection from %s, client %s, subject %s up",
--                    addr2string((struct sockaddr *)&from,tmp, sizeof(tmp)), conf->name, subj);
-+                debug(DBG_WARN, "tlsservernew: TLS connection from %s, client %s, subject %s, %s with cipher %s up",
-+                    addr2string((struct sockaddr *)&from,tmp, sizeof(tmp)), conf->name, subj,
-+                    SSL_get_version(ssl), SSL_CIPHER_get_name(SSL_get_current_cipher(ssl)));
-                 free(subj);
-             }
-             X509_free(cert);
-@@ -569,9 +607,10 @@ void *tlsservernew(void *arg) {
-                 debug(DBG_WARN, "tlsservernew: failed to create new client instance");
-             goto exit;
-         }
--        conf = find_clconf(handle, (struct sockaddr *)&from, &cur);
-+        conf = find_clconf(handle, (struct sockaddr *)&from, &cur, &hp);
-     }
--    debug(DBG_WARN, "tlsservernew: ignoring request, no matching TLS client");
-+    debug(DBG_WARN, "tlsservernew: ignoring request, no matching TLS client for %s", 
-+        addr2string((struct sockaddr *)&from, tmp, sizeof(tmp)));
-     if (cert)
- 	X509_free(cert);
- 
-diff --git a/tlscommon.c b/tlscommon.c
-index 0bd7da4..2dc0f48 100644
---- a/tlscommon.c
-+++ b/tlscommon.c
-@@ -492,12 +492,26 @@ static SSL_CTX *tlscreatectx(uint8_t type, struct tls *conf) {
- #endif
- 
-     if (conf->dhparam) {
-+#if OPENSSL_VERSION_NUMBER >= 0x30000000
-+        if (!SSL_CTX_set0_tmp_dh_pkey(ctx, conf->dhparam)) {
-+#else
-         if (!SSL_CTX_set_tmp_dh(ctx, conf->dhparam)) {
-+#endif
-             while ((error = ERR_get_error()))
-                 debug(DBG_WARN, "tlscreatectx: SSL: %s", ERR_error_string(error, NULL));
-             debug(DBG_WARN, "tlscreatectx: Failed to set dh params. Can continue, but some ciphers might not be available.");
-         }
-     }
-+#if OPENSSL_VERSION_NUMBER >= 0x10100000
-+    else {
-+        if (!SSL_CTX_set_dh_auto(ctx, 1)) {
-+            while ((error = ERR_get_error()))
-+                debug(DBG_WARN, "tlscreatectx: SSL: %s", ERR_error_string(error, NULL));
-+            debug(DBG_WARN, "tlscreatectx: Failed to set automatic dh params. Can continue, but some ciphers might not be available.");
-+        }
-+    }
-+#endif
-+
-     debug(DBG_DBG, "tlscreatectx: created TLS context %s", conf->name);
-     return ctx;
- }
-@@ -506,7 +520,7 @@ struct tls *tlsgettls(char *alt1, char *alt2) {
-     struct tls *t;
- 
-     t = hash_read(tlsconfs, alt1, strlen(alt1));
--    if (!t)
-+    if (!t && alt2)
- 	t = hash_read(tlsconfs, alt2, strlen(alt2));
-     return t;
- }
-@@ -711,64 +725,67 @@ static int matchsubjaltname(X509 *cert, struct certattrmatch* match) {
-     }
- 
-     if (r<1)
--        debug(DBG_WARN, "matchsubjaltname: no matching Subject Alt Name found! (%s)", fail);
-+        debug(DBG_DBG, "matchsubjaltname: no matching Subject Alt Name found! (%s)", fail);
-     free(fail);
- 
-     GENERAL_NAMES_free(alt);
-     return r;
- }
- 
--int certnamecheck(X509 *cert, struct list *hostports) {
--    struct list_node *entry;
--    struct hostportres *hp;
-+int certnamecheck(X509 *cert, struct hostportres *hp) {
-     int r = 0;
-     struct certattrmatch match;
- 
-     memset(&match, 0, sizeof(struct certattrmatch));
- 
--    for (entry = list_first(hostports); entry; entry = list_next(entry)) {
--        r = 0;
--        hp = (struct hostportres *)entry->data;
--        if (hp->prefixlen != 255) {
--            /* we disable the check for prefixes */
-+    r = 0;
-+    if (hp->prefixlen != 255) {
-+        /* we disable the check for prefixes */
-+        return 1;
-+    }
-+    if (inet_pton(AF_INET, hp->host, &match.ipaddr))
-+        match.af = AF_INET;
-+    else if (inet_pton(AF_INET6, hp->host, &match.ipaddr))
-+        match.af = AF_INET6;
-+    else
-+        match.af = 0;
-+    match.exact = hp->host;
-+
-+    if (match.af) {
-+        match.matchfn = &certattr_matchip;
-+        match.type = GEN_IPADD;
-+        r = matchsubjaltname(cert, &match);
-+    }
-+    if (!r) {
-+        match.matchfn = &certattr_matchregex;
-+        match.type = GEN_DNS;
-+        r = matchsubjaltname(cert, &match);
-+    }
-+    if (r) {
-+        if (r > 0) {
-+            debug(DBG_DBG, "certnamecheck: Found subjectaltname matching %s %s", match.af ? "address" : "host", hp->host);
-             return 1;
-         }
--        if (inet_pton(AF_INET, hp->host, &match.ipaddr))
--            match.af = AF_INET;
--        else if (inet_pton(AF_INET6, hp->host, &match.ipaddr))
--            match.af = AF_INET6;
--        else
--            match.af = 0;
--        match.exact = hp->host;
--
--        if (match.af) {
--            match.matchfn = &certattr_matchip;
--            match.type = GEN_IPADD;
--            r = matchsubjaltname(cert, &match);
--        }
--        if (!r) {
--            match.matchfn = &certattr_matchregex;
--            match.type = GEN_DNS;
--            r = matchsubjaltname(cert, &match);
--        }
--        if (r) {
--            if (r > 0) {
--                debug(DBG_DBG, "certnamecheck: Found subjectaltname matching %s %s", match.af ? "address" : "host", hp->host);
--                return 1;
--            }
--            debug(DBG_WARN, "certnamecheck: No subjectaltname matching %s %s", match.af ? "address" : "host", hp->host);
--        } else {
--            if (certattr_matchcn(cert, &match)) {
--                debug(DBG_DBG, "certnamecheck: Found cn matching host %s", hp->host);
--                return 1;
--            }
--            debug(DBG_WARN, "certnamecheck: cn not matching host %s", hp->host);
-+        debug(DBG_WARN, "certnamecheck: No subjectaltname matching %s %s", match.af ? "address" : "host", hp->host);
-+    } else { /* as per RFC 6125 6.4.4: CN MUST NOT be matched if SAN is present */
-+        if (certattr_matchcn(cert, &match)) {
-+            debug(DBG_DBG, "certnamecheck: Found cn matching host %s", hp->host);
-+            return 1;
-         }
-+        debug(DBG_WARN, "certnamecheck: cn not matching host %s", hp->host);
-     }
-     return 0;
- }
- 
--int verifyconfcert(X509 *cert, struct clsrvconf *conf) {
-+int certnamecheckany(X509 *cert, struct list *hostports) {
-+    struct list_node *entry;
-+    for (entry = list_first(hostports); entry; entry = list_next(entry)) {
-+        if (certnamecheck(cert, (struct hostportres *)entry->data)) return 1;
-+    }
-+    return 0;
-+}
-+
-+int verifyconfcert(X509 *cert, struct clsrvconf *conf, struct hostportres *hpconnected) {
-     char *subject;
-     int ok = 1;
-     struct list_node *entry;
-@@ -777,9 +794,16 @@ int verifyconfcert(X509 *cert, struct clsrvconf *conf) {
-     debug(DBG_DBG, "verifyconfcert: verify certificate for host %s, subject %s", conf->name, subject);
-     if (conf->certnamecheck) {
-         debug(DBG_DBG, "verifyconfcert: verify hostname");
--        if (!certnamecheck(cert, conf->hostports)) {
--            debug(DBG_DBG, "verifyconfcert: certificate name check failed for host %s", conf->name);
--            ok = 0;
-+        if (hpconnected) {
-+            if (!certnamecheck(cert, hpconnected)) {
-+                debug(DBG_WARN, "verifyconfcert: certificate name check failed for host %s (%s)", conf->name, hpconnected->host);
-+                ok = 0;
-+            }
-+        } else {
-+            if (!certnamecheckany(cert, conf->hostports)) {
-+                debug(DBG_DBG, "verifyconfcert: no matching CN or SAN found for host %s", conf->name);
-+                ok = 0;
-+            }
-         }
-     }
- 
-@@ -913,11 +937,27 @@ int conftls_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *v
-         dtlsversion = NULL;
-     }
- #else
-+    if (tlsversion || dtlsversion) {
-         debug(DBG_ERR, "error in block %s, setting tls/dtls version requires openssl 1.1.0 or later", val);
-         goto errexit;
-+    }
- #endif
- 
-     if (dhfile) {
-+#if OPENSSL_VERSION_NUMBER >= 0x30000000
-+        BIO *bio = BIO_new_file(dhfile, "r");
-+        if (bio) {
-+            conf->dhparam = EVP_PKEY_new();
-+            if (!PEM_read_bio_Parameters(bio, &conf->dhparam)) {
-+                BIO_free(bio);
-+                while ((error = ERR_get_error()))
-+                    debug(DBG_ERR, "SSL: %s", ERR_error_string(error, NULL));
-+                debug(DBG_ERR, "error in block %s: Failed to load DhFile %s.", val, dhfile);
-+                goto errexit;
-+            }
-+            BIO_free(bio);
-+        }
-+#else
-         FILE *dhfp = fopen(dhfile, "r");
-         if (dhfp) {
-             conf->dhparam = PEM_read_DHparams(dhfp, NULL, NULL, NULL);
-@@ -934,6 +974,7 @@ int conftls_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *v
-         }
-         free(dhfile);
-         dhfile = NULL;
-+#endif
-     }
- 
-     conf->name = stringcopy(val, 0);
-@@ -964,7 +1005,11 @@ errexit:
-     free(tlsversion);
-     free(dtlsversion);
-     free(dhfile);
-+#if OPENSSL_VERSION_NUMBER >= 0x30000000
-+    EVP_PKEY_free(conf->dhparam);
-+#else
-     DH_free(conf->dhparam);
-+#endif
-     free(conf);
-     return 0;
- }
-@@ -1091,6 +1136,10 @@ void freematchcertattr(struct clsrvconf *conf) {
-     }
- }
- 
-+int tlssetsni(SSL *ssl, char *sni) {
-+    return SSL_set_tlsext_host_name(ssl, sni); 
-+}
-+
- int sslaccepttimeout (SSL *ssl, int timeout) {
-     int socket, origflags, ndesc, r = -1, sockerr = 0;
-     socklen_t errlen = sizeof(sockerr);
-diff --git a/tlscommon.h b/tlscommon.h
-index 6be9079..1006626 100644
---- a/tlscommon.h
-+++ b/tlscommon.h
-@@ -3,6 +3,7 @@
- /* See LICENSE for licensing information. */
- 
- #include <openssl/ssl.h>
-+#include "hostport.h"
- 
- #if OPENSSL_VERSION_NUMBER < 0x10100000L
- #define ASN1_STRING_get0_data(o) ((o)->data)
-@@ -25,7 +26,11 @@ struct tls {
-     int tlsmaxversion;
-     int dtlsminversion;
-     int dtlsmaxversion;
-+#if OPENSSL_VERSION_NUMBER >= 0x30000000
-+    EVP_PKEY* dhparam;
-+#else
-     DH *dhparam;
-+#endif
-     uint32_t tlsexpiry;
-     uint32_t dtlsexpiry;
-     X509_VERIFY_PARAM *vpm;
-@@ -40,12 +45,13 @@ void sslinit();
- struct tls *tlsgettls(char *alt1, char *alt2);
- SSL_CTX *tlsgetctx(uint8_t type, struct tls *t);
- X509 *verifytlscert(SSL *ssl);
--int verifyconfcert(X509 *cert, struct clsrvconf *conf);
-+int verifyconfcert(X509 *cert, struct clsrvconf *conf, struct hostportres *);
- char *getcertsubject(X509 *cert);
- int conftls_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val);
- int addmatchcertattr(struct clsrvconf *conf, const char *match);
- void freematchcertattr(struct clsrvconf *conf);
- void tlsreloadcrls();
-+int tlssetsni(SSL *ssl, char *sni);
- int sslconnecttimeout(SSL *ssl, int timeout);
- int sslaccepttimeout (SSL *ssl, int timeout);
- #endif
-diff --git a/tlv11.c b/tlv11.c
-index d570b39..9eaf6d9 100644
---- a/tlv11.c
-+++ b/tlv11.c
-@@ -12,6 +12,7 @@
- #include <stdlib.h>
- #include <string.h>
- #include <arpa/inet.h>
-+#include <stdio.h>
- 
- struct tlv *maketlv(uint8_t t, uint8_t l, void *v) {
-     struct tlv *tlv;
-@@ -97,6 +98,8 @@ void rmtlv(struct list *tlvs, uint8_t t) {
- }
- 
- uint8_t *tlv2str(struct tlv *tlv) {
-+    if(!tlv)
-+        return NULL;
-     uint8_t *s = malloc(tlv->l + 1);
-     if (s) {
- 	memcpy(s, tlv->v, tlv->l);
-@@ -117,6 +120,28 @@ struct tlv *resizetlv(struct tlv *tlv, uint8_t newlen) {
-     return tlv;
- }
- 
-+uint32_t tlv2longint(struct tlv *tlv) {
-+    if (!tlv) return 0;
-+    if (tlv->l != sizeof(uint32_t)) return 0;
-+    return ntohl(*(uint32_t *)tlv->v);
-+}
-+
-+char* tlv2ipv4addr(struct tlv *tlv) {
-+    char *result;
-+
-+    if (!tlv) return NULL;
-+    if (tlv->l != sizeof(in_addr_t)) return NULL;
-+
-+    result = malloc(INET_ADDRSTRLEN);
-+    if (!result) return NULL;
-+
-+    if (!inet_ntop(AF_INET, tlv->v, result, INET_ADDRSTRLEN)) {
-+        free(result);
-+        return NULL;
-+    }
-+    return result;
-+}
-+
- /* Local Variables: */
- /* c-file-style: "stroustrup" */
- /* End: */
-diff --git a/tlv11.h b/tlv11.h
-index 84db3d7..c565d13 100644
---- a/tlv11.h
-+++ b/tlv11.h
-@@ -17,6 +17,8 @@ void freetlvlist(struct list *);
- void rmtlv(struct list *, uint8_t);
- uint8_t *tlv2str(struct tlv *tlv);
- struct tlv *resizetlv(struct tlv *, uint8_t);
-+uint32_t tlv2longint(struct tlv *tlv);
-+char* tlv2ipv4addr(struct tlv *tlv);
- 
- /* Local Variables: */
- /* c-file-style: "stroustrup" */
-diff --git a/tools/naptr-eduroam.sh b/tools/naptr-eduroam.sh
-index 5402d18..2f90601 100755
---- a/tools/naptr-eduroam.sh
-+++ b/tools/naptr-eduroam.sh
-@@ -14,7 +14,6 @@ usage() {
- 
- test -n "${1}" || usage
- 
--REALM="${1}"
- DIGCMD=$(command -v dig)
- HOSTCMD=$(command -v host)
- PRINTCMD=$(command -v printf)
-@@ -38,7 +37,7 @@ dig_it_srv() {
- }
- 
- dig_it_naptr() {
--    ${DIGCMD} +short naptr ${REALM} | grep x-eduroam:radius.tls | sort -n -k1 |
-+    ${DIGCMD} +short naptr "${REALM}" | grep x-eduroam:radius.tls | sort -n -k1 |
-     while read line; do
-         set $line ; TYPE=$3 ; HOST=$(validate_host $6)
-         if ( [ "$TYPE" = "\"s\"" ] || [ "$TYPE" = "\"S\"" ] ) && [ -n "${HOST}" ]; then
-@@ -59,7 +58,7 @@ host_it_srv() {
- }
- 
- host_it_naptr() {
--    ${HOSTCMD} -t naptr ${REALM} | grep x-eduroam:radius.tls | sort -n -k5 |
-+    ${HOSTCMD} -t naptr "${REALM}" | grep x-eduroam:radius.tls | sort -n -k5 |
-     while read line; do
-         set $line ; TYPE=$7 ; HOST=$(validate_host ${10})
-         if ( [ "$TYPE" = "\"s\"" ] || [ "$TYPE" = "\"S\"" ] ) && [ -n "${HOST}" ]; then
-@@ -69,6 +68,12 @@ host_it_naptr() {
-     done
- }
- 
-+REALM=$(validate_host ${1})
-+if [ -z "${REALM}" ]; then
-+    echo "Error: realm \"${1}\" failed validation"
-+    usage
-+fi
-+
- if [ -x "${DIGCMD}" ]; then
-     SERVERS=$(dig_it_naptr)
- elif [ -x "${HOSTCMD}" ]; then
-@@ -79,7 +84,7 @@ else
- fi
- 
- if [ -n "${SERVERS}" ]; then
--    $PRINTCMD "server dynamic_radsec.${REALM} {\n${SERVERS}\n\ttype TLS\n}\n"
-+    $PRINTCMD "server dynamic_radsec.${REALM} {\n${SERVERS}\n}\n"
-     exit 0
- fi
- 
-diff --git a/tools/radsec-dynsrv.sh b/tools/radsec-dynsrv.sh
-index 68bb5ba..d8318ed 100755
---- a/tools/radsec-dynsrv.sh
-+++ b/tools/radsec-dynsrv.sh
-@@ -14,7 +14,6 @@ usage() {
- 
- test -n "${1}" || usage
- 
--REALM="${1}"
- DIGCMD=$(command -v digaaa)
- HOSTCMD=$(command -v host)
- PRINTCMD=$(command -v printf)
-@@ -28,7 +27,7 @@ validate_port() {
- }
- 
- dig_it() {
--   ${DIGCMD} +short srv _radsec._tcp.${REALM} | sort -n -k1 |
-+   ${DIGCMD} +short srv "_radsec._tcp.${REALM}" | sort -n -k1 |
-    while read line ; do
-       set $line ; PORT=$(validate_port $3) ; HOST=$(validate_host $4)
-       if [ -n "${HOST}" ] && [ -n "${PORT}" ]; then 
-@@ -38,7 +37,7 @@ dig_it() {
- }
- 
- host_it() {
--   ${HOSTCMD} -t srv _radsec._tcp.${REALM} | sort -n -k5 |
-+   ${HOSTCMD} -t srv "_radsec._tcp.${REALM}" | sort -n -k5 |
-    while read line ; do
-       set $line ; PORT=$(validate_port $7) ; HOST=$(validate_host $8) 
-       if [ -n "${HOST}" ] && [ -n "${PORT}" ]; then
-@@ -47,6 +46,12 @@ host_it() {
-    done
- }
- 
-+REALM=$(validate_host ${1})
-+if test -z "${REALM}" ; then
-+    echo "Error: realm \"${1}\" failed validation"
-+    usage
-+fi
-+
- if test -x "${DIGCMD}" ; then
-    SERVERS=$(dig_it)
- elif test -x "${HOSTCMD}" ; then
-@@ -57,7 +62,7 @@ else
- fi
- 
- if test -n "${SERVERS}" ; then
--        $PRINTCMD "server dynamic_radsec.${REALM} {\n${SERVERS}\n\ttype TLS\n}\n"
-+        $PRINTCMD "server dynamic_radsec.${REALM} {\n${SERVERS}\n}\n"
-         exit 0
- fi
- 
-diff --git a/udp.c b/udp.c
-index e3e1464..6e86fbe 100644
---- a/udp.c
-+++ b/udp.c
-@@ -160,7 +160,7 @@ unsigned char *radudpget(int s, struct client **client, struct server **server)
-         }
- 
-         p = client
--            ? find_clconf(handle, (struct sockaddr *)&from, NULL)
-+            ? find_clconf(handle, (struct sockaddr *)&from, NULL, NULL)
-             : find_srvconf(handle, (struct sockaddr *)&from, NULL);
-         if (!p) {
-             debug(DBG_WARN, "radudpget: got packet from wrong or unknown UDP peer %s, ignoring", addr2string((struct sockaddr *)&from, tmp, sizeof(tmp)));
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/radsecproxy.git/commitdiff/ac1e65a99fcdf1c7f1bd2c119024ed6f4ddc12bf



More information about the pld-cvs-commit mailing list