Can DDS protocol be used to communicate between devices connected to different networks?How? - data-distribution-service

I am trying to implement a publish and subscribe hello world program for communication between 2 devices using eclipse cyclone DDS protocol, I am able to do it when devices are connected in the same network but when devices are in a different network there is no communication happening. As per my understanding, it's because of the default DDS domain but how do I change it?
I followed https://github.com/eclipse-cyclonedds/cyclonedds
Here there's a mention to make use of an XML file, but I am not understanding how to use it or where to use the file.
Any suggestion would be of much help, thank you!

Cyclone DDS looks at the value of the CYCLONEDDS_URI environment variable to find its configuration file. What you can do is make an XML file somewhere on your computer and put its path in that environment variable. E.g., on Linux:
export CYCLONEDDS_URI=/path/to/cdds.xml
or on Windows (“cmd”, I don’t know how to do it in powershell):
set "CYCLONEDDS_URI=c:/path/to/cdds.xml"
Windows is a bit tricky with the quotes, this seems to work fine. Then, when you start your application, Cyclone DDS will read that file and apply the settings in it. Of course you also need to know what to put in it.
For that, it is useful to know a few things about the networks you are using. In one network, it all works without any configuration because the UDP/IP multicast works semi-magically in a single network. If there are multiple networks, there is a router in between and those routers are often configured not to route multicast traffic.
That means you basically have two options:
Configure the routers to route multicast traffic between the networks (especially the 239.255.0.1 address used by default by DDS). If that works, you’re all set, no need to configure anything in Cyclone DDS.
Disable the use of multicast and instead list the hostnames/IP addresses of the machines you want to communicate with in the configuration file. You still need a router willing to route traffic from the one network to the other, but that is usually not a problem with unicast packets. (If for example you can ping it or login to it remotely, it’s fine.)
For (2), something like:
<CycloneDDS>
<Domain>
<General>
<AllowMulticast>false</AllowMulticast>
</General>
<Discovery>
<ParticipantIndex>auto</ParticipantIndex>
<Peers>
<Peer Address="ip-of-node-1" />
<Peer Address="ip-of-node-2" />
<Peer Address="ip-of-node-3" />
/Peers>
</Discovery>
</Domain>
</CycloneDDS>
should work (obviously with the ip-of-node-1 &c. replaced with the correct addresses/hostnames). Setting “AllowMulticast” to false simply disables all use of multicast. If multicast doesn’t work reliably with all nodes, assuming it works can give a broken system. So at this stage, it is definitely easier to just not use it.
The “ParticipantIndex” has to do with the UDP port numbers it uses. With multicast, multiple processes on a single machine can all use the same UDP port number for receiving the discovery packets, and so there is this agreed-upon port number for discovery that makes everything work without any configuration (port number 7400 for domain id 0). That in turn allows it to use random port numbers for receiving unicast traffic.
With unicast, however, each process needs to have its own unique port number, and that in turn means the other processes need to know to which port numbers to send the data to. Setting the “ParticipantIndex” to auto forces it use predictable port numbers so that the processes can find each other.

Related

Wireguard with dynamic setup for iot

At the moment we have multiple raspberry pies placed at different locations on different networks.
Our current solution to be able to reach them if something goes wrong is auto-ssh with jump host.
Recently I stumbled on Wireguard which could be another more slim way to solve the calling home problem.
The problem is that we would like the setup phase to be more dynamic, we don't want to do special configuration per node we have out there, we just want them to call home with a key and then be apart of the network.
Two questions:
Is Wireguard for us or are there other problems that I can't foresee here.
Is there a way to set it up dynamically with one key and let the clients get random ips?
wireguard always needs a unique keypair / host. So not what you are looking for.
If you just want a phone home option with ip connectivity I would suggest an openvpn server and client. If you use a username/password config (not using certificates), you can reuse the config on multiple clients. Openvpn will act as an dhcp server.
an howto:
https://openvpn.net/community-resources/how-to/
search for:
client-cert-not-required
The option that Maxim Sagaydachny is also valid for command access, an alternative to salt could be puppet with mco/bolt.
On any option you choose, be sure that the daemon restarts when it crashes, reboots, fails...
for systemd services this would be an override with:
[service]
restart=always

Approaches for having multiple applications receive data via port 80

I'm looking for suggestions about approaches to allow multiple applications to use port 80 for communication.
I know it's impossible, or at lease not sensible to have multiple applications to actually bind to port 80, however, I've seen appliances when there is a device that provides both a web interface (HTTP) and RTSP with RTP using port 80.
I have two ideas on how this is achieved:
Are those custom made apps that implement all the functions?
For example the same binary is used for a web server and a RTSP server. That seems kind of limiting due to the fact that you would have to do sever modifications to already developed apps if you want, for example, Apache and openSSH both on port 80.
Are there a "port 80 multiplexers" sort of a pattern?
For example, a parser application that listens to port 80 and depending on the header of the received package, passes the package to the required application.
Found some related references, will give them a try.
https://bbs.archlinux.org/viewtopic.php?id=99457
http://www.rutschle.net/tech/sslh.shtml
I really don't think this is possible in a standard way: port number is actually the one that allows multiplexing among different applications in TCP and UDP protocols. More generic, TSAP, Transport Service Access Point allows multiplexing at the transport layer. TSAP is the port in protocols such as TCP, UDP, or SCTP.
One reason you may want two applications listening on the same port is that a second application can monitor or process in some other way the messages received, and eventually processed, by the first one. In this case, using pcap library other applications could read messages received by the main application that will probably response those messages.
Netfilter can also be useful, http://www.netfilter.org/
However, if you intend two applications to respond messages that arrive to the same port, that would be tricky and would have dependency on each application.
In this response I'm assuming you are thinking of applications listening to the same port at the same IP address. Something different is working with multihost servers where two applications could listen to same port number in different IP addresses.

