Bug 62566 - hostinfo task unusable if network interface is multihomed
Summary: hostinfo task unusable if network interface is multihomed
Status: NEW
Alias: None
Product: Ant
Classification: Unclassified
Component: Core tasks (show other bugs)
Version: 1.10.5
Hardware: All HP-UX
: P2 major (vote)
Target Milestone: ---
Assignee: Ant Notifications List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-07-24 13:22 UTC by Michael Osipov
Modified: 2020-01-03 15:05 UTC (History)
1 user (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Osipov 2018-07-24 13:22:16 UTC
Using <hostinfo /> on a multihomed machine gives incorrect hostname and host address due to the best matching algorithm.

I have refactored Ant's code into a seperate class with a custom traversal for my machine interfaces:

> public static void main(String[] args) throws Exception {
> 	InetAddress lo = InetAddress.getLocalHost();
> 	System.out.println("InetAddress.getLocalHost():");
> 	System.out.println("  HostName: " + lo.getHostName());
> 	System.out.println("  CanonicalHostName: " + lo.getCanonicalHostName());
> 	System.out.println("  HostAddress: " + lo.getHostAddress());
> 
> 	Enumeration<NetworkInterface> ee = NetworkInterface.getNetworkInterfaces();
> 	System.out.println("Network Interfaces:");
> 	while (ee.hasMoreElements()) {
> 		NetworkInterface ni = ee.nextElement();
> 		if (!ni.isLoopback()) {
> 			System.out.println(
> 					"  " + ni + " (" + (ni.isVirtual() ? "virtual" : "physical") + ")");
> 			List<InetAddress> addrs = Collections.list(ni.getInetAddresses());
> 
> 			if (!addrs.isEmpty()) {
> 
> 				System.out.println("  Addresses:");
> 
> 				for (InetAddress inetAddress : addrs) {
> 					System.out.println("    " + inetAddress);
> 				}
> 			}
> 
> 			List<NetworkInterface> see = Collections.list(ni.getSubInterfaces());
> 			if (!see.isEmpty()) {
> 				System.out.println("    Virtual Network Interfaces:");
> 				for (NetworkInterface vni : see) {
> 					System.out.println("      " + vni + " ("
> 							+ (vni.isVirtual() ? "virtual" : "physical") + ")");
> 
> 					List<InetAddress> vaddrs = Collections.list(vni.getInetAddresses());
> 
> 					if (!vaddrs.isEmpty()) {
> 
> 						System.out.println("      Addresses:");
> 
> 						for (InetAddress inetAddress : vaddrs) {
> 							System.out.println("        " + inetAddress);
> 						}
> 					}
> 				}
> 			}
> 		}
> 	}
> 
> 	HostInfo hi = new HostInfo();
> 	hi.executeLocal();
> 	System.out.println("Ant's HostInfo task:");
> 	System.out.println("  " + hi.props);
> }

The output is:

> bash $ java HostInfo
> InetAddress.getLocalHost():
>   HostName: blnn724x.ad001.siemens.net
>   CanonicalHostName: blnn724x.ad001.siemens.net
>   HostAddress: 147.54.64.24
> Network Interfaces:
>   name:lan0 (lan0) (physical)
>   Addresses:
>     /147.54.65.7
>     /147.54.65.2
>     /147.54.64.24
>     Virtual Network Interfaces:
>       name:lan0:2 (lan0:2) (virtual)
>       Addresses:
>         /147.54.65.7
>       name:lan0:1 (lan0:1) (virtual)
>       Addresses:
>         /147.54.65.2
> Ant's HostInfo task:
>   {ADDR6=::1, ADDR4=147.54.65.7, DOMAIN=bln3.siemens.de, NAME=hp7v}

As you can see, the task is unusable on this host. I know that changing the code might break others, but a better option would be either to exclude addresses on virtual interfaces OR provide two strategies: bestmatch and localhost.

I am on Java 8 and HP-UX 11.31.
Comment 1 Jaikiran Pai 2018-07-29 13:33:38 UTC
Hi Michael,

Could you add the output of the following command:

ifconfig -a
Comment 2 Michael Osipov 2018-07-30 08:37:05 UTC
(In reply to Jaikiran Pai from comment #1)
> Hi Michael,
> 
> Could you add the output of the following command:
> 
> ifconfig -a

There is no a switch on HP-UX. There is a workaround like this:

> bash $ for i in `netstat -rn|egrep -v "Interface|Routing"|awk '{print $5}'`;do
> /usr/sbin/ifconfig $i;done
> lo0: flags=849<UP,LOOPBACK,RUNNING,MULTICAST>
>         inet 127.0.0.1 netmask ff000000
> lan0: flags=1843<UP,BROADCAST,RUNNING,MULTICAST,CKO>
>         inet 147.54.64.24 netmask fffffc00 broadcast 147.54.67.255
> lan0:2: flags=1843<UP,BROADCAST,RUNNING,MULTICAST,CKO>
>         inet 147.54.65.7 netmask fffffc00 broadcast 147.54.67.255
> lan0:1: flags=1843<UP,BROADCAST,RUNNING,MULTICAST,CKO>
>         inet 147.54.65.2 netmask fffffc00 broadcast 147.54.67.255
> lan0: flags=1843<UP,BROADCAST,RUNNING,MULTICAST,CKO>
>         inet 147.54.64.24 netmask fffffc00 broadcast 147.54.67.255
> lan0:2: flags=1843<UP,BROADCAST,RUNNING,MULTICAST,CKO>
>         inet 147.54.65.7 netmask fffffc00 broadcast 147.54.67.255
> lan0:1: flags=1843<UP,BROADCAST,RUNNING,MULTICAST,CKO>
>         inet 147.54.65.2 netmask fffffc00 broadcast 147.54.67.255
> lo0: flags=849<UP,LOOPBACK,RUNNING,MULTICAST>
>         inet 127.0.0.1 netmask ff000000
> lan0:1: flags=1843<UP,BROADCAST,RUNNING,MULTICAST,CKO>
>         inet 147.54.65.2 netmask fffffc00 broadcast 147.54.67.255
> lan0: flags=1843<UP,BROADCAST,RUNNING,MULTICAST,CKO>
>         inet 147.54.64.24 netmask fffffc00 broadcast 147.54.67.255
> lan0:2: flags=1843<UP,BROADCAST,RUNNING,MULTICAST,CKO>
>         inet 147.54.65.7 netmask fffffc00 broadcast 147.54.67.255
Comment 3 Stefan Bodewig 2018-07-30 08:47:59 UTC
NetworkInterface.isVirtual has been added with Java 6 so our hostinfo task - which predates it - didn't take it into account. I think it is reasonable to prefer non-virtual interfaces (which would require reflection if we wanted to do it in 1.9.x). Whether virtual is actually worse than site local or even link local is a different question that might require a new attribute or a pluggable strategy.
Comment 4 Michael Osipov 2018-07-30 10:45:46 UTC
(In reply to Stefan Bodewig from comment #3)
> NetworkInterface.isVirtual has been added with Java 6 so our hostinfo task -
> which predates it - didn't take it into account. I think it is reasonable to
> prefer non-virtual interfaces (which would require reflection if we wanted
> to do it in 1.9.x). Whether virtual is actually worse than site local or
> even link local is a different question that might require a new attribute
> or a pluggable strategy.

The funny thing is that you won't detect that at level 0 as you can see since you need to traverse all subinterfaces and compare addresses.
Comment 5 Stefan Bodewig 2018-07-30 12:56:03 UTC
Yes, I've seen that. getSubInterfaces also didn't exist before Java 6.

It looks as if NetworkInterface's semantics has changed between Java5 and Java6 and the hostinfo task relies on Java5's behavior. hostinfo's implementation performs a few checks on InetAddress that can now be performed on NetworkInterafce directly. I must admit I've never used the NetworkInteface class before, I'm just looking at the javadocs and the task't implementation.
Comment 6 Michael Osipov 2020-01-03 15:05:36 UTC
Just noticed that <hostinfo> is also unusable inside a FreeBSD Jail where host and jail reside in the same subnet.  Hostname "localhost" is returned while my custom code provided earlier says:

# freebsd-version
12.1-RELEASE
root@deblndw011x1j:/tmp
# java Test
InetAddress.getLocalHost():
  HostName: deblndw011x1j.ad001.siemens.net
  CanonicalHostName: deblndw011x1j.ad001.siemens.net
  HostAddress: 147.54.64.55
Network Interfaces:
  name:bge0 (bge0) (physical)
  Addresses:
    /147.54.64.149

Ant says:

Adding reference: ant.LocalProperties
parsing buildfile jar:file:/usr/local/share/java/apache-ant/lib/ant.jar!/org/apache/tools/ant/antlib.xml with URI = jar:file:/usr/local/share/java/apache-ant/lib/ant.jar!/org/apache/tools/ant/antlib.xml from a zip file
Setting project property: host.DOMAIN -> localdomain
Setting project property: host.NAME -> localhost
Setting project property: host.ADDR4 -> 147.54.64.149
Setting project property: host.ADDR6 -> ::1

I consider this element unusable, unfortunately.