6464import java .net .InetAddress ;
6565import java .net .NetworkInterface ;
6666import java .net .SocketException ;
67+ import java .net .UnknownHostException ;
6768import java .security .AccessController ;
6869import java .security .PrivilegedAction ;
6970import java .security .PrivilegedExceptionAction ;
7071import java .util .Enumeration ;
7172import java .util .HashMap ;
7273import java .util .Iterator ;
7374import java .util .Map ;
75+ import java .util .List ;
76+ import java .util .ArrayList ;
7477
7578public class Utils {
7679 private static final Log log = LogFactory .getLog (Utils .class );
@@ -569,6 +572,86 @@ public static int getMtomThreshold(MessageContext msgCtxt){
569572 }
570573 return threshold ;
571574 }
575+ /**
576+ * Returns all <code>InetAddress</code> objects encapsulating what are most likely the machine's
577+ * LAN IP addresses. This method was copied from apache-commons-jcs HostNameUtil.java.
578+ * <p>
579+ * This method will scan all IP addresses on all network interfaces on the host machine to
580+ * determine the IP addresses most likely to be the machine's LAN addresses.
581+ * <p>
582+ * @return List<InetAddress>
583+ * @throws IllegalStateException If the LAN address of the machine cannot be found.
584+ */
585+ public static List <InetAddress > getLocalHostLANAddresses () throws SocketException
586+ {
587+ final List <InetAddress > addresses = new ArrayList <>();
588+
589+ try
590+ {
591+ InetAddress candidateAddress = null ;
592+ // Iterate all NICs (network interface cards)...
593+ final Enumeration <NetworkInterface > ifaces = NetworkInterface .getNetworkInterfaces ();
594+ while ( ifaces .hasMoreElements () )
595+ {
596+ final NetworkInterface iface = ifaces .nextElement ();
597+
598+ // Skip loopback interfaces
599+ if (iface .isLoopback () || !iface .isUp ())
600+ {
601+ continue ;
602+ }
603+
604+ // Iterate all IP addresses assigned to each card...
605+ for ( final Enumeration <InetAddress > inetAddrs = iface .getInetAddresses (); inetAddrs .hasMoreElements (); )
606+ {
607+ final InetAddress inetAddr = inetAddrs .nextElement ();
608+ if ( !inetAddr .isLoopbackAddress () )
609+ {
610+ if (inetAddr .isSiteLocalAddress ())
611+ {
612+ // Found non-loopback site-local address.
613+ addresses .add (inetAddr );
614+ }
615+ if ( candidateAddress == null )
616+ {
617+ // Found non-loopback address, but not necessarily site-local.
618+ // Store it as a candidate to be returned if site-local address is not subsequently found...
619+ candidateAddress = inetAddr ;
620+ // Note that we don't repeatedly assign non-loopback non-site-local addresses as candidates,
621+ // only the first. For subsequent iterations, candidate will be non-null.
622+ }
623+ }
624+ }
625+ }
626+ if (candidateAddress != null && addresses .isEmpty ())
627+ {
628+ // We did not find a site-local address, but we found some other non-loopback address.
629+ // Server might have a non-site-local address assigned to its NIC (or it might be running
630+ // IPv6 which deprecates the "site-local" concept).
631+ addresses .add (candidateAddress );
632+ }
633+ // At this point, we did not find a non-loopback address.
634+ // Fall back to returning whatever InetAddress.getLocalHost() returns...
635+ if (addresses .isEmpty ())
636+ {
637+ final InetAddress jdkSuppliedAddress = InetAddress .getLocalHost ();
638+ if ( jdkSuppliedAddress == null )
639+ {
640+ throw new IllegalStateException ( "The JDK InetAddress.getLocalHost() method unexpectedly returned null." );
641+ }
642+ addresses .add (jdkSuppliedAddress );
643+ }
644+ }
645+ catch (UnknownHostException e )
646+ {
647+ var throwable = new SocketException ("Failed to determine LAN address" );
648+ throwable .initCause (e );
649+ throw throwable ;
650+ }
651+
652+ return addresses ;
653+ }
654+
572655 /**
573656 * Returns the ip address to be used for the replyto epr
574657 * CAUTION:
@@ -582,25 +665,9 @@ public static int getMtomThreshold(MessageContext msgCtxt){
582665 * - Obtain the ip to be used here from the Call API
583666 *
584667 * @return Returns String.
585- * @throws java.net.SocketException
586668 */
587669 public static String getIpAddress () throws SocketException {
588- Enumeration e = NetworkInterface .getNetworkInterfaces ();
589- String address = "127.0.0.1" ;
590-
591- while (e .hasMoreElements ()) {
592- NetworkInterface netface = (NetworkInterface ) e .nextElement ();
593- Enumeration addresses = netface .getInetAddresses ();
594-
595- while (addresses .hasMoreElements ()) {
596- InetAddress ip = (InetAddress ) addresses .nextElement ();
597- if (!ip .isLoopbackAddress () && isIP (ip .getHostAddress ())) {
598- return ip .getHostAddress ();
599- }
600- }
601- }
602-
603- return address ;
670+ return getLocalHostLANAddresses ().stream ().findFirst ().map (InetAddress ::toString ).orElse ("127.0.0.1" );
604671 }
605672
606673 /**
@@ -639,10 +706,6 @@ public static String getHostname(AxisConfiguration axisConfiguration) {
639706 return null ;
640707 }
641708
642- private static boolean isIP (String hostAddress ) {
643- return hostAddress .split ("[.]" ).length == 4 ;
644- }
645-
646709 /**
647710 * Get the scheme part from a URI (or URL).
648711 *
0 commit comments