一、Async mode的功能
Asyn mode是OpenSSL支持异步I/O(AIO)的模式,在这个模式下openssl把硬件加速卡等不占用cpu的操作剥离出来,单独交给一个叫asyn job的结构去做。在asyn job执行的过程中,cpu可以把当前任务暂停,切换上下文(保存/恢复栈,寄存器等,用__setjump, longjump实现)返回给user。User需要主动(或者等待硬件加速卡的事件通知)去poll这个async job的状态,是否是ASYNC_FINISHED状态。如果是,说明之前的任务已经完成,则可以继续后面的操作(取回加密/解密结果)。
二、Async相关数据结构
比较重要的数据结构:
ASYNC_JOB: fibrectx用来保存和恢复栈、寄存器;waitctx指向SSL的waitctx。
async_ctx: 全局唯一,currjob指向一个ASYNC_JOB;dispatcher用来保存和恢复栈、寄存器,与ASYNC_JOB的fibrectx配合使用。
三、Async mode相关API
开启Async mode可以使用:SSL_CTX_set_mode(ctx, SSL_MODE_ASYNC)或SSL_set_mode(ssl, SSL_MODE_ASYNC)。在user调用SSL_do_handshake()(SSL_read()/SSL_write()类似)时,会调用到ssl_start_async_job():
3578 int SSL_do_handshake(SSL *s)
3579 {
3580 int ret = 1;
3581
3582 if (s->handshake_func == NULL) {
3583 SSLerr(SSL_F_SSL_DO_HANDSHAKE, SSL_R_CONNECTION_TYPE_NOT_SET);
3584 return -1;
3585 }
3586
3587 ossl_statem_check_finish_init(s, -1);
3588
3589 s->method->ssl_renegotiate_check(s, 0);
3590
3591 if (SSL_in_init(s) || SSL_in_before(s)) {
3592 if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
3593 struct ssl_async_args args;
3594
3595 args.s = s;
3596
3597 ret = ssl_start_async_job(s, &args, ssl_do_handshake_intern);
3598 } else {
3599 ret = s->handshake_func(s);
3600 }
3601 }
3602 return ret;
3603 }
ASYNC_get_current_job()就是返回全局的async_ctx->currjob,如