open62541 / open62541

Open source implementation of OPC UA (OPC Unified Architecture) aka IEC 62541 licensed under Mozilla Public License v2.0
http://open62541.org
Mozilla Public License 2.0
2.59k stars 1.24k forks source link

EventLoop(UPD): Unicast connection does not work with localhost configuration #5915

Closed keba-estr closed 8 months ago

keba-estr commented 1 year ago

Description

The Address of the PubSub configuration contains an Url and a NetworkInterface. As I see it, the Url is the remote part including some remote URL and a port, whereas the NetworkInterface is the local network interface the connection should send to and receive from.

Opening a PubSub connection fails with the error trace "Error binding the socket to the address (Cannot assign requested address), closing".

Example: Url: opc.udp://192.168.10.1:4840 NetworkInterface: 192.168.10.2 where 192.168.10.1 is the remote server url and 192.168.10.2 is the ip address of the local network interface.

Background Information / Reproduction Steps

The function UA_PubSubConnection_connectUDP passes these parameters as key-value-pairs to the EventLoop. In the UDP EventLoop the "address" is read in UDP_openReceiveConnection and the resolved hostname is passed to UDP_registerListenSockets, where the function bind is called for this hostname. According to the documentation of bind this function should be called with a local address, not with a remote address.

Maybe the parameter "interface" should be used instead here?

The branch 1.3.5 sets addr.sin_addr.s_addr = INADDR_ANY; before calling UA_bind, so the remote address was not used there when calling UA_bind.

Checklist

Please provide the following information:

jpfr commented 1 year ago

Are you on linux? Try to use the network interface name (such as eth0).

If that doesn't confirm to the OPC UA standard we will change that behavior.

keba-estr commented 1 year ago

Are you on linux? Try to use the network interface name (such as eth0).

If that doesn't confirm to the OPC UA standard we will change that behavior.

Yes, it is a linux system.

If I change the NetworkInterface from 192.168.10.2 to eth1, the behaviour does not change, because the open62541 evaluates the Url for calling bind.

keba-estr commented 1 year ago

If i use the parameter "interface", at least the configuration is successful.

keba-estr commented 1 year ago

Excerpt of the PubSub specification (OPC 10000-14-Pubsub-1.05.02-2022-11-01.pdf):

7.3.2.3 UDP unicast For UDP unicast, the address information for the Subscriber is configured on the PubSubConnection and the address information for the Publisher is configured on the WriterGroup. The receive port for UDP unicast communication is configured on a PubSubConnection. The Address parameter for a PubSubConnection is defined in 6.2.7.3. All NetworkMessages for one port are received through one PubSubConnection. The filtering and assignment of NetworkMessages for the Subscriber is done based on the PublisherId. The hostname for the Url in the PubSubConnection Address parameter is set to ‘localhost’ since the source address is not used for filtering. The NetworkInterface field in the Address is not required and is only configured if the Subscriber should listen only on the configured interface. If the NetworkInterface is null or empty, the Subscriber should listen on all interfaces. The syntax of the Url field in the PubSubConnection Address parameter has the following form: opc.udp://localhost[:<port>] The destination address is configured on the datagram TransportSettings of a WriterGroup. The Address parameter for a WriterGroup datagram TransportSetting is defined in 6.4.1.3.4. The Address parameter for WriterGroup datagram TransportSettings shall be configured. If no Address is configured on a WriterGroup, the WriterGroup PubSubState shall be Error. The NetworkInterface field in the Address is not required and should be null or empty and shall be ignored. The syntax of Url field in the WriterGroup datagram TransportSettings Address parameter has the following form: opc.udp://<host>[:<port>] The host is either an unicast IP address or a registered name like a hostname or domain name that can be resolved to a unicast IP addresses. The IP address and the port are the destination of the UDP datagram. The IANA registered OPC UA port for UDP communication is 4840. This is the default and recommended port for unicast communication. Alternative ports may be used.

7.3.2.2 UDP multicast and broadcast The transport protocol URL for UDP multicast and broadcast communication is configured on a PubSubConnection for Publisher and Subscriber. The Address parameter for a PubSubConnection is defined in 6.2.7.3. The Url field in the Address is used as destination address for NetworkMessages sent as UDP datagram. The Address is also used to receive UDP datagrams from the multicast IP address. All DataSetWriters and DataSetReaders that send to and receive from the multicast IP address shall be configured on one PubSubConnection. The Address parameter for WriterGroup datagram TransportSettings shall be null. If an Address is configured on a WriterGroup, the WriterGroup PubSubState shall be Error. The NetworkInterface field in the Address is required if more than one network interface is available. The syntax of the UDP transport protocol URL used in the Address has the following form: opc.udp://

[:] The address is either an multicast or broadcast IP address or a registered name like a domain name that can be resolved to a multicast or broadcast IP address.. It is the destination of the UDP datagram. The IANA registered OPC UA port for UDP communication is 4840. This is the default and recommended port for broadcast and multicast communication. Alternative ports may be used. It is recommended to use switches with IGMP and MLD support to limit the distribution of multicast traffic to the interested participants.

keba-estr commented 1 year ago

Evaluation of addresses in open62541 is correct according to new specification.

keba-estr commented 1 year ago

@jpfr: The following part of the specification is not met with the open62541 1.4 branch:

The hostname for the Url in the PubSubConnection Address parameter is set to ‘localhost’ since the source address is not used for filtering. The NetworkInterface field in the Address is not required and is only configured if the Subscriber should listen only on the configured interface. If the NetworkInterface is null or empty, the Subscriber should listen on all interfaces.

If the hostname ist set to "localhost" or "127.0.0.1", the subscriber only listens to the localhost interface and not to all interfaces.

jpfr commented 1 year ago

If the hostname ist set to "localhost" or "127.0.0.1", the subscriber only listens to the localhost interface and not to all interfaces.

We could change the behavior so that localhost, 127.0.0.1 and "any IPv6 address for localhost" are used to trigger "listen on all interfaces".

I think right now only "localhost" does that.

Works for you?

keba-estr commented 1 year ago

"localhost"

At the moment only an empty hostname triggers "listen on all interfaces" for the UDP implementation. The change would be fine for me. The host name is evaluated correctly in this case. Is there a combination possible that the hostname is "localhost", but the networkinterface specifies some specific network for receiving? Or is this against the specification?