UPnP auto select external port

I am trying to make an application that utilizes UPnP if necessary to open ports so incoming transmissions can be received. The thing is, I don't want to specify an external port (because one, the external port doesn't matter for the application to be found, and two, I want to make sure multiple people on the same router can use the application, and sharing a port is not an option, obviously). None of the API's I'm looking at says anything about begin able to not specifying a port, but would sending something like 0 or -1 cause it to choose a port itself, or do I have to choose a random number and hope for the best?
Also, will the port mappings ever expire, or do I have to forcefully de-map all of them? I was wondering for in-case the application crashes or the computer looses power or something.

SOCAT to redirect UDP don't work!

I'm trying to transmit data in UDP datagrams into a client in external location to a pc in my local lan.
But my network is over a ADSL modem sending to a pc with Slackware, this pc redirect packages into other pcs.
I'm using socat to redirect UDP:
socat -v udp-listen:1935,fork,reuseaddr udp:192.168.0.40:37000
In LAN the conection is fine, but external IPs don't work.
Somebody help?
I don't think socat is the culprit, however consider to use stone instead of socat, because using a fork() for each received packet is a bit weird. Stone is called in your case like this (I think):
stone -n -d -d -d -d 192.168.0.40:37000/udp 1935/udp
Now why external IPs perhaps do not work. Sadly your text does not tell much about your setup, so I have to guess:
It depends on your firewall/modem/router if it is able to forward UDP packets. Usually, if you initiate the UDP requests from the inside, the router will open a NAT connection, which often means, that not only the source IP of the packets change, but the source port as well. As UDP is connectionless, UDP NAT connections usually time out very quickly, say after 5 minutes, if no data is transferred on them.
If the UDP must be opened in the opposite direction (from Internet to Intranet), the router usually discards all the UDP packets coming in from Internet, because it does not know where to forward them to. A router cannot just choose some arbitrary machine, this would be a security hole. So in the "Internet connecting to a machine behind the router" you must open the UDP port on the router and let it forward to the right machine. In that case packets sent from your internal machine will get their source IP and the source port rewritten, the machine on the Internet always will see the packets as coming from your router. So except for the additional rule in the router this case is the same as the outgoing case.
Note that there are several different ways how to make NAT (symmetric, etc.) and several methods on how to open a port on the router (Config, UPnP, etc.) so the ways to poke some holes into it always depends on your hardware capabilities. This all cannot be answered here.
Some other ideas what might go wrong as well:
Some UDP protocols encode IP addresses within the payload. In that case it is not enough just to forward the packets, you must change the payload as well to correct the IP addresses exchanged to enable all machines to talk together. Such UDP protocols are badly designed, anyway, because you never should assume that two arbitrary machines can directly talk with each other, so all good protocols should support easy proxying.
Some ISPs filter certain UDP ports, for arbitrary reason. If you have problems talking from Internet to your DSL, try with two external machines directly connected to different ISPs. If these can talk via UDP check if you can talk from your Intranet to one of the external machines. If this still works, this means, that you can talk backwards as well, as usually UDP is not a directed protocol, but if there is some NAT involved you somehow must make sure that the communication ports stay open.
Mobile Internet plans often do not support P2P. This probably means, those plans do not support Internet at all, as IP, by definition, is P2P. What the ISPs really want to say with "no P2P" is (my guess), that connections from Internet to the mobile device are not supported. In that case you always must initiate a connection from the mobile device, so you cannot use push methods (Internet to Mobile), the mobile device always must pull (data from Internet). Some broadband/cable providers might do the same. Usually you can see this if your ISP hands out an IP in the 10.x.y.z range to you.
There might be another trick how to get the connection working:
Ask your ISP to get some IPv6. Perhaps use 6to4. With IPv6 you eliminate NAT completely, your local LAN then directly interconnects to the Internet on IPv6. Be sure to activate your firewall/iptables on your Intranet host on the IPv6 interface, else you might see Intruders very quickly.
HTH

Can we use WCF Discovery to discover services outside your local network?

Is it possible to use WCF discovery to access services that reside outside your local network ?
The short answer is no.
Discovery uses a UDP broadcast packet. You can discover anything that your UDP broadcast packet is allowed to reach. There is the catch, most routers, firewalls, and commercial switches block udp broadcast packets. You may be able to change the settings on your router where you connect to the next larger network (or internet), and you 'might' extend your discovery slightly. Again though, the very next switch or router you hit will most likely be set to block udp.
In this situation, most people design a "report in" server. This is one static place to which all other hosts and clients and pre-programmed to "report in" on startup. This one server keeps a table of where all hosts and clients are, and if one client wants to find a certain host, it asks this main server for the uri of the host its looking for.
EDIT:
Robin mentioned increasing the TTL (Time To Live) from the default of 1 to a higher number. Maybe this will help someone.
https://serverfault.com/a/619825/146341