Отсрочка выхода сопрограммы

Кажется, моя проблема проистекает из того факта, что openssl не имеет стиля передачи продолжения для обратных вызовов, таких как указание имени сервера (SNI), но я пытаюсь заставить его использовать его.

Я хочу не блокировать рабочий поток при чтении SSL-сообщений клиентов и не блокировать рабочий поток, пока я отказываюсь возвращать обратный вызов SNI, ожидая завершения рукопожатия ssl-сервера (поэтому я могу заново подписать сертификат сервера).

Для asio bsaed повторная подпись SSL-прокси с использованием boost::asio::ssl::stream обертка для openssl.

я использую SSL_CTX_set_tlsext_servername_* помощники, чтобы получить обратный вызов во время согласования SSL с клиентом.

В настоящее время убедитесь, что я использую сопрограмму и рукопожатие внутри лямбда от boost::asio::spawn на strand, Я использую обратный вызов с указанием имени сервера (соответствующим образом завернутый), чтобы я мог заблокировать клиентское рукопожатие во время серверного рукопожатия, но без блокировки рабочего потока (совместная подпрограмма будет приостановлена.

boost::asio::spawn(strand_, [=](boost::asio::yield_context yield){
boost::system::error_code ec;
boost::system::error_code ec_server;

sni_callback = [=,&ec](std::string server_name) {
server_->ssl_connection->ssl_socket.async_handshake(boost::asio::ssl::stream_base::client, yield[ec_server]);
/* Todo: sign the server certificate and replace the ssl_socket SSL_CTX here */
};

ssl_connection->ssl_socket.handshake(boost::asio::ssl:stream_base::server, ec);

if (! ec) ec = ec_server;

handler(ec);
});

Но я понимаю, что рукопожатие ssl с клиентом заблокирует рабочий поток, когда он завершит работу.

Я попытался Asyc рукопожатие с клиентом:

  ssl_connection->ssl_socket.async_handshake(boost::asio::ssl:stream_base::server, yield[ec]);

но программа выдает ошибку в yield во время оболочки обработчика SNI.

Несомненно, это потому, что неблокирующее рукопожатие не вызывает обработчик SNI в сопрограмме — и единственный способ, которым он может это сделать (без блокировки рабочего потока), — это если все его внутренние обработчики вызываются в сопрограмме, но Я знаю, что он использует внутреннюю прядь для своей работы.

Со всеми загруженными символами совместно используемой библиотеки (даже для libstdc ++ и т. Д.) Трассировка стека:

.#0  0x000000000000000c in ?? ()
.#1  0x00007f8200000000 in ?? ()
.#2  0x00007f829e15043d in CRYPTO_free (str=0x7f828c054640) at mem.c:401
.#3  0x00007f829e1faba5 in ASN1_primitive_free (pval=<optimized out>, it=<optimized out>) at tasn_fre.c:261
.#4  0x00007f828c052250 in ?? ()
.#5  0x0000000000000005 in ?? ()
.#6  0x00007f828c0524f0 in ?? ()
.#7  0x0000000000000005 in ?? ()
.#8  0x00007f829d30c560 in ?? ()
.#9  0x00007f829d30c710 in ?? ()
.#10 0x000000000000000c in ?? ()
.#11 0x00007f828c0180b4 in ?? ()
.#12 0x00007f829e15043d in CRYPTO_free (str=0x7f828c052250) at mem.c:401
.#13 0x00007f829e1eb2cf in EVP_PKEY_CTX_free (ctx=<optimized out>) at pmeth_lib.c:381
.#14 0x00007f829e1de1e2 in EVP_MD_CTX_cleanup (ctx=0x7f829d30c590) at digest.c:394
.#15 0x00007f829e5041c1 in tls1_PRF (digest_mask=262400, seed1=0x7f829e5213fb, seed1_len=15, seed2=0x7f829d30c720, seed2_len=-1639094656, seed3=0x0,
seed3_len=-1657747584, seed4=0x23635fe, seed4_len=-1657747600, sec=0x7f82a0035df0 "\321\365M\236\202\177", slen=<optimized out>, out1=0x7f82a0035178 "d\356@",
out2=0x7f82a0038508 "", olen=4247053, seed5_len=0, seed5=0x0) at t1_enc.c:272
.#16 0x00007f829e4dbb18 in ?? () from /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0
.#17 0x00007f829d30c780 in ?? ()
.#18 0x00000000023635fe in ?? ()
.#19 0x00007f829d30c770 in ?? ()
.#20 0x00007f82a0035df0 in ?? ()
.#21 0x0000000000000000 in ?? ()

Я ожидаю, что это трассировка стека во время очистки от ошибки.

Чтобы вызвать обработчик SNI в той же сопрограмме, я думаю, что мне нужно, чтобы все промежуточные обратные вызовы ssl :: stream выполнялись в этой сопрограмме.
Есть ли прямой способ сделать это?

Интересно, может ли boost :: ssl вызывать свои обработчики в своей собственной цепочке, но все еще в стеке сопрограмм, это единственное исправление, но я не знаю, достаточно ли у магии asio_handler_invoke с обработчиком магии, чтобы это произошло, даже если это было возможно. Как вы можете вложить asio_handler_invoke для запуска на сопрограмме (strand-y сама по себе) И через внутреннюю цепочку.

Также я должен использовать asio_invoke_handler в последней строке моего примера?

4

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector