Lightning-rod represents the point of contact with the Cloud infrastructure allowing the end users to manage the board resources even if they are behind a NAT or a strict firewall.
The only assumption that can (for all purposes, always) be considered true is outgoing Web traffic being permitted, i.e., board-initiated communication over standard HTTP/HTTPS ports. We thus resorted to an HTTP-borne mechanism for bidirectional connectivity and reachability of internal services, namely WebSockets.
WebSockets, as channels between a browser and a server, are considered standard facilities for bidirectional communication and in particular server-pushed messaging.
In accordance to typical use cases targeted by these older mechanisms, WebSockets enable the server to push unsolicited content to the browser without waiting for a request.
Messages can thus be passed back and forth while keeping the connection open creating a two-way (bi-directional) ongoing conversation between a browser and the server.
One of the main advantages of WebSockets is that they are network agnostic, by just piggybacking communication onto standard HTTP interactions. As anticipated, this is of benefit for those environments which block Web-unrelated traffic using firewalls.
Less explored is:
the creation of generic TCP tunnels over WS, a way to get client-initiated connectivity to any server-side local (or remote) service.
devised a design and implementation of a novel reverse tunneling technique, as a way to provide server-initiated, e.g., Cloud-triggered, connectivity to any board-hosted service, or any other node on a contributed resource network, e.g., a WSN.
In particular the latter may enable typical IoT scenarios, e.g., Machine-to-Machine (M2M) interactions, by supporting these patterns in a device-centric fashion: having a gateway act not only as a proxy for access to data gathered from mostly passive resources, but also as a relay to activate remoting toward nodes in a masqueraded network.
This is ensured by a WAMP and WebSocket-based communication between the Stack4Things lightning-rod engine and its Cloud counterpart.
The communication layer is implemented within a set of libraries, implementing the client-side functionalities of the WAMP protocol.
Moreover, another WebSocket library enables the engine to act as a WebSocket reverse tunneling server, connecting to a specific WebSocket server running in the Cloud.
This allows internal services to be directly accessed by external users through the WebSocket tunnel whose incoming traffic is automatically forwarded to the internal daemon (e.g., SSH, HTTP, Telnet) under consideration.
Outgoing traffic is redirected to the WebSocket tunnel and eventually reaches the end user that connects to the WebSocket server running in the Cloud in order to interact with the board service.
As remote infrastructure, boards are possibly going to be available over very restrictive, IPv4-only deployments.
The figure above depicts systems, flows and interactions of such a WS reverse tunnel (abbreviated as rtunnel), in the case of board-provided access to a service hosted on the board itself.
By leveraging the diagram, in the following we outline the sequence of operations for the setup of a rtunnel.
The rtunnel client (e.g., a board) first sends a WS connection request to the rtunnel server, specifying a TCP port.
When the rtunnel server receives the WS connection request, a new TCP server is brought up listening on the specified port, the WS request is then accepted, and a WS connection (depicted in the figure as “control WS”) is started.
When an external TCP client tries to connect to the TCP server on the rtunnel server side, the new TCP connection is paused and, through the control WS, a WS message is sent in order to signal the request for a new TCP connection, and specify a unique ID for that connection.
When the rtunnel client receives the message signaling the request for a new TCP connection, it sends a new WS connection request to the rtunnel server, specifying the ID of the connection.
When the rtunnel server receives the WS connection request, it checks if the received ID does not match any of the existing TCP connections and, if so, it accepts the request and opens a new WS connection (depicted in figure as “WS tunnel”).
The new TCP connection thus gets piped to the new WS connection (that acts as a WS-encapsulated tunnel for TCP segments) and then resumed.
On the WS rtunnel client side, as soon as the new WS tunnel is established, a new TCP client is brought up connecting to the local service of interest, and such a new TCP connection gets piped to the new WS tunnel.
TCP segments coming from the external TCP client are now able to reach the local service, and traffic thus gets to flow back and forth until the rtunnel is torn down.