----- Original Message -----
> Thanks to have submitted the patch. It looks fine (I have just a minor
> comment below). Could I please ask you to provide also the entries for
> the ChangeLog file as part of your patch? It is a boring task but this
> is required by the GNU Coding standards[1]. If you have no time for
> this, I can do it.
Whitespace removed, changelog entry added. Fixed patch is attached.
Regards,
Tomas Hozza
From af919b1126c407a2e1e1a2c6ad4af5831247ee4a Mon Sep 17 00:00:00 2001
From: Karsten Hopp <[email protected]>
Date: Thu, 11 Jul 2013 11:27:35 +0200
Subject: [PATCH] Fix timeout option when used with SSL
Previously wget didn't honor the --timeout option if the remote host did
not answer SSL handshake
Signed-off-by: Tomas Hozza <[email protected]>
---
src/ChangeLog | 4 ++++
src/openssl.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 57 insertions(+), 9 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 8822973..658e933 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2013-07-11 Karsten Hopp <[email protected]>
+
+ * openssl.c: respect connect timeout
+
2013-07-11 Tim Ruehsen <[email protected]>
* gnutls.c (ssl_connect_wget): respect connect timeout.
diff --git a/src/openssl.c b/src/openssl.c
index 3924e41..189b334 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -256,19 +256,42 @@ struct openssl_transport_context {
char *last_error; /* last error printed with openssl_errstr */
};
-static int
-openssl_read (int fd, char *buf, int bufsize, void *arg)
-{
- int ret;
- struct openssl_transport_context *ctx = arg;
+struct openssl_read_args {
+ int fd;
+ struct openssl_transport_context *ctx;
+ char *buf;
+ int bufsize;
+ int retval;
+};
+
+static void openssl_read_callback(void *arg) {
+ struct openssl_read_args *args = (struct openssl_read_args *) arg;
+ struct openssl_transport_context *ctx = args->ctx;
SSL *conn = ctx->conn;
+ char *buf = args->buf;
+ int bufsize = args->bufsize;
+ int ret;
+
do
ret = SSL_read (conn, buf, bufsize);
- while (ret == -1
- && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
+ while (ret == -1 && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL
&& errno == EINTR);
+ args->retval = ret;
+}
- return ret;
+static int
+openssl_read (int fd, char *buf, int bufsize, void *arg)
+{
+ struct openssl_read_args args;
+ args.fd = fd;
+ args.buf = buf;
+ args.bufsize = bufsize;
+ args.ctx = (struct openssl_transport_context*) arg;
+
+ if (run_with_timeout(opt.read_timeout, openssl_read_callback, &args)) {
+ return -1;
+ }
+ return args.retval;
}
static int
@@ -386,6 +409,18 @@ static struct transport_implementation openssl_transport = {
openssl_peek, openssl_errstr, openssl_close
};
+struct scwt_context {
+ SSL *ssl;
+ int result;
+};
+
+static void
+ssl_connect_with_timeout_callback(void *arg)
+{
+ struct scwt_context *ctx = (struct scwt_context *)arg;
+ ctx->result = SSL_connect(ctx->ssl);
+}
+
/* Perform the SSL handshake on file descriptor FD, which is assumed
to be connected to an SSL server. The SSL handle provided by
OpenSSL is registered with the file descriptor FD using
@@ -398,6 +433,7 @@ bool
ssl_connect_wget (int fd, const char *hostname)
{
SSL *conn;
+ struct scwt_context scwt_ctx;
struct openssl_transport_context *ctx;
DEBUGP (("Initiating SSL handshake.\n"));
@@ -425,7 +461,14 @@ ssl_connect_wget (int fd, const char *hostname)
if (!SSL_set_fd (conn, FD_TO_SOCKET (fd)))
goto error;
SSL_set_connect_state (conn);
- if (SSL_connect (conn) <= 0 || conn->state != SSL_ST_OK)
+
+ scwt_ctx.ssl = conn;
+ if (run_with_timeout(opt.read_timeout, ssl_connect_with_timeout_callback,
+ &scwt_ctx)) {
+ DEBUGP (("SSL handshake timed out.\n"));
+ goto timeout;
+ }
+ if (scwt_ctx.result <= 0 || conn->state != SSL_ST_OK)
goto error;
ctx = xnew0 (struct openssl_transport_context);
@@ -441,6 +484,7 @@ ssl_connect_wget (int fd, const char *hostname)
error:
DEBUGP (("SSL handshake failed.\n"));
print_errors ();
+ timeout:
if (conn)
SSL_free (conn);
return false;
--
1.8.3.1