When an EJB client application interacts with a clustered Wildfly deployment, it receives topology updates from cluster nodes describing the membership of the cluster.
For each node in the cluster, a set of one or more client mappings is provided to indicate how the client may connect to the node, if it hasn't already. If the node is connected to a single network, there will be one client mapping; if the node is multi-homed and connected to two networks, there will be two client mappings, etc. Client mappings specify three things: a CIDR representation of the network the client may be on, a destination hostname or IP address and a destination port.
Client mappings may be generated by default (if none are provided in the server profile) or may be specified by the user via client mappings defined in the socket binding of the Remoting connector. For example:
When the client mapping information is received by the EJB client application, it is added to the discovered node registry (DNR) in the Discovery component of the EJB client. The DNR represents all known information about nodes with which the client can interact which was received from nodes in one or more clusters.
When an invocation is attempted, the Discovery component uses this information to generate a set of ServiceURLs which represent candidate targets (i.e. servers containing the deployment and module the client is invoking on) for the invocation. The Discovery component uses "an algorithm" to take the information in the DNR (and other places) and convert that information to a corresponding set of ServiceURLs representing available targets. The Discovery component will then select one such ServiceURL and return this as the target for the invocation. For example, in the above case, the service URL will look something like:
This service URL describes a server with logical name "node1" which:
- is a member of a cluster called "ejb"
- has the EJB module "my-foo-app/my-bar-module" and all the beans that it contains deployed
- can be connected to by the URL "remote://22.214.171.124:1099" as long as you are on network "126.96.36.199/24"
Discovery obtains node information used in the algorithm from various sources: client mappings associated with cluster nodes, as described above, as well as Remoting endpoints associated with established connections to nodes. These pieces of information describe at a minimum a host and a port.
The problem is that "the algorithm" used in Discovery to compute the set of ServiceURLs treats hostnames and IP addresses as simple strings. So "localhost" and "127.0.0.1" are treated as different hosts, even though they refer to the same host. If a mix of hostnames and IP addresses for the same node is received, this results in an incomplete/incorrect set of ServiceURLs being generated which in turn leads to incorrect Discovery failures.