warmcat / libwebsockets

canonical libwebsockets.org networking library
https://libwebsockets.org
Other
4.72k stars 1.48k forks source link

ssl/tls alert handshake failure with binance websocket api #3114

Closed nathanaxel closed 4 months ago

nathanaxel commented 4 months ago

Overview

I'm quite new to Libwebsockets (LWS) and have explored the minimal examples. Unfortunately, I haven't figured out why the WebSocket API isn't working, though WebSocket data streams and HTTP with Binance are functioning correctly.

Documentation

You can find more information on the WebSocket API provided by Binance here: Binance WebSocket API Documentation

Simplified Code Example

Here's a simplified version of my code:


#include <libwebsockets.h>
#include <string>
#include <cstring>
#include <iostream>

static int callback_websockets(struct lws *wsi, enum lws_callback_reasons reason,
                               void *user, void *in, size_t len) {
    switch (reason) {
        case LWS_CALLBACK_CLIENT_ESTABLISHED:
            std::cout << "Connection established" << std::endl;
            lws_callback_on_writable(wsi);
            break;

        case LWS_CALLBACK_CLIENT_RECEIVE:
            std::cout << "Received data: " << std::string((const char*)in, len) << std::endl;
            break;

        case LWS_CALLBACK_CLIENT_WRITEABLE: {
            std::string json_msg = R"({"id": "922bcc6e-9de8-440d-9e84-7c80933a8d0d", "method": "ping"})";
            int m = lws_write(wsi, (unsigned char*)json_msg.c_str(), json_msg.length(), LWS_WRITE_TEXT);
            if (m < static_cast<int>(json_msg.length())) {
                std::cerr << "ERROR: Writing to socket failed." << std::endl;
                return -1;
            }
            std::cout << "Sent message: " << json_msg << std::endl;
            break;
        }

        case LWS_CALLBACK_CLOSED:
        case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
            std::cout << "Disconnected." << std::endl;
            break;

        default:
            break;
    }
    return 0;
}

static const struct lws_protocols protocols[] = {
    {
        "test",
        callback_websockets,
        0,
        512, // Adjust according to your needs
    },
    { NULL, NULL, 0, 0 } // Terminator
};

int main() {
    struct lws_context_creation_info info;
    memset(&info, 0, sizeof(info));
    info.port = CONTEXT_PORT_NO_LISTEN;
    info.protocols = protocols;
    info.gid = -1;
    info.uid = -1;
    info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;

    struct lws_context *context = lws_create_context(&info);
    if (context == nullptr) {
        std::cerr << "Creating WebSocket context failed." << std::endl;
        return -1;
    }

    struct lws_client_connect_info ccinfo = {0};
    ccinfo.context = context;
    ccinfo.address = "testnet.binance.vision.com";
    ccinfo.port = 443;
    ccinfo.path = "/ws-api/v3";
    ccinfo.host = lws_canonical_hostname(context);
    ccinfo.origin = ccinfo.host;
    ccinfo.protocol = protocols[0].name;
    ccinfo.ssl_connection = LCCSCF_USE_SSL;

    struct lws* wsi = lws_client_connect_via_info(&ccinfo);
    if (wsi == nullptr) {
        std::cerr << "WebSocket connection failed." << std::endl;
        lws_context_destroy(context);
        return -1;
    }

    while (true) {
        lws_service(context, 1000);  // Process pending WebSocket events and perform callbacks
    }

    lws_context_destroy(context);
    return 0;
}
nathanaxel commented 4 months ago

I solved it by putting the SNI into the host. Thank you, I am closing it now