diff options
| author | venaas <venaas> | 2007-01-03 12:27:45 +0000 | 
|---|---|---|
| committer | venaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf> | 2007-01-03 12:27:45 +0000 | 
| commit | 60d9b64a571ccd841ef858fc98e0d27c429ba0a1 (patch) | |
| tree | 7494093ac86efd5439522fc4217890a77f4309d8 | |
| parent | 84666c7aa28fc47b3d86a920bbf55f467391f98e (diff) | |
tlsconnect changes
git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@4 e88ac4ed-0b26-0410-9574-a7f39faa03bf
| -rw-r--r-- | radsecproxy.c | 87 | ||||
| -rw-r--r-- | radsecproxy.h | 2 | 
2 files changed, 51 insertions, 38 deletions
| diff --git a/radsecproxy.c b/radsecproxy.c index 608382e..5374403 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -16,6 +16,7 @@   * make our server ignore client retrans?   * tls keep alives   * routing based on id.... + * need to also encrypt Tunnel-Password and Message-Authenticator attrs   * tls certificate validation  */ @@ -44,6 +45,7 @@  #include <netdb.h>  #include <unistd.h> +#include <sys/time.h>  #include <pthread.h>  #include <openssl/ssl.h>  #include <openssl/rand.h> @@ -221,42 +223,48 @@ unsigned char *radudpget(int s, struct peer **peer, struct sockaddr_storage *sa)      return rad;  } -void tlsconnect(struct peer *peer, int oldsock, char *text) { -    unsigned int sleeptime, try = 0; +void tlsconnect(struct peer *peer, struct timeval *when, char *text) { +    struct timeval now; +    time_t elapsed; +    unsigned long error;      pthread_mutex_lock(&peer->lock); -    if (peer->sockcl != oldsock) { +    if (when && memcmp(&peer->lastconnecttry, when, sizeof(struct timeval))) {  	/* already reconnected, nothing to do */ -	printf("reconnect: seems already reconnected\n"); +	printf("tlsconnect: seems already reconnected\n");  	pthread_mutex_unlock(&peer->lock);  	return;      } -    printf("tlsconnect %d %s\n", oldsock, text); -    sleep(1); +    printf("tlsconnect %s\n", text); +      for (;;) {  	printf("tlsconnect: trying to open TLS connection to %s port %s\n", peer->host, peer->port); -	if ((peer->sockcl = connecttopeer(peer)) >= 0) +	gettimeofday(&now, NULL); +	if (when) { // don't wait first time +	    elapsed = now.tv_sec - peer->lastconnecttry.tv_sec; +	    if (peer->connectionok) { +		peer->connectionok = 0; +		sleep(10); +	    } else if (elapsed < 5) +		sleep(10); +	    else if (elapsed < 600) +		sleep(elapsed * 2); +	    else +		sleep(900); +	} +	if (peer->sockcl >= 0) +	    close(peer->sockcl); +	if ((peer->sockcl = connecttopeer(peer)) < 0) +	    continue; +	SSL_free(peer->sslcl); +	peer->sslcl = SSL_new(ssl_ctx_cl); +	SSL_set_fd(peer->sslcl, peer->sockcl); +	if (SSL_connect(peer->sslcl) > 0)  	    break; -	try++; -	if (try < 6) -	    sleeptime = 10; -	else if (try < 20) -	    sleeptime = 60; -	else -	    sleeptime = 900; -	/* should possibly re-resolve host addresses at some point */ -	printf("tlsconnect: can't connect, retry #%d in %ds\n", try, sleeptime); -	sleep(sleeptime); +	while ((error = ERR_get_error())) +	    err("tlsconnect: TLS: %s", ERR_error_string(error, NULL));      } -	 -    SSL_free(peer->sslcl); -    peer->sslcl = SSL_new(ssl_ctx_cl); -    SSL_set_fd(peer->sslcl, peer->sockcl); -    /* must close oldsock after get new socket so that they are always different */ -    if (oldsock >= 0) -	close(oldsock); -    SSL_connect(peer->sslcl);      printf("tlsconnect: TLS connection to %s port %s up\n", peer->host, peer->port);      pthread_mutex_unlock(&peer->lock);  } @@ -303,10 +311,11 @@ unsigned char *radtlsget(SSL *ssl) {  }  int clientradput(struct peer *peer, unsigned char *rad) { -    int cnt, s; +    int cnt;      size_t len;      unsigned long error; - +    struct timeval lastconnecttry; +          len = RADLEN(rad);      if (peer->type == 'U') {  	if (send(peer->sockcl, rad, len, 0) >= 0) { @@ -317,14 +326,15 @@ int clientradput(struct peer *peer, unsigned char *rad) {  	return 0;      } -    s = peer->sockcl; +    lastconnecttry = peer->lastconnecttry;      while ((cnt = SSL_write(peer->sslcl, rad, len)) <= 0) {  	while ((error = ERR_get_error()))  	    err("clientwr: TLS: %s", ERR_error_string(error, NULL)); -	tlsconnect(peer, s, "clientradput"); -	s = peer->sockcl; +	tlsconnect(peer, &lastconnecttry, "clientradput"); +	lastconnecttry = peer->lastconnecttry;      } -	    + +    peer->connectionok = 1;      printf("clientradput: Sent %d bytes, Radius packet of length %d to TLS peer %s\n",  	   cnt, len, peer->host);      return 1; @@ -572,19 +582,22 @@ struct peer *radsrv(struct request *rq, char *buf, struct peer *from) {  void *clientrd(void *arg) {      struct peer *from, *peer = (struct peer *)arg; -    int i, s; +    int i;      unsigned char *buf;      struct sockaddr_storage fromsa; +    struct timeval lastconnecttry;      for (;;) { -	s = peer->sockcl; -	buf = (peer->type == 'U' ? radudpget(s, &peer, NULL) : radtlsget(peer->sslcl)); +	lastconnecttry = peer->lastconnecttry; +	buf = (peer->type == 'U' ? radudpget(peer->sockcl, &peer, NULL) : radtlsget(peer->sslcl));  	if (!buf && peer->type == 'T') {  	    printf("retry in 60s\n");  	    sleep(60); /* should have exponential backoff perhaps, better do it inside radtlsget */ -	    tlsconnect(peer, s, "clientrd"); +	    tlsconnect(peer, &lastconnecttry, "clientrd");  	    continue;  	} + +	peer->connectionok = 1;  	i = buf[1]; /* i is the id */ @@ -637,7 +650,7 @@ void *clientwr(void *arg) {  	    exit(1);  	}      } else -	tlsconnect(peer, -1, "new client"); +	tlsconnect(peer, NULL, "new client");      if (pthread_create(&clientrdth, NULL, clientrd, (void *)peer))  	errx("clientwr: pthread_create failed"); @@ -998,8 +1011,6 @@ void getconfig(const char *filename) {  	    }  	}  	peer->sockcl = -1; -	peer->sslsrv = NULL; -	peer->sslcl = NULL;  	pthread_mutex_init(&peer->lock, NULL);  	if (!resolvepeer(peer)) {  	    printf("failed to resolve host %s port %s, exiting\n", peer->host, peer->port); diff --git a/radsecproxy.h b/radsecproxy.h index 2d7b233..77d02ae 100644 --- a/radsecproxy.h +++ b/radsecproxy.h @@ -73,6 +73,8 @@ struct peer {      pthread_t clientth;      int sockcl;      struct addrinfo *addrinfo; +    struct timeval lastconnecttry; +    uint8_t connectionok;      /* requests and newrq* are requests passed from servers to clients */      struct request *requests;      uint8_t newrq; | 
