mirror of
https://github.com/mirror/wget.git
synced 2024-12-28 22:00:27 +08:00
Fix SSL/TLS timeout issues.
* connect.c (fd_read, fd_peek): Let implementation take care about timeout. * gnutls.c (_do_handshake, _do_reauth, wgnutls_read_timeout): Fix support for interactive timeout. * gnutls.c (wgnutls_peek): Let wgnutls_read_timeout() take care about timeout. * openssl.c (openssl_read_peek): Fix 0 (-1) timeout. * retr.c (fd_read_body): Avoid wrong 'interactive timeout'.
This commit is contained in:
parent
c12a295496
commit
7a3a82faf8
@ -941,12 +941,14 @@ fd_read (int fd, char *buf, int bufsize, double timeout)
|
||||
struct transport_info *info;
|
||||
LAZY_RETRIEVE_INFO (info);
|
||||
|
||||
if (!poll_internal (fd, info, WAIT_FOR_READ, timeout))
|
||||
return -1;
|
||||
/* let imp->reader take care about timeout.
|
||||
(or in worst case timeout can be 2*timeout) */
|
||||
if (info && info->imp->reader)
|
||||
return info->imp->reader (fd, buf, bufsize, info->ctx, timeout);
|
||||
else
|
||||
return sock_read (fd, buf, bufsize);
|
||||
|
||||
if (!poll_internal (fd, info, WAIT_FOR_READ, timeout))
|
||||
return -1;
|
||||
return sock_read (fd, buf, bufsize);
|
||||
}
|
||||
|
||||
/* Like fd_read, except it provides a "preview" of the data that will
|
||||
@ -966,12 +968,13 @@ fd_peek (int fd, char *buf, int bufsize, double timeout)
|
||||
{
|
||||
struct transport_info *info;
|
||||
LAZY_RETRIEVE_INFO (info);
|
||||
if (!poll_internal (fd, info, WAIT_FOR_READ, timeout))
|
||||
return -1;
|
||||
|
||||
if (info && info->imp->peeker)
|
||||
return info->imp->peeker (fd, buf, bufsize, info->ctx, timeout);
|
||||
else
|
||||
return sock_peek (fd, buf, bufsize);
|
||||
|
||||
if (!poll_internal (fd, info, WAIT_FOR_READ, timeout))
|
||||
return -1;
|
||||
return sock_peek (fd, buf, bufsize);
|
||||
}
|
||||
|
||||
/* Write the entire contents of BUF to FD. If TIMEOUT is non-zero,
|
||||
|
255
src/gnutls.c
255
src/gnutls.c
@ -58,12 +58,20 @@ as that of the covered work. */
|
||||
|
||||
#include "host.h"
|
||||
|
||||
struct st_read_timer
|
||||
{
|
||||
double timeout;
|
||||
double next_timeout;
|
||||
struct ptimer *timer;
|
||||
int timed_out;
|
||||
};
|
||||
|
||||
static int
|
||||
_do_handshake (gnutls_session_t session, int fd, double timeout, int is_nonblock);
|
||||
_do_handshake (gnutls_session_t session, int fd, struct st_read_timer *timeout);
|
||||
|
||||
#if GNUTLS_VERSION_NUMBER >= 0x030604
|
||||
static int
|
||||
_do_reauth (gnutls_session_t session, int fd, double timeout, int is_nonblock);
|
||||
_do_reauth (gnutls_session_t session, int fd, struct st_read_timer *timeout);
|
||||
#endif
|
||||
|
||||
static int
|
||||
@ -255,17 +263,14 @@ wgnutls_read_timeout (int fd, char *buf, int bufsize, void *arg, double timeout)
|
||||
#ifdef F_GETFL
|
||||
int flags = 0;
|
||||
#endif
|
||||
int ret = 0;
|
||||
struct ptimer *timer = NULL;
|
||||
struct wgnutls_transport_context *ctx = arg;
|
||||
int timed_out = 0;
|
||||
double next_timeout;
|
||||
int ret = gnutls_record_check_pending (ctx->session);
|
||||
struct st_read_timer read_timer = {(timeout == -1 ? opt.read_timeout : timeout), 0, NULL, 0};
|
||||
|
||||
errno = 0;
|
||||
if (timeout == -1)
|
||||
timeout = opt.read_timeout;
|
||||
next_timeout = timeout;
|
||||
if (timeout)
|
||||
if (ret)
|
||||
return gnutls_record_recv (ctx->session, buf, MIN (ret, bufsize));
|
||||
|
||||
if (read_timer.timeout)
|
||||
{
|
||||
#ifdef F_GETFL
|
||||
flags = fcntl (fd, F_GETFL, 0);
|
||||
@ -280,63 +285,83 @@ wgnutls_read_timeout (int fd, char *buf, int bufsize, void *arg, double timeout)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
timer = ptimer_new ();
|
||||
if (timer == NULL)
|
||||
read_timer.timer = ptimer_new ();
|
||||
if (read_timer.timer == NULL)
|
||||
{
|
||||
ret = -1;
|
||||
goto timer_err;
|
||||
}
|
||||
read_timer.next_timeout = read_timer.timeout;
|
||||
}
|
||||
|
||||
ret = ctx->last_error;
|
||||
do
|
||||
{
|
||||
ret = GNUTLS_E_AGAIN;
|
||||
if (timeout)
|
||||
if (ret == GNUTLS_E_REHANDSHAKE)
|
||||
{
|
||||
next_timeout = timeout - ptimer_measure (timer);
|
||||
if (next_timeout <= 0)
|
||||
int err;
|
||||
DEBUGP (("GnuTLS: *** REHANDSHAKE while reading\n"));
|
||||
if ((err = _do_handshake (ctx->session, fd, &read_timer)) != 0)
|
||||
{
|
||||
timed_out = 1;
|
||||
ret = err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* (rehandshake, reauth) needs some workaround for interactive timeout */
|
||||
if (timeout == 0 || gnutls_record_check_pending (ctx->session)
|
||||
|| select_fd_nb (fd, next_timeout, WAIT_FOR_READ))
|
||||
#if GNUTLS_VERSION_NUMBER >= 0x030604
|
||||
else if (ret == GNUTLS_E_REAUTH_REQUEST)
|
||||
{
|
||||
int err;
|
||||
DEBUGP (("GnuTLS: *** re-authentication while reading\n"));
|
||||
if ((err = _do_reauth (ctx->session, fd, &read_timer)) != 0)
|
||||
{
|
||||
ret = err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
do
|
||||
{
|
||||
ret = gnutls_record_recv (ctx->session, buf, bufsize);
|
||||
timed_out = timeout && ptimer_measure (timer) >= timeout;
|
||||
if (!timed_out && ret == GNUTLS_E_REHANDSHAKE)
|
||||
if (ret == GNUTLS_E_AGAIN && read_timer.timer)
|
||||
{
|
||||
DEBUGP (("GnuTLS: *** REHANDSHAKE while reading\n"));
|
||||
if ((ret = _do_handshake (ctx->session, fd, opt.read_timeout, 1)) == 0)
|
||||
ret = GNUTLS_E_AGAIN; /* restart reading */
|
||||
int err = select_fd_nb (fd, read_timer.next_timeout, WAIT_FOR_READ);
|
||||
if (err <= 0)
|
||||
{
|
||||
if (err == 0)
|
||||
read_timer.timed_out = 1;
|
||||
goto break_all;
|
||||
}
|
||||
if ( (read_timer.next_timeout = read_timer.timeout - ptimer_measure (read_timer.timer)) <= 0 )
|
||||
{
|
||||
read_timer.timed_out = 1;
|
||||
goto break_all;
|
||||
}
|
||||
}
|
||||
#if GNUTLS_VERSION_NUMBER >= 0x030604
|
||||
if (!timed_out && ret == GNUTLS_E_REAUTH_REQUEST)
|
||||
{
|
||||
DEBUGP (("GnuTLS: *** re-authentication while reading\n"));
|
||||
if ((ret = _do_reauth (ctx->session, fd, opt.read_timeout, 1)) == 0)
|
||||
ret = GNUTLS_E_AGAIN; /* restart reading */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
|
||||
}
|
||||
while (ret == GNUTLS_E_INTERRUPTED || (ret == GNUTLS_E_AGAIN && !timed_out));
|
||||
while (ret == GNUTLS_E_REHANDSHAKE
|
||||
#if GNUTLS_VERSION_NUMBER >= 0x030604
|
||||
|| ret == GNUTLS_E_REAUTH_REQUEST
|
||||
#endif
|
||||
);
|
||||
|
||||
if (timeout)
|
||||
break_all:
|
||||
if (read_timer.timer)
|
||||
{
|
||||
ptimer_destroy (timer);
|
||||
ptimer_destroy (read_timer.timer);
|
||||
timer_err: ;
|
||||
#ifdef F_GETFL
|
||||
if (fcntl (fd, F_SETFL, flags) < 0)
|
||||
return -1;
|
||||
#else
|
||||
const int zero = 0;
|
||||
if (ioctl (fd, FIONBIO, &zero) < 0)
|
||||
return -1;
|
||||
{
|
||||
const int zero = 0;
|
||||
if (ioctl (fd, FIONBIO, &zero) < 0)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
if (timed_out && ret == GNUTLS_E_AGAIN)
|
||||
if (read_timer.timed_out)
|
||||
errno = ETIMEDOUT;
|
||||
}
|
||||
|
||||
@ -346,7 +371,7 @@ timer_err: ;
|
||||
static int
|
||||
wgnutls_read (int fd, char *buf, int bufsize, void *arg, double timeout)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret;
|
||||
struct wgnutls_transport_context *ctx = arg;
|
||||
|
||||
if (ctx->peeklen)
|
||||
@ -362,22 +387,38 @@ wgnutls_read (int fd, char *buf, int bufsize, void *arg, double timeout)
|
||||
}
|
||||
|
||||
ret = wgnutls_read_timeout (fd, buf, bufsize, arg, timeout);
|
||||
if (ret < 0)
|
||||
ctx->last_error = ret;
|
||||
|
||||
ctx->last_error = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
wgnutls_write (int fd _GL_UNUSED, char *buf, int bufsize, void *arg)
|
||||
{
|
||||
int ret;
|
||||
struct wgnutls_transport_context *ctx = arg;
|
||||
int ret = ctx->last_error;
|
||||
|
||||
/* it should never happen,
|
||||
placed here only for debug msg. */
|
||||
if (ret == GNUTLS_E_REHANDSHAKE)
|
||||
{
|
||||
DEBUGP (("GnuTLS: *** REHANDSHAKE while writing\n"));
|
||||
if ((ret = _do_handshake (ctx->session, fd, NULL)) != 0)
|
||||
goto ext;
|
||||
}
|
||||
#if GNUTLS_VERSION_NUMBER >= 0x030604
|
||||
else if (ret == GNUTLS_E_REAUTH_REQUEST)
|
||||
{
|
||||
DEBUGP (("GnuTLS: *** re-authentication while writing\n"));
|
||||
if ((ret = _do_reauth (ctx->session, fd, NULL)) != 0)
|
||||
goto ext;
|
||||
}
|
||||
#endif
|
||||
|
||||
do
|
||||
ret = gnutls_record_send (ctx->session, buf, bufsize);
|
||||
while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
|
||||
if (ret < 0)
|
||||
ctx->last_error = ret;
|
||||
ext:
|
||||
ctx->last_error = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -386,11 +427,13 @@ wgnutls_poll (int fd, double timeout, int wait_for, void *arg)
|
||||
{
|
||||
struct wgnutls_transport_context *ctx = arg;
|
||||
|
||||
if (timeout)
|
||||
return ctx->peeklen || gnutls_record_check_pending (ctx->session)
|
||||
|| select_fd (fd, timeout, wait_for);
|
||||
else
|
||||
return ctx->peeklen || gnutls_record_check_pending (ctx->session);
|
||||
if ((wait_for & WAIT_FOR_READ)
|
||||
&& (ctx->peeklen || gnutls_record_check_pending (ctx->session)))
|
||||
return 1;
|
||||
|
||||
if (timeout == -1)
|
||||
timeout = opt.read_timeout;
|
||||
return select_fd (fd, timeout, wait_for);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -410,13 +453,14 @@ wgnutls_peek (int fd, char *buf, int bufsize, void *arg, double timeout)
|
||||
bufsize = sizeof ctx->peekbuf;
|
||||
|
||||
if (bufsize > offset)
|
||||
{
|
||||
if (timeout && gnutls_record_check_pending (ctx->session) == 0
|
||||
{ /* let wgnutls_read_timeout() take care about timeout */
|
||||
/*if (timeout && gnutls_record_check_pending (ctx->session) == 0
|
||||
&& select_fd (fd, 0.0, WAIT_FOR_READ) <= 0)
|
||||
read = 0;
|
||||
else
|
||||
else*/
|
||||
read = wgnutls_read_timeout (fd, buf + offset, bufsize - offset,
|
||||
ctx, timeout);
|
||||
ctx->last_error = read;
|
||||
if (read < 0)
|
||||
{
|
||||
if (offset)
|
||||
@ -440,8 +484,17 @@ static const char *
|
||||
wgnutls_errstr (int fd _GL_UNUSED, void *arg)
|
||||
{
|
||||
struct wgnutls_transport_context *ctx = arg;
|
||||
return (ctx->last_error == GNUTLS_E_AGAIN && errno == ETIMEDOUT ?
|
||||
strerror (ETIMEDOUT) : gnutls_strerror (ctx->last_error));
|
||||
|
||||
if (ctx->last_error > 0
|
||||
|| ((ctx->last_error == GNUTLS_E_AGAIN
|
||||
|| ctx->last_error == GNUTLS_E_REHANDSHAKE
|
||||
#if GNUTLS_VERSION_NUMBER >= 0x030604
|
||||
|| ctx->last_error == GNUTLS_E_REAUTH_REQUEST
|
||||
#endif
|
||||
) && errno == ETIMEDOUT))
|
||||
return NULL;
|
||||
|
||||
return gnutls_strerror (ctx->last_error);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -469,14 +522,16 @@ static struct transport_implementation wgnutls_transport =
|
||||
};
|
||||
|
||||
static int
|
||||
_do_handshake (gnutls_session_t session, int fd, double timeout, int is_nonblock)
|
||||
_do_handshake (gnutls_session_t session, int fd, struct st_read_timer *read_timer)
|
||||
{
|
||||
#ifdef F_GETFL
|
||||
int flags = 0;
|
||||
#endif
|
||||
int err;
|
||||
double next_timeout = (read_timer ? read_timer->next_timeout : opt.read_timeout);
|
||||
|
||||
if (!is_nonblock && timeout)
|
||||
/* if (read_timer != NULL) - fd is already non blocking */
|
||||
if (!read_timer && next_timeout)
|
||||
{
|
||||
#ifdef F_GETFL
|
||||
flags = fcntl (fd, F_GETFL, 0);
|
||||
@ -497,30 +552,46 @@ _do_handshake (gnutls_session_t session, int fd, double timeout, int is_nonblock
|
||||
{
|
||||
err = gnutls_handshake (session);
|
||||
|
||||
if (timeout && err == GNUTLS_E_AGAIN)
|
||||
if (err == GNUTLS_E_AGAIN && next_timeout)
|
||||
{
|
||||
int sel;
|
||||
if (gnutls_record_get_direction (session))
|
||||
{
|
||||
/* wait for writeability */
|
||||
err = select_fd_nb (fd, timeout, WAIT_FOR_WRITE);
|
||||
sel = WAIT_FOR_WRITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* wait for readability */
|
||||
err = select_fd_nb (fd, timeout, WAIT_FOR_READ);
|
||||
sel = WAIT_FOR_READ;
|
||||
}
|
||||
sel = select_fd_nb (fd, next_timeout, sel);
|
||||
|
||||
if (err <= 0)
|
||||
if (sel <= 0)
|
||||
{
|
||||
if (err == 0)
|
||||
if (sel == 0)
|
||||
{
|
||||
errno = ETIMEDOUT;
|
||||
err = -1;
|
||||
if (read_timer)
|
||||
goto read_timedout;
|
||||
else
|
||||
{
|
||||
errno = ETIMEDOUT;
|
||||
err = -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
err = GNUTLS_E_AGAIN;
|
||||
if (read_timer)
|
||||
{
|
||||
if ( (read_timer->next_timeout = read_timer->timeout - ptimer_measure (read_timer->timer)) <= 0 )
|
||||
{
|
||||
read_timedout: /* return GNUTLS_E_REHANDSHAKE for gnutls_read */
|
||||
err = GNUTLS_E_REHANDSHAKE;
|
||||
read_timer->timed_out = 1;
|
||||
break;
|
||||
}
|
||||
next_timeout = read_timer->next_timeout;
|
||||
}
|
||||
}
|
||||
else if (err < 0)
|
||||
{
|
||||
@ -537,7 +608,7 @@ _do_handshake (gnutls_session_t session, int fd, double timeout, int is_nonblock
|
||||
}
|
||||
while (err && gnutls_error_is_fatal (err) == 0);
|
||||
|
||||
if (!is_nonblock && timeout)
|
||||
if (!read_timer && next_timeout)
|
||||
{
|
||||
#ifdef F_GETFL
|
||||
if (fcntl (fd, F_SETFL, flags) < 0)
|
||||
@ -554,14 +625,16 @@ _do_handshake (gnutls_session_t session, int fd, double timeout, int is_nonblock
|
||||
|
||||
#if GNUTLS_VERSION_NUMBER >= 0x030604
|
||||
static int
|
||||
_do_reauth (gnutls_session_t session, int fd, double timeout, int is_nonblock)
|
||||
_do_reauth (gnutls_session_t session, int fd, struct st_read_timer *read_timer)
|
||||
{
|
||||
#ifdef F_GETFL
|
||||
int flags = 0;
|
||||
#endif
|
||||
int err;
|
||||
double next_timeout = (read_timer ? read_timer->next_timeout : opt.read_timeout);
|
||||
|
||||
if (!is_nonblock && timeout)
|
||||
/* if (read_timer != NULL) - fd is already non blocking */
|
||||
if (!read_timer && next_timeout)
|
||||
{
|
||||
#ifdef F_GETFL
|
||||
flags = fcntl (fd, F_GETFL, 0);
|
||||
@ -582,30 +655,46 @@ _do_reauth (gnutls_session_t session, int fd, double timeout, int is_nonblock)
|
||||
{
|
||||
err = gnutls_reauth (session, 0);
|
||||
|
||||
if (timeout && err == GNUTLS_E_AGAIN)
|
||||
if (err == GNUTLS_E_AGAIN && next_timeout)
|
||||
{
|
||||
int sel;
|
||||
if (gnutls_record_get_direction (session))
|
||||
{
|
||||
/* wait for writeability */
|
||||
err = select_fd_nb (fd, timeout, WAIT_FOR_WRITE);
|
||||
sel = WAIT_FOR_WRITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* wait for readability */
|
||||
err = select_fd_nb (fd, timeout, WAIT_FOR_READ);
|
||||
sel = WAIT_FOR_READ;
|
||||
}
|
||||
sel = select_fd_nb (fd, next_timeout, sel);
|
||||
|
||||
if (err <= 0)
|
||||
if (sel <= 0)
|
||||
{
|
||||
if (err == 0)
|
||||
if (sel == 0)
|
||||
{
|
||||
errno = ETIMEDOUT;
|
||||
err = -1;
|
||||
if (read_timer)
|
||||
goto read_timedout;
|
||||
else
|
||||
{
|
||||
errno = ETIMEDOUT;
|
||||
err = -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
err = GNUTLS_E_AGAIN;
|
||||
if (read_timer)
|
||||
{
|
||||
if ( (read_timer->next_timeout = read_timer->timeout - ptimer_measure (read_timer->timer)) <= 0 )
|
||||
{
|
||||
read_timedout: /* return GNUTLS_E_REAUTH_REQUEST for gnutls_read */
|
||||
err = GNUTLS_E_REAUTH_REQUEST;
|
||||
read_timer->timed_out = 1;
|
||||
break;
|
||||
}
|
||||
next_timeout = read_timer->next_timeout;
|
||||
}
|
||||
}
|
||||
else if (err < 0)
|
||||
{
|
||||
@ -614,7 +703,7 @@ _do_reauth (gnutls_session_t session, int fd, double timeout, int is_nonblock)
|
||||
}
|
||||
while (err && gnutls_error_is_fatal (err) == 0);
|
||||
|
||||
if (!is_nonblock && timeout)
|
||||
if (!read_timer && next_timeout)
|
||||
{
|
||||
#ifdef F_GETFL
|
||||
if (fcntl (fd, F_SETFL, flags) < 0)
|
||||
@ -840,7 +929,7 @@ ssl_connect_wget (int fd, const char *hostname, int *continue_session)
|
||||
}
|
||||
}
|
||||
|
||||
err = _do_handshake (session, fd, opt.read_timeout, 0);
|
||||
err = _do_handshake (session, fd, NULL);
|
||||
|
||||
if (err < 0)
|
||||
{
|
||||
|
@ -482,7 +482,8 @@ struct openssl_read_args
|
||||
int retval;
|
||||
};
|
||||
|
||||
static void openssl_read_peek_callback(void *arg)
|
||||
static void
|
||||
openssl_read_peek_callback(void *arg)
|
||||
{
|
||||
struct openssl_read_args *args = (struct openssl_read_args *) arg;
|
||||
struct openssl_transport_context *ctx = args->ctx;
|
||||
@ -506,9 +507,6 @@ openssl_read_peek (int fd, char *buf, int bufsize, void *arg, double timeout, ss
|
||||
struct openssl_transport_context *ctx = arg;
|
||||
int ret = SSL_pending (ctx->conn);
|
||||
|
||||
if (bufsize == 0)
|
||||
return 0;
|
||||
|
||||
if (ret)
|
||||
ret = fn (ctx->conn, buf, MIN (bufsize, ret));
|
||||
else
|
||||
@ -520,7 +518,6 @@ openssl_read_peek (int fd, char *buf, int bufsize, void *arg, double timeout, ss
|
||||
args.fn = fn;
|
||||
args.ctx = ctx;
|
||||
|
||||
errno = 0;
|
||||
if (timeout == -1)
|
||||
timeout = opt.read_timeout;
|
||||
|
||||
@ -540,14 +537,14 @@ openssl_read_peek (int fd, char *buf, int bufsize, void *arg, double timeout, ss
|
||||
#ifdef F_GETFL
|
||||
#define NONBLOCK_DECL int flags = 0;
|
||||
#define FD_SET_NONBLOCKED(_fd) \
|
||||
flags = fcntl (_fd, F_GETFL, 0);\
|
||||
if (flags < 0)\
|
||||
return flags;\
|
||||
if (fcntl (_fd, F_SETFL, flags | O_NONBLOCK))\
|
||||
return -1;
|
||||
flags = fcntl (_fd, F_GETFL, 0); \
|
||||
if (flags < 0) \
|
||||
return flags; \
|
||||
if (fcntl (_fd, F_SETFL, flags | O_NONBLOCK)) \
|
||||
return -1;
|
||||
#define FD_SET_BLOCKED(_fd) \
|
||||
if (fcntl (_fd, F_SETFL, flags) < 0)\
|
||||
return -1;
|
||||
if (fcntl (_fd, F_SETFL, flags) < 0) \
|
||||
return -1;
|
||||
#else
|
||||
#define NONBLOCK_DECL
|
||||
#define FD_SET_NONBLOCKED(_fd) \
|
||||
@ -574,8 +571,7 @@ openssl_read_peek (int fd, char *buf, int bufsize, void *arg, double timeout, ss
|
||||
_ret = -1; \
|
||||
else \
|
||||
{ \
|
||||
if (_timeout == -1) \
|
||||
_timeout = opt.read_timeout;
|
||||
double next_timeout = _timeout;
|
||||
|
||||
#define TIMER_FREE(_fd) \
|
||||
ptimer_destroy (timer); \
|
||||
@ -590,7 +586,6 @@ openssl_read_peek (int fd, char *buf, int bufsize, void *arg, double timeout, ss
|
||||
#define TIMER_WAIT(_fd, _conn, _ret, _timeout) \
|
||||
{ \
|
||||
int wait_for; \
|
||||
double next_timeout; \
|
||||
int err = SSL_get_error(_conn, _ret); \
|
||||
if (err == SSL_ERROR_WANT_READ) \
|
||||
wait_for = WAIT_FOR_READ; \
|
||||
@ -598,20 +593,18 @@ openssl_read_peek (int fd, char *buf, int bufsize, void *arg, double timeout, ss
|
||||
wait_for = WAIT_FOR_WRITE; \
|
||||
else \
|
||||
break; \
|
||||
next_timeout = _timeout - ptimer_measure (timer); \
|
||||
if (next_timeout < 0) \
|
||||
{ \
|
||||
timed_out = 1; \
|
||||
break; \
|
||||
} \
|
||||
err = select_fd_nb (_fd, next_timeout, wait_for); \
|
||||
if (err <= 0) \
|
||||
{ \
|
||||
if (err == 0) \
|
||||
timedout: \
|
||||
timed_out = 1; \
|
||||
_ret = -1; \
|
||||
break; \
|
||||
} \
|
||||
next_timeout = _timeout - ptimer_measure (timer); \
|
||||
if (next_timeout <= 0) \
|
||||
goto timedout; \
|
||||
}
|
||||
|
||||
static int
|
||||
@ -638,13 +631,10 @@ static int
|
||||
openssl_read_peek (int fd, char *buf, int bufsize, void *arg, double timeout, ssl_fn_t fn)
|
||||
{
|
||||
struct openssl_transport_context *ctx = arg;
|
||||
int ret;
|
||||
int ret = SSL_pending (ctx->conn);
|
||||
|
||||
if (bufsize == 0)
|
||||
return 0;
|
||||
/* avoid wrong 'interactive timeout' when errno == ETIMEDOUT */
|
||||
errno = 0;
|
||||
ret = SSL_pending (ctx->conn);
|
||||
if (timeout == -1)
|
||||
timeout = opt.read_timeout;
|
||||
/* If we have data available for immediate read, simply return that,
|
||||
or do blocked read when timeout == 0 */
|
||||
if (ret || timeout == 0)
|
||||
@ -689,7 +679,7 @@ openssl_poll (int fd, double timeout, int wait_for, void *arg)
|
||||
{
|
||||
struct openssl_transport_context *ctx = arg;
|
||||
SSL *conn = ctx->conn;
|
||||
if (SSL_pending (conn))
|
||||
if ((wait_for & WAIT_FOR_READ) && SSL_pending (conn))
|
||||
return 1;
|
||||
/* if (timeout == 0)
|
||||
return 1; */
|
||||
|
@ -417,6 +417,8 @@ fd_read_body (const char *downloaded_filename, int fd, FILE *out, wgint toread,
|
||||
timeout, so that the gauge can be updated regularly even
|
||||
when the data arrives very slowly or stalls. */
|
||||
tmout = 0.95;
|
||||
/* avoid wrong 'interactive timeout' */
|
||||
errno = 0;
|
||||
if (opt.read_timeout)
|
||||
{
|
||||
double waittm;
|
||||
|
Loading…
Reference in New Issue
Block a user