diff -r b44a353664b8 -r da638a97c27a jdk/src/share/classes/sun/security/krb5/KdcComm.java --- a/jdk/src/share/classes/sun/security/krb5/KdcComm.java Mon Jul 15 14:44:50 2013 +0200 +++ b/jdk/src/share/classes/sun/security/krb5/KdcComm.java Mon Jul 15 18:17:23 2013 +0100 @@ -46,6 +46,7 @@ import java.util.List; import java.util.Set; import java.util.HashSet; +import java.util.Iterator; import sun.security.krb5.internal.KRBError; /** @@ -203,7 +204,6 @@ if (obuf == null) return null; - Exception savedException = null; Config cfg = Config.getInstance(); if (realm == null) { @@ -218,49 +218,62 @@ if (kdcList == null) { throw new KrbException("Cannot get kdc for realm " + realm); } - String tempKdc = null; // may include the port number also + // tempKdc may include the port number also + Iterator tempKdc = KdcAccessibility.list(kdcList).iterator(); + if (!tempKdc.hasNext()) { + throw new KrbException("Cannot get kdc for realm " + realm); + } byte[] ibuf = null; - for (String tmp: KdcAccessibility.list(kdcList)) { - tempKdc = tmp; - try { - ibuf = send(obuf,tempKdc,useTCP); - KRBError ke = null; + try { + ibuf = sendIfPossible(obuf, tempKdc.next(), useTCP); + } catch(Exception first) { + while(tempKdc.hasNext()) { try { - ke = new KRBError(ibuf); - } catch (Exception e) { - // OK - } - if (ke != null && ke.getErrorCode() == - Krb5.KRB_ERR_RESPONSE_TOO_BIG) { - ibuf = send(obuf, tempKdc, true); - } - KdcAccessibility.removeBad(tempKdc); - break; - } catch (Exception e) { - if (DEBUG) { - System.out.println(">>> KrbKdcReq send: error trying " + - tempKdc); - e.printStackTrace(System.out); - } - KdcAccessibility.addBad(tempKdc); - savedException = e; + ibuf = sendIfPossible(obuf, tempKdc.next(), useTCP); + if (ibuf != null) { + return ibuf; + } + } catch(Exception ignore) {} } + throw first; } if (ibuf == null) { - if (savedException != null) { - if (savedException instanceof IOException) { - throw (IOException) savedException; - } else { - throw (KrbException) savedException; - } - } else { - throw new IOException("Cannot get a KDC reply"); - } + throw new IOException("Cannot get a KDC reply"); } return ibuf; } // send the AS Request to the specified KDC + // failover to using TCP if useTCP is not set and response is too big + private byte[] sendIfPossible(byte[] obuf, String tempKdc, boolean useTCP) + throws IOException, KrbException { + + try { + byte[] ibuf = send(obuf, tempKdc, useTCP); + KRBError ke = null; + try { + ke = new KRBError(ibuf); + } catch (Exception e) { + // OK + } + if (ke != null && ke.getErrorCode() == + Krb5.KRB_ERR_RESPONSE_TOO_BIG) { + ibuf = send(obuf, tempKdc, true); + } + KdcAccessibility.removeBad(tempKdc); + return ibuf; + } catch(Exception e) { + if (DEBUG) { + System.out.println(">>> KrbKdcReq send: error trying " + + tempKdc); + e.printStackTrace(System.out); + } + KdcAccessibility.addBad(tempKdc); + throw e; + } + } + + // send the AS Request to the specified KDC private byte[] send(byte[] obuf, String tempKdc, boolean useTCP) throws IOException, KrbException { @@ -500,7 +513,7 @@ } // Returns a preferred KDC list by putting the bad ones at the end - private static synchronized String[] list(String kdcList) { + private static synchronized List list(String kdcList) { StringTokenizer st = new StringTokenizer(kdcList); List list = new ArrayList<>(); if (badPolicy == BpType.TRY_LAST) { @@ -519,7 +532,7 @@ list.add(st.nextToken()); } } - return list.toArray(new String[list.size()]); + return list; } } }