Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add secure RawSocket example #72

Open
Bobface opened this issue Dec 26, 2015 · 15 comments
Open

Add secure RawSocket example #72

Bobface opened this issue Dec 26, 2015 · 15 comments

Comments

@Bobface
Copy link

Bobface commented Dec 26, 2015

Hello,

can I somehow connect to Secure WebSocket Servers (wss://)? I can't find a solution in the documentation.

@jpetso
Copy link
Contributor

jpetso commented Jan 15, 2016

Not as of now.

@davidchappelle has patches that might be merged into autobahn-cpp which generalize the transport interface. Theoretically this means that after these get merged, you could add a WebSocket transport yourself.

I'm not aware of any code that actually implements WebSockets from autobahn-cpp yet, though. (It might pop up in the future, or it might not.)

@oberstet
Copy link
Contributor

If you mean: WAMP-RawSocket over TLS .. that should work already. We need an example though.

If you specifically mean WAMP-WebSocket over TLS, as @jpetso notes, there has to be a proper transport abstraction first.

Second is adding WebSocket transport as one option - and that based on https://github.com/zaphoyd/websocketpp

Once that is done, secure WebSocket comes free, as websocketpp supports that.

@oberstet oberstet changed the title Connect to secure socket Add secure RawSocket example Jan 28, 2016
@davidchappelle
Copy link
Contributor

If anyone is looking to add websocket support to autobahn-cpp, please
connect with me as all of the transport abstraction work is already done.
It just needs to be broken up into smaller commits and merged back to the
master branch.

On Thu, Jan 28, 2016 at 1:06 PM, Tobias Oberstein notifications@github.com
wrote:

If you mean: WAMP-RawSocket over TLS .. that should work already. We need
an example though.

If you specifically mean WAMP-WebSocket over TLS, as @jpetso
https://github.com/jpetso notes, there has to be a proper transport
abstraction first.

Second is adding WebSocket transport as one option - and that based on
https://github.com/zaphoyd/websocketpp

Once that is done, secure WebSocket comes free, as websocketpp supports
that.


Reply to this email directly or view it on GitHub
#72 (comment)
.

@davidchappelle
Copy link
Contributor

With the way that the abstraction was done, I would expect it to be fairly
trivial to add websocket support.

On Thu, Jan 28, 2016 at 1:08 PM, David Chappelle chappedm@gmail.com wrote:

If anyone is looking to add websocket support to autobahn-cpp, please
connect with me as all of the transport abstraction work is already done.
It just needs to be broken up into smaller commits and merged back to the
master branch.

On Thu, Jan 28, 2016 at 1:06 PM, Tobias Oberstein <
notifications@github.com> wrote:

If you mean: WAMP-RawSocket over TLS .. that should work already. We need
an example though.

If you specifically mean WAMP-WebSocket over TLS, as @jpetso
https://github.com/jpetso notes, there has to be a proper transport
abstraction first.

Second is adding WebSocket transport as one option - and that based on
https://github.com/zaphoyd/websocketpp

Once that is done, secure WebSocket comes free, as websocketpp supports
that.


Reply to this email directly or view it on GitHub
#72 (comment)
.

@DZabavchik
Copy link

Tested wss:// with websocket transport, works as expected.

Tested with the following setup:

Crossbar.io router behind AWS ELB (SSL 443 -> TCP PVT Port)

#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>

typedef websocketpp::client<websocketpp::config::asio_tls_client> websocket_client;
typedef autobahn::wamp_websocketpp_websocket_transport<websocketpp::config::asio_tls_client> websocket_transport;

Configure TLS init handler for Websocket client

    websocket_client client;
    client.set_tls_init_handler([this](websocketpp::connection_hdl) {
        return websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv1);
    });
    transport = std::make_shared < autobahn::wamp_websocketpp_websocket_transport<websocketpp::config::asio_tls_client> >(
        client, "wss://host.domain.com");

@oberstet
Copy link
Contributor

