Next Tutorial: Logging Previous Tutorial: Security
Overview
In this tutorial, we are going to create two nodes that are not able to communicate with the default configuration of Gazebo Transport. This limitation arises when the nodes are separated by a router, typically when they are part of different local networks. Routers do not propagate UDP multicast traffic and this is the reason for this limitation. We'll create a scenario to simulate this configuration, and then we'll enable the relay capabilities of Gazebo Transport to make the communication possible.
Setup
We'll use Docker to configure the environment for this example. Feel free to install Docker following any of the existing guides available (here's one).
We're going to build a Docker image and run it inside your host computer. Download the build.bash, run.bash and Dockerfile files.
Now, it's time to build the Docker image:
Run your Docker container:
Inside the docker instance, go to the example
directory:
Back on your host, make sure that you have Gazebo Tools and net-tools installed:
Now, let's configure Gazebo Transport to block all multicast traffic going into your Docker instance. Run the command ifconfig
to list your network interfaces:
We want to isolate Gazebo Transport to the network interface not connected to your Docker instance. Thus, try to identify the IP address of the network interface not associated with Docker or the loopback interface. In our case, the IP address is 172.23.1.7
.
Launch the publisher
Go back to the terminal inside the Docker container and run the publisher example:
Launch the subscriber
Open a terminal in your host and launch your subscriber, forcing Gazebo Transport to only bind to the IP address that we found in the previous step:
You shouldn't receive anything as the discovery messages are not reaching both nodes.
Now, setup your host to relay messages to the node running inside your Docker container. For that purpose, you'll need to know the IP address used in your Docker container. Run the ifconfig
command inside your Docker instance:
Go back to your terminal in the host and configure the environment variable GZ_RELAY
with the IP address used inside the container.
Now, you should receive the messages, as your node in the host is directly relaying the discovery messages inside your Docker instance via unicast.
Known limitations
Keep in mind that the end points of all the nodes should be reachable both ways. The relay feature will overcome the UDP multicast limitation but remember that after the discovery phase the nodes will exchange data directly using a different set of end points. These end points should be reachable from any node, otherwise the communication will not work.
Example: Imagine that you're running a publisher in your home machine. Typically, you'll be using a private IP address behind your home router doing NAT. If you try to run a subscriber node inside a computer over the internet using a public IP, things will not work even using GZ_RELAY
. The discovery protocol will reach the subscriber and back (thanks to the NAT), but things will stop at that point. The real data exchange will not be possible, as the subscriber will not be able to communicate with the publisher's endpoint using a private IP address. A solution to this problem is to create a VPN to create the abstraction that both machines are within the same local network.