public static InetAddress findConnectingAddress ( InetSocketAddress targetAddress , long maxWaitMillis , long startLoggingAfter ) throws IOException { if ( targetAddress == null ) { throw new NullPointerException ( "targetAddress must not be null" ) ; } if ( maxWaitMillis <= 0 ) { throw new IllegalArgumentException ( "Max wait time must be positive" ) ; } final long startTimeNanos = System . nanoTime ( ) ; long currentSleepTime = MIN_SLEEP_TIME ; long elapsedTimeMillis = 0 ; final List < AddressDetectionState > strategies = Collections . unmodifiableList ( Arrays . asList ( AddressDetectionState . LOCAL_HOST , AddressDetectionState . ADDRESS , AddressDetectionState . FAST_CONNECT , AddressDetectionState . SLOW_CONNECT ) ) ; // loop while there is time left while ( elapsedTimeMillis < maxWaitMillis ) { boolean logging = elapsedTimeMillis >= startLoggingAfter ; if ( logging ) { LOG . info ( "Trying to connect to " + targetAddress ) ; } // Try each strategy in order for ( AddressDetectionState strategy : strategies ) { InetAddress address = findAddressUsingStrategy ( strategy , targetAddress , logging ) ; if ( address != null ) { return address ; } } // we have made a pass with all strategies over all interfaces // sleep for a while before we make the next pass elapsedTimeMillis = ( System . nanoTime ( ) - startTimeNanos ) / 1_000_000 ; long toWait = Math . min ( maxWaitMillis - elapsedTimeMillis , currentSleepTime ) ; if ( toWait > 0 ) { if ( logging ) { LOG . info ( "Could not connect. Waiting for {} msecs before next attempt" , toWait ) ; } else { LOG . debug ( "Could not connect. Waiting for {} msecs before next attempt" , toWait ) ; } try { Thread . sleep ( toWait ) ; } catch ( InterruptedException e ) { throw new IOException ( "Connection attempts have been interrupted." ) ; } } // increase the exponential backoff timer currentSleepTime = Math . min ( 2 * currentSleepTime , MAX_SLEEP_TIME ) ; } // our attempts timed out. use the heuristic fallback LOG . warn ( "Could not connect to {}. Selecting a local address using heuristics." , targetAddress ) ; InetAddress heuristic = findAddressUsingStrategy ( AddressDetectionState . HEURISTIC , targetAddress , true ) ; if ( heuristic != null ) { return heuristic ; } else { LOG . warn ( "Could not find any IPv4 address that is not loopback or link-local. Using localhost address." ) ; return InetAddress . getLocalHost ( ) ; } }
Finds the local network address from which this machine can connect to the target address . This method tries to establish a proper network connection to the given target so it only succeeds if the target socket address actually accepts connections . The method tries various strategies multiple times and uses an exponential backoff timer between tries .