@DZabavchik Nice. Thanks for leaving code/comments for WS example here!

@sashakh
Copy link

sashakh commented Jul 16, 2016

Hi,

Does current autobahn-cpp code works with wss:// ? Or some patches still be needed. I've tried something like this:

`
#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>

typedef websocketpp::clientwebsocketpp::config::asio_tls_client client;
typedef autobahn::wamp_websocketpp_websocket_transportwebsocketpp::config::asio_tls_clientwebsocket_transport;

    client ws_clinet;
    ws_clinet.set_tls_init_handler([&](websocketpp::connection_hdl) {
            return websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv1);
    });
    ws_clinet.init_asio(&io);

    auto transport = std::make_shared < autobahn::wamp_websocketpp_websocket_transport<websocketpp::config::asio_tls_client> >(
        ws_clinet, "wss://127.0.0.1:8443/ws", debug);

`

, but without success (however it works with autobahn-python). The error is:

Connecting to realm: realm1
starting io service
[2016-07-16 18:39:21] [info] Error getting remote endpoint: system:107 (Transport endpoint is not connected)
[2016-07-16 18:39:21] [fail] WebSocket Connection Unknown - "" /ws 0 websocketpp.transport:9 Timer Expired
[2016-07-16 18:39:21] [error] handle_connect error: Timer Expired
[2016-07-16 18:39:21] [info] asio async_shutdown error: asio.ssl:336462100 (uninitialized)
stopped io service
failed to connect

Any suggestions? Could you probably to show full example?

Thanks!

@DZabavchik
Copy link

Autobahn-cpp does work with wss://

Since you are connecting to wss://localhost I assume you are using self-signed certificate.

You may need to add your CA cert to trusted root CA file.

Regards,

Denis

On Jul 16, 2016, at 20:59, Sasha Khapyorsky notifications@github.com wrote:

Hi,

Does current autobahn-cpp code works with wss:// ? Or some patches still be needed. I've tried something like this:

`
#include
#include

typedef websocketpp::clientwebsocketpp::config::asio_tls_client client;
typedef autobahn::wamp_websocketpp_websocket_transportwebsocketpp::config::asio_tls_clientwebsocket_transport;

client ws_clinet;
ws_clinet.set_tls_init_handler([&](websocketpp::connection_hdl) {
        return websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv1);
});
ws_clinet.init_asio(&io);

auto transport = std::make_shared < autobahn::wamp_websocketpp_websocket_transport<websocketpp::config::asio_tls_client> >(
    ws_clinet, "wss://127.0.0.1:8443/ws", debug);

`

, but without success (however it works with autobahn-python). The error is:

Connecting to realm: realm1
starting io service
[2016-07-16 18:39:21] [info] Error getting remote endpoint: system:107 (Transport endpoint is not connected)
[2016-07-16 18:39:21] [fail] WebSocket Connection Unknown - "" /ws 0 websocketpp.transport:9 Timer Expired
[2016-07-16 18:39:21] [error] handle_connect error: Timer Expired
[2016-07-16 18:39:21] [info] asio async_shutdown error: asio.ssl:336462100 (uninitialized)
stopped io service
failed to connect

Any suggestions? Could you probably to show full example?

Thanks!


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@sashakh
Copy link

sashakh commented Jul 16, 2016

Thanks for the quick replay Denis,

Actually I'm not using localhost (just placed this name in the example). Also it works without any problem with autobahn-python, but doesn't with autobahn-cpp.

Probably it is some mess with types. For instance I cannot see where:

typedef autobahn::wamp_websocketpp_websocket_transport<websocketpp::config::asio_tls_client> websocket_transport;

is used.

