in modules/jndi/src/main/java/org/apache/harmony/jndi/provider/dns/Resolver.java [562:757]
public Enumeration<ResourceRecord> list(String name) throws NamingException {
final int OUT_BUF_SIZE = 512;
final int IN_BUF_SIZE = 65536;
Vector<ResourceRecord> answerVect = new Vector<ResourceRecord>();
Message mesToSend = null;
Message receivedMes = null;
Enumeration<ResourceRecord> enum1;
// String zoneMasterServer = null;
// Vector authoritativeServerIPs = new Vector();
HashSet<Object> authoritativeServers = new HashSet<Object>();
Iterator<Object> authServersIter;
int qClassArr[] = new int[1];
byte outBuf[] = new byte[OUT_BUF_SIZE];
int outLen;
byte inBuf[] = new byte[IN_BUF_SIZE];
boolean received = false;
boolean completeAnswer = false;
String proto = null;
ResolverCache cache = ResolverCache.getInstance();
// SList slist = SList.getInstance();
if (name == null) {
// jndi.2E=The name is null
throw new NullPointerException(Messages.getString("jndi.2E")); //$NON-NLS-1$
}
// if given name is SRV style name where domain name is prefixed
// with _Proto
if (name.startsWith("_")) { //$NON-NLS-1$
int n = name.indexOf('.');
if (n != -1) {
proto = name.substring(0, n);
if (name.length() > n) {
name = name.substring(n + 1, name.length());
} else {
// nonsense
name = "."; //$NON-NLS-1$
}
} else {
// nonsense
name = "."; //$NON-NLS-1$
}
}
enum1 = lookup(name, new int[] { ProviderConstants.NS_TYPE },
new int[] { ProviderConstants.ANY_QTYPE });
mesToSend = createMessageForSending(name, ProviderConstants.AXFR_QTYPE,
ProviderConstants.ANY_QCLASS);
outLen = mesToSend.writeBytes(outBuf, 0);
// determine the list of zone authoritative servers
while (enum1.hasMoreElements()) {
ResourceRecord rr = enum1.nextElement();
if (rr.getRRType() == ProviderConstants.NS_TYPE) {
authoritativeServers.add(rr.getRData());
// assertion: all authoritative servers should have the same
// DNS class
qClassArr[0] = rr.getRRClass();
} else if (rr.getRRType() == ProviderConstants.SOA_TYPE) {
StringTokenizer st = new StringTokenizer(
(String) rr.getRData(), " "); //$NON-NLS-1$
if (st.hasMoreTokens()) {
authoritativeServers.add(st.nextToken());
qClassArr[0] = rr.getRRClass();
break;
}
}
}
// try to perform a zone transfer
authServersIter = authoritativeServers.iterator();
authServersLoop: while (authServersIter.hasNext()) {
String authServerName = (String) authServersIter.next();
Enumeration<ResourceRecord> addrEnum = lookup(authServerName,
new int[] { ProviderConstants.A_TYPE }, qClassArr);
while (addrEnum.hasMoreElements()) {
ResourceRecord curRR = addrEnum.nextElement();
String ip = (String) curRR.getRData();
try {
// if (LogConst.DEBUG) {
// ProviderMgr.logger.fine(
// "Initiating zone transfer, IP=" + ip);
// }
TransportMgr.sendReceiveTCP(ip,
ProviderConstants.DEFAULT_DNS_PORT, outBuf, outLen,
inBuf, IN_BUF_SIZE, this.initialTimeout
* this.timeoutRetries);
received = true;
} catch (SocketTimeoutException e) {
// if (LogConst.DEBUG) {
// ProviderMgr.logger.fine("Socket timeout");
// }
} catch (DomainProtocolException e) {
// some problem was encountered
// ProviderMgr.logger.log(Level.WARNING,
// "Connection failure", e);
}
if (received) {
receivedMes = new Message();
try {
int rCode;
Message.parseMessage(inBuf, 0, receivedMes);
rCode = receivedMes.getRCode();
switch (rCode) {
case ProviderConstants.NO_ERROR:
// put all received records into Resolver's
// cache
for (int k = 0; k < 3; k++) {
switch (k) {
case 0:
enum1 = receivedMes.getAnswerRRs();
break;
case 1:
enum1 = receivedMes
.getAuthorityRRs();
break;
case 2:
enum1 = receivedMes
.getAdditionalRRs();
break;
}
while (enum1.hasMoreElements()) {
ResourceRecord rr = enum1.nextElement();
cache.put(rr);
if (k == 0) {
answerVect.addElement(rr);
}
}
}
completeAnswer = true;
break;
case ProviderConstants.NAME_ERROR:
// jndi.6D=Name {0} was not found
throw new NameNotFoundException(Messages
.getString("jndi.6D", name)); //$NON-NLS-1$
case ProviderConstants.SERVER_FAILURE:
case ProviderConstants.FORMAT_ERROR:
case ProviderConstants.NOT_IMPLEMENTED:
case ProviderConstants.REFUSED:
default:
}
} catch (DomainProtocolException e) {
// ProviderMgr.logger.log(Level.WARNING,
// "Error while parsing of DNS message", e);
}
} // if received
if (completeAnswer) {
// if (LogConst.DEBUG) {
// ProviderMgr.logger.fine(
// "list: Complete answer received");
// }
break authServersLoop;
}
} // address loop
} // authoritative servers loop
if (!completeAnswer) {
// found nothing
// jndi.6E=Unable to perform zone transfer
throw new ServiceUnavailableException(Messages.getString("jndi.6E")); //$NON-NLS-1$
}
// SRV _Proto prefix support - filter all records that don't have given
// _Proto field
if (proto != null) {
Vector<ResourceRecord> answerVect2 = new Vector<ResourceRecord>();
for (int i = 0; i < answerVect.size(); i++) {
ResourceRecord rr = answerVect.elementAt(i);
StringTokenizer st = new StringTokenizer(rr.getName(), "."); //$NON-NLS-1$
String token = null;
boolean valid = false;
if (st.hasMoreTokens()) {
token = st.nextToken();
if (token.length() > 0 && token.charAt(0) == '_'
&& st.hasMoreTokens()) {
token = st.nextToken();
if (token.equalsIgnoreCase(proto)) {
valid = true;
}
}
}
if (valid) {
answerVect2.addElement(rr);
}
}
answerVect = answerVect2;
}
return answerVect.elements();
}