[noPoll] Issue with using Secure Sockets client connecion (wss://) from Windows

Kale, Rahul Rahul.Kale en barco.com
Sab Nov 21 02:17:45 CET 2015


Hello,

We are using the latest published version of noPoll.
Your suggestion of blocking nopoll_conn_wait_until_connection_ready would not fix the
issue since the SSL_connect() returns error well before that (SSL_ERROR_SYSCALL).

As I mentioned in the original report,  I had put a small timeout as a workaround.
However, when we started testing against a Websocket server a long distance away
(California, US to Belgium) the problem resurfaced.

Yesterday, I spent some time digging into the problem further. Turns out that
if I increased the timeout to a large value (300 ms instead of 10 ms) the connection
starts working. I rationalized that if the TCP connect completes (3 way handshake)
before we hand the socket over to SSL/TLS for processing, the problem goes away.

So now I implemented a new workaround. I wait for the TCP connection to complete
before  telling SSL library the socket fd using SSL_set_fd().

I modified nopoll_conn.c as follows:

/* set socket */
wait_for_socket_connect(conn->session); // workaround -- RPK
SSL_set_fd (conn->ssl, conn->session);

Where the wait_for_socket_connect is implemented as follows in nopoll_conn.c :

static int wait_for_socket_connect(int socketfd)
{
    // On windows, when connect() is called on non-blocking call
    // connection succeeded if the socket is ready for writing
    fd_set write_fdset, except_fdset;
    struct timeval timeout;

    FD_ZERO(&write_fdset);
    FD_ZERO(&except_fdset);
    FD_SET((unsigned int) socketfd, &write_fdset );
    FD_SET((unsigned int) socketfd, &except_fdset );

    // Wait upto 2 seconds
    timeout.tv_sec =  0;
    timeout.tv_usec = 2000000;

    select( 0, NULL, &write_fdset, &except_fdset, &timeout);

    // connection failed
    if (FD_ISSET(socketfd, &except_fdset)) {
        return -1;
    }
    // successful connection
    else if (FD_ISSET(socketfd, &write_fdset)) {
        return 0;
    }
    return -1;
}

It is very strange that this problem occurs only from the second connection using
the library. You should be able to reproduce the problem using the test program
I posted in the original report. I understand that the OpenSSL library is supposed to
automatically take care of this and there should not be any need to wait
for the base TCP connection to be established beforehand. But for some reason it does not.

The above workaround is holding up for now but we would like to resolve this
properly.

Thanks,

Rahul

Rahul Kale

IP Video Systems
Barco, Inc
1287 Anvilwood Ave
Sunnyvale, CA  94089

Tel  +1 408 400 4238

From: Kale, Rahul
Sent: Thursday, November 19, 2015 3:14 PM
To: nopoll en lists.aspl.es
Cc: 'Francis Brosnan Blázquez'
Subject: RE: [noPoll] Issue with using Secure Sockets client connecion (wss://) from Windows


Hello,

Any resolution to the issue regarding this?
In spite of the workaround mentioned below, we see this fail
in certain cases.

Thanks,

Rahul

Rahul Kale

IP Video Systems
Barco, Inc
1287 Anvilwood Ave
Sunnyvale, CA  94089


From: nopoll-bounces en lists.aspl.es<mailto:nopoll-bounces en lists.aspl.es> [mailto:nopoll-bounces en lists.aspl.es] On Behalf Of Kale, Rahul
Sent: Tuesday, September 08, 2015 6:35 PM
To: nopoll en lists.aspl.es<mailto:nopoll en lists.aspl.es>
Subject: [noPoll] Issue with using Secure Sockets client connecion (wss://) from Windows


Hello,

I am facing an issue with using noPoll library for Secure Websockets (wss://)
client connection on Windows platform. Basically, the first connection from
the same binary works but subsequent connections do not work reliably.
When I tried to debug the issue, by enabling logs, the problem goes away.
Strangely, if I install my own log handler with an empty (do nothing)
implementation, the problem also goes away.
I have been trying to track down the problem the past week and finally have
something to report.

Firstly, I have isolated the code (see below) to the bare minimum below for you to reproduce the
issue. The code makes 100 back to back connections in a loop and exits the loop
early if it fails. This code rarely lasts for 2 or more loops. However if you
enable logs (setting nopoll_log_set_handler to true) or install a log
handler (using nopoll_log_set_handler), it will make 100 successful connections.

Since logging did not help, I ended up compiling the noPoll source myself for further
debugging. Since I am using VS 2008, I had to fix the code here and there to get it
to compile and also had to add __declspec(dllexport) to most functions in the header file.
By adding trial and error printfs I narrowed down the spot when it fails.
Whenever the connect fails, the SSL_connect() function errors out with
SSL_ERROR_SYSCALL at around line 756 in nopoll_conn.c.

Assuming that there is some timing issue (since logging adds just enough delay),
I have put a temporary fix as a workaround which fixes the issue: I added
a nopoll_sleep() just before SSL_connect() like so:

    nopoll_sleep (10000);
    while (SSL_connect (conn->ssl) <= 0) {
    ...


I am sure you will find the root cause and have a better fix.

Here is the sample code:

#include "nopoll.h"

static void noPollLogger(noPollCtx *ctx, noPollDebugLevel level, const char *log_msg, noPollPtr user_data) {
    // Do nothing here
}

int ConnectToWebsocket()
{

    noPollCtx * context = nopoll_ctx_new();

    //nopoll_log_set_handler(context, noPollLogger, NULL);
    nopoll_log_enable(context, false);

    noPollConnOpts * opts = nopoll_conn_opts_new();
    nopoll_conn_opts_ssl_peer_verify(opts, false); // disable cert verification
    noPollConn * connection = nopoll_conn_tls_new(context, opts, "10.1.2.3", "443", NULL,
        "wss://10.1.2.3:443/wstunnel/?dst=127.0.0.1:6060", "tunnel-protocol", "some-origin");

    bool connected = true;
    int count = 0;
    while (!nopoll_conn_is_ready(connection)) {
        if (!nopoll_conn_is_ok(connection)) {
            connected = false;
            break;
        }
        nopoll_sleep(10000);
        fprintf(stdout, "Info: Waiting for connection...\n", count++);
    }

    if (connected) {
       fprintf(stdout, "Info: Connected!!\n");
    }
    else {
       fprintf(stdout, "Failed websocket connection\n");
       exit(1);
    }

    nopoll_conn_close(connection);
    nopoll_ctx_unref(context);

    return 0;
}

int main(int argc, char *argv[])
{
    for (int i = 0; i < 100; i++) {
        ConnectToWebsocket();
        fprintf(stderr, "Done Loop %d\n", i);
    }
    return 0;
}

Thanks,

Rahul

Rahul Kale

IP Video Systems
Barco, Inc
1287 Anvilwood Ave
Sunnyvale, CA  94089

Tel  +1 408 400 4238

This message is subject to the following terms and conditions: MAIL DISCLAIMER<http://www.barco.com/en/maildisclaimer>
This message is subject to the following terms and conditions: MAIL DISCLAIMER<http://www.barco.com/en/maildisclaimer>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://lists.aspl.es/pipermail/nopoll/attachments/20151121/a9d47439/attachment-0001.html>


Más información sobre la lista de distribución noPoll