Maybe you have some simple example (like wss_publish.cpp or so?

Many Thanks,
Sasha

@DZabavchik
Copy link

DZabavchik commented Jul 16, 2016

Typedef is just not used. You could do:

auto transport = std::make_shared < websocket_transport >(ws_client, "wss://host/ws");

Any chance TLSv1 is disabled on the server? Can you run Crossbar with debug logging and see what server says when you try to connect? How do you initialize OpenSSL library (ciphers, algos and CA file).

Some related issues:
zaphoyd/websocketpp#263
zaphoyd/websocketpp#360

@sashakh
Copy link

sashakh commented Jul 17, 2016

I will try to verify the server, however it may take some time (it is not mine). Many Thanks!

@sashakh
Copy link

sashakh commented Jul 19, 2016

Hi, There are logs... Not so clear for me (

From autobahn-cpp side:

starting io service
[2016-07-19 18:15:43] [connect] Successful connection
[2016-07-19 18:15:43] [error] handle_transport_init received error: TLS handshake failed
[2016-07-19 18:15:43] [fail] WebSocket Connection 52.29.34.99:8443 - "" /ws 0 websocketpp.transport.asio.socket:8 TLS handshake failed
[2016-07-19 18:15:43] [info] asio async_shutdown error: asio.ssl:336462231 (shutdown while in init)
stopped io service
failed to connect

From server side:

2016-07-19T15:13:39+0000 [Router 5017 crossbar.router.protocol.WampWebSocketServerProtocol] dropping connection: None
2016-07-19T15:13:39+0000 [Router 5017 crossbar.router.protocol.WampWebSocketServerProtocol] Connection to/from tcp4:80.235.34.78:51424 was lost in a non-clean fashion: Connection lost
2016-07-19T15:13:39+0000 [Router 5017 crossbar.router.protocol.WampWebSocketServerProtocol] _connectionLost: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionLost'>: Connection to the other side was lost in a non-clean fashion: Connection lost.
]
2016-07-19T15:13:39+0000 [Router 5017 crossbar.router.protocol.WampWebSocketServerProtocol] WAMP-over-WebSocket transport lost: wasClean=True, code=1001, reason="None"
2016-07-19T15:13:39+0000 [Controller 5012 crossbar.controller.processtypes.RouterWorkerProcess] Worker worker-001 -> Controller traffic: {2: {'count': 301, 'bytes': 171683}, 3: {'count': 8, 'bytes': 3923}}

-----------AND ---------------

2016-07-19T15:15:08+0000
[Router 5017 crossbar.router.protocol.WampWebSocketServerProtocol] Unable to format event {'log_logger': <Logger 'crossbar.router.protocol.WampWebSocketServerProtocol'>, 'log_source': None, 'log_format': "parsed WebSocket extension 'permessage-deflate' with params '{'client_max_window_bits': [True]}'", 'log_time': 1468941308.227039}: u"'client_max_window_bits'"
2016-07-19T15:15:08+0000 [Router 5017 crossbar.router.protocol.WampWebSocketServerProtocol] client request permessage-compress extension, but we did not accept any offer [[PerMessageDeflateOffer(acceptNoContextTakeover = True, acceptMaxWindowBits = True, requestNoContextTakeover = False, requestMaxWindowBits = 0)]]

@sashakh
Copy link

sashakh commented Nov 28, 2016

I've found the problem finally. crossbario supports only TLS v1.2 clients. So using:

ws_clinet.set_tls_init_handler([&](websocketpp::connection_hdl) {
        return websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv12_client);
});

makes it to work.

Thanks for the help!

@xandrrix
Copy link

xandrrix commented Mar 1, 2017

I'm having an issue implementing the utilization of wss/wamp with a combination of websocketpp and autobahn|cpp libraries.

Ultimately, my issue is that calling connect_future = transport->connect() results in a segmentation fault of sorts.

