M
M
Maxim Korytko2021-09-27 20:18:23
ASIO
Maxim Korytko, 2021-09-27 20:18:23

Blocking call to io_context.run() and socket.connect(). How to fix?

When you enter an incorrect ip-address or port number, the code module using boost::asio goes into the block permanently.
Simple code example:

int main(int argc, char* argv[]){

namespace ba = boost::asio;
using ba::ip::tcp;

ba::io_service service;
tcp::socket s(service);

if (argc<3)
    return 255;

try {
    auto it = tcp::resolver(service).resolve({argv[1], argv[2]});
   
 s.connect(*it); // first resolved value


    std::cout << "Connected " << s.local_endpoint() << " -> " << s.remote_endpoint() << "\n";

    // demo write
    ba::write(s, ba::buffer("hello world\n"));
} catch (const boost::system::system_error& e) {
    std::cout << "ERROR:" << e.what() << "\n";
}}

There are no problems if it is known in advance that a valid and quite viable host is located at the address that we submitted to the program. For example, if you enter "127.0.0.1" or "192.168.10.17" (the address of one of the home machines), then the program will work correctly and display the coveted "Connected". However, if you enter an address like "1.2.3.4" or "12.13.14.15", "107.210.211.97" then at the moment the entire execution thread is blocked. Permanently. You can only terminate a program by manually terminating the process. More complex example:

s.connect(*it); // first resolved value



boost::asio::io_context io_context;
    boost::asio::ip::tcp::resolver resolver(io_context);
    boost::asio::ip::tcp::resolver::results_type endpoints;


    std::string address = ui->lineEdit_primaryServerAddress->text().toStdString();
    endpoints = resolver.resolve(address, INET_SERVICE);

    boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
    ctx.load_verify_file(SSL_CERT);

    rb_baseClient c(io_context, ctx, endpoints);
    c.set_request(CLNT_MSG_WHO_ARE_YOU);

    try
    {
        boost::system::error_code _ec2;
        io_context.run();
    }

    catch (std::exception& e)
    {
        io_context.stop();
        std::cerr << e.what() << std::endl;
        ui->label_primaryServerHostname->setStyleSheet("color: darkred");
        this->pServerIsAlive = false;
        emit pServerStatusChanged(false);
    }

    std::string reply=c.get_reply();

This is part of the code for the client of one of the projects. The program should connect to the host at the address received from the gui, check the validity of the software installed at the other end, and, depending on the replay, determine further elements of the graph. interface. If the address is correct, then everything works as intended. However, if you enter an incorrect address, for example, the same "1.2.3.4" or a decimal number, for example, "1" or "15212", then the execution thread goes into blocking mode at the moment

io_context.run();

Debug io_context.run(); is not possible.
The IO context is populated in the client class. Here is his cut:

rb_baseClient::rb_baseClient(boost::asio::io_context& io_context, boost::asio::ssl::context& context,
                             boost::asio::ip::tcp::resolver::results_type endpoints) :
    _socket(io_context, context), _endpoints(endpoints)
{
    //    memset(_reply, 0, max_length);
    //    memset(_request, 0, max_length);
    this->connect();
}


void rb_baseClient::connect()
{
try
{
    _socket.set_verify_mode(boost::asio::ssl::verify_peer);
    _socket.set_verify_callback(
                boost::bind(&rb_baseClient::verify_certificate, this, _1, _2));

    boost::asio::async_connect(_socket.lowest_layer(), _endpoints,
                               boost::bind(&rb_baseClient::handle_connect, this,
                                           boost::asio::placeholders::error));
}
catch (std::exception& e)
{
    cerr << "rb_baseClient::connect: " << e.what();
    strcpy(_reply, SERVER_CONNECTION_FAILED);
}
}

I consulted the official boost documentation, but could not find a solution to this problem there. I also tried to add deadline-timers - but it turned out to be useless. Google and Yandex did not help either.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question