From: bluhm Date: Tue, 13 Jan 2015 17:35:35 +0000 (+0000) Subject: For non-blocking sockets tls_connect_fds() could fail with EAGAIN. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=3d6199eb2ca0a6e97970865df4d371fdd27837be;p=openbsd For non-blocking sockets tls_connect_fds() could fail with EAGAIN. Use the same logic from the read, write, accept functions to inform the caller wether a readable or writable socket is needed. After that event, the connect function must be called again. All the checks before connecting are done only once. OK tedu@ --- diff --git a/lib/libtls/tls_client.c b/lib/libtls/tls_client.c index 79b1baf648c..c6117c32929 100644 --- a/lib/libtls/tls_client.c +++ b/lib/libtls/tls_client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_client.c,v 1.7 2015/01/02 16:38:07 bluhm Exp $ */ +/* $OpenBSD: tls_client.c,v 1.8 2015/01/13 17:35:35 bluhm Exp $ */ /* * Copyright (c) 2014 Joel Sing * @@ -135,7 +135,10 @@ tls_connect_fds(struct tls *ctx, int fd_read, int fd_write, { union { struct in_addr ip4; struct in6_addr ip6; } addrbuf; X509 *cert = NULL; - int ret; + int ret, ssl_err; + + if (ctx->flags & TLS_CONNECTING) + goto connecting; if ((ctx->flags & TLS_CLIENT) == 0) { tls_set_error(ctx, "not a client context"); @@ -198,11 +201,22 @@ tls_connect_fds(struct tls *ctx, int fd_read, int fd_write, } } + connecting: if ((ret = SSL_connect(ctx->ssl_conn)) != 1) { - tls_set_error(ctx, "SSL connect failed: %i", - SSL_get_error(ctx->ssl_conn, ret)); - goto err; + ssl_err = SSL_get_error(ctx->ssl_conn, ret); + switch (ssl_err) { + case SSL_ERROR_WANT_READ: + ctx->flags |= TLS_CONNECTING; + return (TLS_READ_AGAIN); + case SSL_ERROR_WANT_WRITE: + ctx->flags |= TLS_CONNECTING; + return (TLS_WRITE_AGAIN); + default: + tls_set_error(ctx, "SSL connect failed: %i", ssl_err); + goto err; + } } + ctx->flags &= ~TLS_CONNECTING; if (ctx->config->verify_host) { cert = SSL_get_peer_certificate(ctx->ssl_conn); diff --git a/lib/libtls/tls_internal.h b/lib/libtls/tls_internal.h index 4b250574ef7..1a2bd388b7d 100644 --- a/lib/libtls/tls_internal.h +++ b/lib/libtls/tls_internal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tls_internal.h,v 1.5 2014/12/17 17:51:33 doug Exp $ */ +/* $OpenBSD: tls_internal.h,v 1.6 2015/01/13 17:35:35 bluhm Exp $ */ /* * Copyright (c) 2014 Jeremie Courreges-Anglas * Copyright (c) 2014 Joel Sing @@ -44,7 +44,8 @@ struct tls_config { #define TLS_CLIENT (1 << 0) #define TLS_SERVER (1 << 1) -#define TLS_SERVER_CONN (1 << 2) +#define TLS_SERVER_CONN (1 << 2) +#define TLS_CONNECTING (1 << 3) struct tls { struct tls_config *config;