The fault is happening in boost::asio::detail::strand_service& boost::asio::use_serviceboost::asio::detail::strand_service(boost::asio::io)service&) io_service.hpp (line 33). Here is a screenshot of the call stack (http://imgur.com/bWV25WB). As the error (at the end of this post) suggests, I have tried adding -fno-limit-debug-info while compiling with no difference in results. This error happens when compiled using clang or g++ (aka it makes no difference). It's an odd error output that seems like something that should be a compilation error rather than a runtime error. Very strange (to me).

The web socket feed I'm attempting to utilize is found here (https://poloniex.com/support/api/).

Any thoughts, ideas, or advice on what I'm doing wrong in my code (below) would be extremely appreciated. If there's any other information I can provide to help investigate this, please don't hesitate to let me know!

Includes I'm using:

#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>
#include <iostream>
#include <string>
#include <stdio.h>
#include <exception>
#include <autobahn/autobahn.hpp>
#include <autobahn/wamp_websocketpp_websocket_transport.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include <memory>
#include <tuple>

Code With An Issue

try {
        boost::asio::io_service io;

        typedef websocketpp::client<websocketpp::config::asio_tls_client> websocket_client;
        typedef autobahn::wamp_websocketpp_websocket_transport<websocketpp::config::asio_tls_client> websocket_transport;

        websocket_client client;
        client.set_tls_init_handler([&](websocketpp::connection_hdl) {
            return websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv12_client);
        });
        auto transport = std::make_shared < autobahn::wamp_websocketpp_websocket_transport<websocketpp::config::asio_tls_client> >(
                client, "wss://api.poloniex.com");

        //auto transport = std::make_shared<autobahn::wamp_tcp_transport>(
        //        io, parameters->rawsocket_endpoint(),true);

        // create a WAMP session that talks WAMP-RawSocket over TCP
        auto session = std::make_shared<autobahn::wamp_session>(io, true);

        transport->attach(std::static_pointer_cast<autobahn::wamp_transport_handler>(session));

        // Make sure the continuation futures we use do not run out of scope prematurely.
        // Since we are only using one thread here this can cause the io service to block
        // as a future generated by a continuation will block waiting for its promise to be
        // fulfilled when it goes out of scope. This would prevent the session from receiving
        // responses from the router.
        boost::future<void> connect_future;
        boost::future<void> start_future;
        boost::future<void> join_future;
        boost::future<void> subscribe_future;
        connect_future = transport->connect().then([&](boost::future<void> connected) {
            try {
                connected.get();
            } catch (const std::exception& e) {
                std::cerr << e.what() << std::endl;
                io.stop();
                return;
            }

            std::cerr << "transport connected" << std::endl;

            start_future = session->start().then([&](boost::future<void> started) {
                try {
                    started.get();
                } catch (const std::exception& e) {
                    std::cerr << e.what() << std::endl;
                    io.stop();
                    return;
                }

                std::cerr << "session started" << std::endl;

                join_future = session->join("realm1").then([&](boost::future<uint64_t> joined) {
                    try {
                        std::cerr << "joined realm: " << joined.get() << std::endl;
                    } catch (const std::exception& e) {
                        std::cerr << e.what() << std::endl;
                        io.stop();
                        return;
                    }

                    subscribe_future = session->subscribe("ticker", &on_topic1).then([&] (boost::future<autobahn::wamp_subscription> subscribed)
                    {
                        try {
                            std::cerr << "subscribed to topic: " << subscribed.get().id() << std::endl;
                        }
                        catch (const std::exception& e) {
                            std::cerr << e.what() << std::endl;
                            io.stop();
                            return;
                        }

                    });
                });
            });
        });

        std::cerr << "starting io service" << std::endl;
        io.run();
        std::cerr << "stopped io service" << std::endl;
    }
    catch (std::exception& e) {
        std::cerr << "exception: " << e.what() << std::endl;
        return 1;
    }

Results/Errors Output:

Boost: 106300
Connecting to realm: realm1
Exception: EXC_BAD_ACCESS (code=1, address=0x0)
error: bitbot_tests.cpp.o DWARF DIE at 0x0015aea5 (class connection<websocketpp::config::asio_tls_client::transport_config>) has a member variable 0x0015b017 (m_tcp_pre_init_handler) whose type is a forward declaration, not a complete definition.
Try compiling the source file with -fno-limit-debug-info
error: bitbot_tests.cpp.o :: Class 'endpoint<websocketpp::connection<websocketpp::config::asio_tls_client>, websocketpp::config::asio_tls_client>' has a base class 'websocketpp::config::asio_tls_client::transport_type' which does not have a complete definition.
error: bitbot_tests.cpp.o :: Try compiling the source file with -fno-limit-debug-info.

