Open luzizheng opened 1 week ago
Yes, you can. You do it by configuring something called the "participant index":
<Domain>
<Discovery>
<ParticipantIndex>
X
</ParticipantIndex>
</Discovery>
</Domain>
and this X
can be none
, auto
, an integer ≥ 0 and ≤ N or default
(= none
or auto
, depending on some heuristics about multicast). If it is none
, you get this random port number. If it is auto
it tries integers from 0 .. M ≤ N, trying to bind sockets to the corresponding port numbers and failing if it doesn't find a number that works. So that leaves M, N and the resulting port numbers.
N ultimately comes from the limits on port numbers (the resulting port numbers must be ≤ 65535) and way the port numbers get calculated using this number. With the default settings, N ≤ 120 IIRC. M is Domain/Discovery/MaxAutoParticipantIndex
which used to be 9 but today got bumped to 99.
The mapping comes from the specification and can be configured using the elements under Domain/Discovery/Ports
. It is:
Base
+ DomainGain * domain_id
+ ParticipantGain * participant index
+ (UnicastMetaOffset and/or UnicastDataOffset)
With the defaults, for domain id 0, participant index 0 you get 7410/7411; participant index 1 you get 7412/7413; &c.
The normal way to get a static port number is by putting a number in ParticipantIndex
. If you really want to, you can also fix it by tweaking the port mapping, but that'll confuse everyone 🙂.
My configuration is as follows:
I then run a test program that creates two participants with domains 0 and 1. Then I use the ss tool to detect that there are two more dynamically bound random port numbers.
<Domain>
<Discovery>
<ParticipantIndex>0</ParticipantIndex>
</Discovery>
</Domain>
ss -tunlp | grep dds
udp UNCONN 0 0 10.13.83.236:38628 0.0.0.0.* user:(("test_dds_port",pid=17724,fd=10))
udp UNCONN 0 0 0.0.0.0:7410 0.0.0.0.* user:(("test_dds_port",pid=17724,fd=3))
udp UNCONN 0 0 0.0.0.0:7411 0.0.0.0.* user:(("test_dds_port",pid=17724,fd=4))
udp UNCONN 0 0 0.0.0.0:7660 0.0.0.0.* user:(("test_dds_port",pid=17724,fd=8))
udp UNCONN 0 0 0.0.0.0:7661 0.0.0.0.* user:(("test_dds_port",pid=17724,fd=9))
udp UNCONN 0 0 10.13.83.236:45700 0.0.0.0.* user:(("test_dds_port",pid=17724,fd=5))
Oy! I forgot about the sockets it creates for sending data. Those get a random port number and I don't think it can be configured otherwise currently ...
There is not much use for separate sockets for sending data if there's only one network interface in use, which is the common case for Cyclone. It is not difficult to change that, but it is a bit fiddly because the multicast transmit interface needs to be set and it does not do that for the sockets it uses to receive data.
I think it'll stop creating that extra socket and use the "unicast data" socket (i.e., the one at offset 11) if you change https://github.com/eclipse-cyclonedds/cyclonedds/blob/447912e79fd08e2a0dcb439a0022116a96267c90/src/core/ddsi/src/ddsi_init.c#L1567 to
if (gv->n_interfaces == 1 || gv->config.many_sockets_mode == DDSI_MSM_NO_UNICAST)
and you change: https://github.com/eclipse-cyclonedds/cyclonedds/blob/447912e79fd08e2a0dcb439a0022116a96267c90/src/core/ddsi/src/ddsi_udp.c#L602 to
set_mc_xmit_options = true;
but I haven't tried it ...
If you decide to give it a go, please let me know whether it works or not ☺️
One unicast port per domain participant it serves, chosen by the kernel from the list of anonymous ports, that is, >= 32768. Can this unicast port number be configured with a static port number?