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 { | 