@xandrrix
Copy link

xandrrix commented Mar 1, 2017

Hi again all. I actually fixed my issue and in so doing, I think I've created an example of using secure RawSocket/WebSocket.

Includes:

#include <autobahn/autobahn.hpp>
#include <autobahn/wamp_websocketpp_websocket_transport.hpp>
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
#include <boost/version.hpp>
#include <iostream>
#include <memory>
#include <string>
#include <tuple>

Solution:

typedef websocketpp::client<websocketpp::config::asio_tls_client> client;
    typedef autobahn::wamp_websocketpp_websocket_transport<websocketpp::config::asio_tls_client> websocket_transport;

    try {
        //std::cerr << "Connecting to realm: " << parameters->realm() << std::endl;

        boost::asio::io_service io;
        //bool debug = parameters->debug();

        client ws_client;
        ws_client.init_asio(&io);
        ws_client.set_tls_init_handler([&](websocketpp::connection_hdl) {
            return websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv12_client);
        });
        auto transport = std::make_shared < autobahn::wamp_websocketpp_websocket_transport<websocketpp::config::asio_tls_client> >(
                ws_client, "wss://api.poloniex.com:443", true);

        //auto transport = std::make_shared<autobahn::wamp_tcp_transport>(
        //        io, parameters->rawsocket_endpoint(),true);

        // create a WAMP session that talks WAMP-RawSocket over TCP
        auto session = std::make_shared<autobahn::wamp_session>(io, true);

        transport->attach(std::static_pointer_cast<autobahn::wamp_transport_handler>(session));

        // Make sure the continuation futures we use do not run out of scope prematurely.
        // Since we are only using one thread here this can cause the io service to block
        // as a future generated by a continuation will block waiting for its promise to be
        // fulfilled when it goes out of scope. This would prevent the session from receiving
        // responses from the router.
        boost::future<void> connect_future;
        boost::future<void> start_future;
        boost::future<void> join_future;
        boost::future<void> subscribe_future;
        connect_future = transport->connect().then([&](boost::future<void> connected) {
            try {
                connected.get();
            } catch (const std::exception& e) {
                std::cerr << e.what() << std::endl;
                io.stop();
                return;
            }

            std::cerr << "transport connected" << std::endl;

            start_future = session->start().then([&](boost::future<void> started) {
                try {
                    started.get();
                } catch (const std::exception& e) {
                    std::cerr << e.what() << std::endl;
                    io.stop();
                    return;
                }

                std::cerr << "session started" << std::endl;

                join_future = session->join("realm1").then([&](boost::future<uint64_t> joined) {
                    try {
                        std::cerr << "joined realm: " << joined.get() << std::endl;
                    } catch (const std::exception& e) {
                        std::cerr << e.what() << std::endl;
                        io.stop();
                        return;
                    }

                    subscribe_future = session->subscribe("BTC_ETH", &on_topic1).then([&] (boost::future<autobahn::wamp_subscription> subscribed)
                    {
                        try {
                            std::cerr << "subscribed to topic: " << subscribed.get().id() << std::endl;
                        }
                        catch (const std::exception& e) {
                            std::cerr << e.what() << std::endl;
                            io.stop();
                            return;
                        }

                    });
                });
            });
        });

        std::cerr << "starting io service" << std::endl;
        io.run();
        while(1){
            cout<<"looping..."<<endl;
            sleep(1);
        }
        std::cerr << "stopped io service" << std::endl;
    }
    catch (std::exception& e) {
        std::cerr << "exception: " << e.what() << std::endl;
        ret_var.successfully_ran = false;
		return ret_var;
    }
    return ret_var;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants