Implement Async SSL_shutdown
This extends the existing async functionality to SSL_shutdown(), i.e. SSL_shutdown() can now casuse an SSL_ERROR_WANT_ASYNC error to be returned from SSL_get_error() if async mode has been enabled. Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
This commit is contained in:
parent
35ade23b02
commit
ec4479249d
@ -218,6 +218,27 @@ static int restore_errno(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void do_ssl_shutdown(SSL *ssl)
|
||||
{
|
||||
int ret;
|
||||
|
||||
do {
|
||||
/* We only do unidirectional shutdown */
|
||||
ret = SSL_shutdown(ssl);
|
||||
if (ret < 0) {
|
||||
switch (SSL_get_error(ssl, ret)) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
case SSL_ERROR_WANT_ASYNC:
|
||||
/* We just do busy waiting. Nothing clever */
|
||||
continue;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
} while (ret < 0);
|
||||
}
|
||||
|
||||
|
||||
#ifndef OPENSSL_NO_PSK
|
||||
/* Default PSK identity and key */
|
||||
static char *psk_identity = "Client_identity";
|
||||
@ -2002,7 +2023,7 @@ int s_client_main(int argc, char **argv)
|
||||
reconnect--;
|
||||
BIO_printf(bio_c_out,
|
||||
"drop connection and then reconnect\n");
|
||||
SSL_shutdown(con);
|
||||
do_ssl_shutdown(con);
|
||||
SSL_set_connect_state(con);
|
||||
SHUTDOWN(SSL_get_fd(con));
|
||||
goto re_start;
|
||||
@ -2320,7 +2341,7 @@ int s_client_main(int argc, char **argv)
|
||||
shut:
|
||||
if (in_init)
|
||||
print_stuff(bio_c_out, con, full_log);
|
||||
SSL_shutdown(con);
|
||||
do_ssl_shutdown(con);
|
||||
SHUTDOWN(SSL_get_fd(con));
|
||||
end:
|
||||
if (con != NULL) {
|
||||
|
@ -190,10 +190,11 @@ struct ssl_async_args {
|
||||
SSL *s;
|
||||
void *buf;
|
||||
int num;
|
||||
int type;
|
||||
enum { READFUNC, WRITEFUNC, OTHERFUNC} type;
|
||||
union {
|
||||
int (*func1)(SSL *, void *, int);
|
||||
int (*func2)(SSL *, const void *, int);
|
||||
int (*func_read)(SSL *, void *, int);
|
||||
int (*func_write)(SSL *, const void *, int);
|
||||
int (*func_other)(SSL *);
|
||||
} f;
|
||||
};
|
||||
|
||||
@ -1469,10 +1470,15 @@ static int ssl_io_intern(void *vargs)
|
||||
s = args->s;
|
||||
buf = args->buf;
|
||||
num = args->num;
|
||||
if (args->type == 1)
|
||||
return args->f.func1(s, buf, num);
|
||||
else
|
||||
return args->f.func2(s, buf, num);
|
||||
switch (args->type) {
|
||||
case READFUNC:
|
||||
return args->f.func_read(s, buf, num);
|
||||
case WRITEFUNC:
|
||||
return args->f.func_write(s, buf, num);
|
||||
case OTHERFUNC:
|
||||
return args->f.func_other(s);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SSL_read(SSL *s, void *buf, int num)
|
||||
@ -1493,8 +1499,8 @@ int SSL_read(SSL *s, void *buf, int num)
|
||||
args.s = s;
|
||||
args.buf = buf;
|
||||
args.num = num;
|
||||
args.type = 1;
|
||||
args.f.func1 = s->method->ssl_read;
|
||||
args.type = READFUNC;
|
||||
args.f.func_read = s->method->ssl_read;
|
||||
|
||||
return ssl_start_async_job(s, &args, ssl_io_intern);
|
||||
} else {
|
||||
@ -1518,8 +1524,8 @@ int SSL_peek(SSL *s, void *buf, int num)
|
||||
args.s = s;
|
||||
args.buf = buf;
|
||||
args.num = num;
|
||||
args.type = 1;
|
||||
args.f.func1 = s->method->ssl_peek;
|
||||
args.type = READFUNC;
|
||||
args.f.func_read = s->method->ssl_peek;
|
||||
|
||||
return ssl_start_async_job(s, &args, ssl_io_intern);
|
||||
} else {
|
||||
@ -1546,8 +1552,8 @@ int SSL_write(SSL *s, const void *buf, int num)
|
||||
args.s = s;
|
||||
args.buf = (void *)buf;
|
||||
args.num = num;
|
||||
args.type = 2;
|
||||
args.f.func2 = s->method->ssl_write;
|
||||
args.type = WRITEFUNC;
|
||||
args.f.func_write = s->method->ssl_write;
|
||||
|
||||
return ssl_start_async_job(s, &args, ssl_io_intern);
|
||||
} else {
|
||||
@ -1569,6 +1575,18 @@ int SSL_shutdown(SSL *s)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
|
||||
struct ssl_async_args args;
|
||||
|
||||
args.s = s;
|
||||
args.type = OTHERFUNC;
|
||||
args.f.func_other = s->method->ssl_shutdown;
|
||||
|
||||
return ssl_start_async_job(s, &args, ssl_io_intern);
|
||||
} else {
|
||||
return s->method->ssl_shutdown(s);
|
||||
}
|
||||
|
||||
return s->method->ssl_shutdown(s);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user