diff options
author | venaas <venaas> | 2007-01-15 15:56:30 +0000 |
---|---|---|
committer | venaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf> | 2007-01-15 15:56:30 +0000 |
commit | 736eeaf37e3e5387208f0c378198385f0d3ae79b (patch) | |
tree | 4dc975210cc7f395b4c1b33023ded87bfe4ece31 | |
parent | c8b0e66df1648e75ffec5004001ac1f9de96ec46 (diff) |
code for cleaning up when tls client goes away
git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@36 e88ac4ed-0b26-0410-9574-a7f39faa03bf
-rw-r--r-- | radsecproxy.c | 67 | ||||
-rw-r--r-- | radsecproxy.h | 3 |
2 files changed, 47 insertions, 23 deletions
diff --git a/radsecproxy.c b/radsecproxy.c index 9d55d4f..de59c12 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -320,6 +320,10 @@ unsigned char *radtlsget(SSL *ssl) { cnt = SSL_read(ssl, buf + total, 4 - total); if (cnt <= 0) { printf("radtlsget: connection lost\n"); + if (SSL_get_error(ssl, cnt) == SSL_ERROR_ZERO_RETURN) { + //remote end sent close_notify, send one back + SSL_shutdown(ssl); + } return NULL; } } @@ -336,6 +340,10 @@ unsigned char *radtlsget(SSL *ssl) { cnt = SSL_read(ssl, rad + total, len - total); if (cnt <= 0) { printf("radtlsget: connection lost\n"); + if (SSL_get_error(ssl, cnt) == SSL_ERROR_ZERO_RETURN) { + //remote end sent close_notify, send one back + SSL_shutdown(ssl); + } free(rad); return NULL; } @@ -1237,13 +1245,22 @@ void *tlsserverwr(void *arg) { struct client *client = (struct client *)arg; struct replyq *replyq; - pthread_mutex_lock(&client->replycount_mutex); + printf("tlsserverwr starting for %s\n", client->peer.host); + replyq = client->replyq; + pthread_mutex_lock(&replyq->count_mutex); for (;;) { - replyq = client->replyq; while (!replyq->count) { - printf("tls server writer, waiting for signal\n"); - pthread_cond_wait(&replyq->count_cond, &replyq->count_mutex); - printf("tls server writer, got signal\n"); + if (client->peer.ssl) { + printf("tls server writer, waiting for signal\n"); + pthread_cond_wait(&replyq->count_cond, &replyq->count_mutex); + printf("tls server writer, got signal\n"); + } + if (!client->peer.ssl) { + //ssl might have changed while waiting + pthread_mutex_unlock(&replyq->count_mutex); + printf("tlsserverwr: exiting as requested\n"); + pthread_exit(NULL); + } } pthread_mutex_unlock(&replyq->count_mutex); cnt = SSL_write(client->peer.ssl, replyq->replies->buf, RADLEN(replyq->replies->buf)); @@ -1269,9 +1286,12 @@ void *tlsserverrd(void *arg) { int s; struct client *client = (struct client *)arg; pthread_t tlsserverwrth; + SSL *ssl; + + printf("tlsserverrd starting for %s\n", client->peer.host); + ssl = client->peer.ssl; - printf("tlsserverrd starting\n"); - if (SSL_accept(client->peer.ssl) <= 0) { + if (SSL_accept(ssl) <= 0) { while ((error = ERR_get_error())) err("tlsserverrd: SSL: %s", ERR_error_string(error, NULL)); errx("accept failed, child exiting"); @@ -1282,15 +1302,8 @@ void *tlsserverrd(void *arg) { for (;;) { buf = radtlsget(client->peer.ssl); - if (!buf) { - printf("tlsserverrd: connection lost\n"); - s = SSL_get_fd(client->peer.ssl); - SSL_free(client->peer.ssl); - client->peer.ssl = NULL; - if (s >= 0) - close(s); - pthread_exit(NULL); - } + if (!buf) + break; printf("tlsserverrd: got Radius message from %s\n", client->peer.host); memset(&rq, 0, sizeof(struct request)); to = radsrv(&rq, buf, client); @@ -1300,6 +1313,19 @@ void *tlsserverrd(void *arg) { } sendrq(to, client, &rq); } + printf("tlsserverrd: connection lost\n"); + // stop writer by setting peer.ssl to NULL and give signal in case waiting for data + client->peer.ssl = NULL; + pthread_mutex_lock(&client->replyq->count_mutex); + pthread_cond_signal(&client->replyq->count_cond); + pthread_mutex_unlock(&client->replyq->count_mutex); + printf("tlsserverrd: waiting for writer to end\n"); + pthread_join(tlsserverwrth, NULL); + s = SSL_get_fd(ssl); + SSL_free(ssl); + close(s); + printf("tlsserverrd thread for %s exiting\n", client->peer.host); + pthread_exit(NULL); } int tlslistener(SSL_CTX *ssl_ctx) { @@ -1339,6 +1365,7 @@ int tlslistener(SSL_CTX *ssl_ctx) { SSL_set_fd(client->peer.ssl, snew); if (pthread_create(&tlsserverth, NULL, tlsserverrd, (void *)client)) errx("pthread_create failed"); + pthread_detach(tlsserverth); } return 0; } @@ -1581,7 +1608,7 @@ int main(int argc, char **argv) { SSL_CTX *ssl_ctx_srv; unsigned long error; pthread_t udpserverth; - pthread_attr_t joinable; + // pthread_attr_t joinable; int i; parseargs(argc, argv); @@ -1590,14 +1617,14 @@ int main(int argc, char **argv) { ssl_locks_setup(); - pthread_attr_init(&joinable); - pthread_attr_setdetachstate(&joinable, PTHREAD_CREATE_JOINABLE); + // pthread_attr_init(&joinable); + // pthread_attr_setdetachstate(&joinable, PTHREAD_CREATE_JOINABLE); /* listen on UDP if at least one UDP client */ for (i = 0; i < client_count; i++) if (clients[i].peer.type == 'U') { - if (pthread_create(&udpserverth, &joinable, udpserverrd, NULL)) + if (pthread_create(&udpserverth, NULL /*&joinable*/, udpserverrd, NULL)) errx("pthread_create failed"); break; } diff --git a/radsecproxy.h b/radsecproxy.h index 7ad2002..b4393d4 100644 --- a/radsecproxy.h +++ b/radsecproxy.h @@ -81,9 +81,6 @@ struct peer { struct client { struct peer peer; struct replyq *replyq; - int replycount; - pthread_mutex_t replycount_mutex; - pthread_cond_t replycount_cond; }; struct server { |