Асинхронный прием сокета ssl с использованием asio и c

#c #ssl #asynchronous #boost-asio #asio

#c #ssl #асинхронный #boost-asio #asio

Вопрос:

Я пытаюсь написать асинхронный сервер с использованием asio с зашифрованными сокетами SSL. В настоящее время у меня есть код, который не использует SSL, и после выполнения этого руководства у меня есть общее представление о том, как принимать сокет SSL, однако я не знаю, как адаптировать этот код для приема SSL-соединения:

 void waitForClients() {

    acceptor.async_accept(
        [this](std::error_code ec, asio::ip::tcp::socket socket) {
            if (!ec) {
                Conn newConn = std::make_shared<Connection>(ctx, std::move(socket));
                connections.push_back(newConn);

            } else {
                std::cerr << "[SERVER] New connection error: " << ec.message() << "n";
            }
            waitForClients();
        }
    );
}

//this is how the tutorial shows to accept a connection
ssl_socket socket(io_context, ssl_context);
acceptor.accept(socket.next_layer());
 

Проблема в том, что обратный вызов for acceptor.async_accept выдает обычный asio::ip::tcp::socket , а не an asio::ssl::ssl_socket<asio::ip::tcp::socket> , и я не могу найти никакой документации, которая предполагает, что существует метод async_accept ввода SSL-сокета таким образом. Единственный метод, который я видел, — это сначала создать сокет, а затем принять его впоследствии, что невозможно сделать таким асинхронным способом.

Любая помощь будет высоко оценена.

Комментарии:

1. Если у вас уже есть код, который делает это для сокета, отличного от SSL, вы можете просто использовать те же вещи, чтобы принять сокет SSL. Если вопрос заключается в том, как использовать потоки или писать асинхронный код в целом на c , тогда удалите все сокеты и asio из вашего вопроса и сделайте базовый пример запуска / присоединения к потоку. Если ни один из них не применяется, вам следует уточнить свой вопрос.

2. @super Я попытался добавить пояснения к своему вопросу, но я не совсем уверен, что неясно, если есть что-то конкретное, было бы неплохо узнать.

3. Я никогда не использовал это сам, но быстрый взгляд на документацию показывает typedef ssl::stream<tcp::socket> ssl_socket; . Таким ssl_socket образом, в данном случае это просто оболочка вокруг обычного сокета. Итак, обычный сокет — это то, что вам нужно. Просто оберните его в ssl::stream.

4. @super Я не был уверен, смогу ли я создать an ssl_socket из существующего сокета, а не принимать подключение к an ssl_socket напрямую. Но стоит попробовать

5. Я действительно не вижу проблемы. В acceptor.accept(socket.next_layer()); вы передаете сокет в accept . Почему вы не можете просто сделать то же самое для async_accept ?

Ответ №1:

Я решил проблему, поняв, что вторым аргументом конструктора asio::ssl::stream<asio::ip::tcp::socket> является любой инициализатор для базового типа asio::ip::tcp::socket . Таким образом, проблема может быть решена:

 void waitForClients() {
    acceptor.async_accept(
        [this](std::error_code ec, asio::ip::tcp::socket socket) {
            if (!ec) {
                //initialise an ssl stream from already created socket
                asio::ssl::stream<asio::ip::tcp::socket> sslStream(sslCtx, std::move(socket);
                //then pass it on to be used
                Conn newConn = std::make_shared<Connection>(ctx, sslStream);
                connections.push_back(newConn);

            } else {
                std::cerr << "[SERVER] New connection error: " << ec.message() << "n";
            }
            waitForClients();
        }
    );
}
 

Комментарии:

1. Я просто пытался убедить вас в информации, которую вы предоставляете в комментариях. Вы сказали, что речь идет об управлении временем жизни. Я только изложил это для вас. Я почти уверен, что это именно то, что сказал вам мой второй комментарий. Но, эй, отличная работа по ее решению.

2. Оставляя комментарий, чтобы помочь другим в будущем: похоже, порядок аргументов для инициализатора ssl::stream был изменен (?), Поэтому std::move(сокет) теперь должен быть перед контекстом