/* returns 0 on timeout, -1 on error and num if ok */
int sslreadtimeout(SSL *ssl, unsigned char *buf, int num, int timeout) {
int s, ndesc, cnt, len;
- fd_set readfds, writefds;
+ fd_set readfds;
struct timeval timer;
s = SSL_get_fd(ssl);
return -1;
/* make socket non-blocking? */
for (len = 0; len < num; len += cnt) {
- FD_ZERO(&readfds);
- FD_SET(s, &readfds);
- writefds = readfds;
- if (timeout) {
- timer.tv_sec = timeout;
- timer.tv_usec = 0;
+ if (SSL_pending(ssl) == 0) {
+ FD_ZERO(&readfds);
+ FD_SET(s, &readfds);
+ if (timeout) {
+ timer.tv_sec = timeout;
+ timer.tv_usec = 0;
+ }
+ ndesc = select(s + 1, &readfds, NULL, NULL, timeout ? &timer : NULL);
+ if (ndesc < 1)
+ return ndesc;
}
- ndesc = select(s + 1, &readfds, &writefds, NULL, timeout ? &timer : NULL);
- if (ndesc < 1)
- return ndesc;
cnt = SSL_read(ssl, buf + len, num - len);
if (cnt <= 0)
}
}
}
+ debug(DBG_INFO, "tlsclientrd: exiting for %s", server->conf->name);
ERR_remove_state(0);
+ SSL_shutdown(server->ssl);
+ shutdown(server->sock, SHUT_RDWR);
+ close(server->sock);
+
+ /* Wake up clientwr(). */
server->clientrdgone = 1;
+ pthread_mutex_lock(&server->newrq_mutex);
+ pthread_cond_signal(&server->newrq_cond);
+ pthread_mutex_unlock(&server->newrq_mutex);
return NULL;
}
debug(DBG_DBG, "tlsserverrd: starting for %s", addr2string(client->addr));
- if (pthread_create(&tlsserverwrth, NULL, tlsserverwr, (void *)client)) {
+ if (pthread_create(&tlsserverwrth, &pthread_attr, tlsserverwr, (void *)client)) {
debug(DBG_ERR, "tlsserverrd: pthread_create failed");
return;
}
for (;;) {
- buf = radtlsget(client->ssl, 0);
+ buf = radtlsget(client->ssl, IDLE_TIMEOUT * 3);
if (!buf) {
debug(DBG_ERR, "tlsserverrd: connection from %s lost", addr2string(client->addr));
break;
SSL_CTX *ctx = NULL;
unsigned long error;
struct client *client;
+ struct tls *accepted_tls = NULL;
s = *(int *)arg;
if (getpeername(s, (struct sockaddr *)&from, &fromlen)) {
cert = verifytlscert(ssl);
if (!cert)
goto exit;
+ accepted_tls = conf->tlsconf;
}
while (conf) {
- if (verifyconfcert(cert, conf)) {
- X509_free(cert);
- client = addclient(conf, 1);
- if (client) {
- client->ssl = ssl;
- client->addr = addr_copy((struct sockaddr *)&from);
- tlsserverrd(client);
- removeclient(client);
- } else
- debug(DBG_WARN, "tlsservernew: failed to create new client instance");
- goto exit;
- }
- conf = find_clconf(handle, (struct sockaddr *)&from, &cur);
+ if (accepted_tls == conf->tlsconf && verifyconfcert(cert, conf)) {
+ X509_free(cert);
+ client = addclient(conf, 1);
+ if (client) {
+ client->ssl = ssl;
+ client->addr = addr_copy((struct sockaddr *)&from);
+ tlsserverrd(client);
+ removeclient(client);
+ } else
+ debug(DBG_WARN, "tlsservernew: failed to create new client instance");
+ goto exit;
+ }
+ conf = find_clconf(handle, (struct sockaddr *)&from, &cur);
}
debug(DBG_WARN, "tlsservernew: ignoring request, no matching TLS client");
if (cert)
debug(DBG_WARN, "accept failed");
continue;
}
- if (pthread_create(&tlsserverth, NULL, tlsservernew, (void *)&s)) {
+ if (pthread_create(&tlsserverth, &pthread_attr, tlsservernew, (void *)&s)) {
debug(DBG_ERR, "tlslistener: pthread_create failed");
shutdown(s, SHUT_RDWR);
close(s);