📄 dnsserver.java
字号:
/**************************************************************** * Licensed to the Apache Software Foundation (ASF) under one * * or more contributor license agreements. See the NOTICE file * * distributed with this work for additional information * * regarding copyright ownership. The ASF licenses this file * * to you under the Apache License, Version 2.0 (the * * "License"); you may not use this file except in compliance * * with the License. You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, * * software distributed under the License is distributed on an * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * * KIND, either express or implied. See the License for the * * specific language governing permissions and limitations * * under the License. * ****************************************************************/package org.apache.james.dnsserver;import org.apache.avalon.framework.activity.Initializable;import org.apache.avalon.framework.activity.Disposable;import org.apache.avalon.framework.configuration.Configurable;import org.apache.avalon.framework.configuration.Configuration;import org.apache.avalon.framework.configuration.ConfigurationException;import org.apache.avalon.framework.logger.AbstractLogEnabled;import org.xbill.DNS.CNAMERecord;import org.xbill.DNS.Cache;import org.xbill.DNS.Credibility;import org.xbill.DNS.DClass;import org.xbill.DNS.ExtendedResolver;import org.xbill.DNS.Lookup;import org.xbill.DNS.Message;import org.xbill.DNS.MXRecord;import org.xbill.DNS.Name;import org.xbill.DNS.Rcode;import org.xbill.DNS.Record;import org.xbill.DNS.Resolver;import org.xbill.DNS.RRset;import org.xbill.DNS.ResolverConfig;import org.xbill.DNS.SetResponse;import org.xbill.DNS.TextParseException;import org.xbill.DNS.Type;import java.net.InetAddress;import java.net.UnknownHostException;import java.util.ArrayList;import java.util.Arrays;import java.util.Collection;import java.util.Collections;import java.util.Comparator;import java.util.Iterator;import java.util.List;import java.util.Random;/** * Provides DNS client functionality to services running * inside James */public class DNSServer extends AbstractLogEnabled implements Configurable, Initializable, Disposable, org.apache.james.services.DNSServer, DNSServerMBean { /** * A resolver instance used to retrieve DNS records. This * is a reference to a third party library object. */ protected Resolver resolver; /** * A TTL cache of results received from the DNS server. This * is a reference to a third party library object. */ private Cache cache; /** * Maximum number of RR to cache. */ private int maxCacheSize = 50000; /** * Whether the DNS response is required to be authoritative */ private int dnsCredibility; /** * The DNS servers to be used by this service */ private List dnsServers = new ArrayList(); /** * The MX Comparator used in the MX sort. */ private Comparator mxComparator = new MXRecordComparator(); /** * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration) */ public void configure( final Configuration configuration ) throws ConfigurationException { final boolean autodiscover = configuration.getChild( "autodiscover" ).getValueAsBoolean( true ); if (autodiscover) { getLogger().info("Autodiscovery is enabled - trying to discover your system's DNS Servers"); String[] serversArray = ResolverConfig.getCurrentConfig().servers(); if (serversArray != null) { for ( int i = 0; i < serversArray.length; i++ ) { dnsServers.add(serversArray[ i ]); getLogger().info("Adding autodiscovered server " + serversArray[i]); } } } // Get the DNS servers that this service will use for lookups final Configuration serversConfiguration = configuration.getChild( "servers" ); final Configuration[] serverConfigurations = serversConfiguration.getChildren( "server" ); for ( int i = 0; i < serverConfigurations.length; i++ ) { dnsServers.add( serverConfigurations[ i ].getValue() ); } if (dnsServers.isEmpty()) { getLogger().info("No DNS servers have been specified or found by autodiscovery - adding 127.0.0.1"); dnsServers.add("127.0.0.1"); } final boolean authoritative = configuration.getChild( "authoritative" ).getValueAsBoolean( false ); // TODO: Check to see if the credibility field is being used correctly. From the // docs I don't think so dnsCredibility = authoritative ? Credibility.AUTH_ANSWER : Credibility.NONAUTH_ANSWER; maxCacheSize = (int) configuration.getChild( "maxcachesize" ).getValueAsLong( maxCacheSize ); } /** * @see org.apache.avalon.framework.activity.Initializable#initialize() */ public void initialize() throws Exception { getLogger().debug("DNSServer init..."); // If no DNS servers were configured, default to local host if (dnsServers.isEmpty()) { try { dnsServers.add( InetAddress.getLocalHost().getHostName() ); } catch ( UnknownHostException ue ) { dnsServers.add( "127.0.0.1" ); } } //Create the extended resolver... final String[] serversArray = (String[])dnsServers.toArray(new String[0]); if (getLogger().isInfoEnabled()) { for(int c = 0; c < serversArray.length; c++) { getLogger().info("DNS Server is: " + serversArray[c]); } } try { resolver = new ExtendedResolver( serversArray ); Lookup.setDefaultResolver(resolver); } catch (UnknownHostException uhe) { getLogger().fatalError("DNS service could not be initialized. The DNS servers specified are not recognized hosts.", uhe); throw uhe; } cache = new Cache (DClass.IN); cache.setMaxEntries(maxCacheSize); Lookup.setDefaultCache(cache, DClass.IN); getLogger().debug("DNSServer ...init end"); } /** * <p>Return the list of DNS servers in use by this service</p> * * @return an array of DNS server names */ public String[] getDNSServers() { return (String[])dnsServers.toArray(new String[0]); } /** * <p>Return a prioritized unmodifiable list of MX records * obtained from the server.</p> * * @param hostname domain name to look up * * @return a list of MX records corresponding to this mail domain */ public List findMXRecordsRaw(String hostname) { Record answers[] = lookup(hostname, Type.MX); List servers = new ArrayList(); if (answers == null) { return servers; } MXRecord mxAnswers[] = new MXRecord[answers.length]; for (int i = 0; i < answers.length; i++) { mxAnswers[i] = (MXRecord)answers[i]; } Arrays.sort(mxAnswers, mxComparator); for (int i = 0; i < mxAnswers.length; i++) { servers.add(mxAnswers[i].getTarget ().toString ()); getLogger().debug(new StringBuffer("Found MX record ").append(mxAnswers[i].getTarget ().toString ()).toString()); } return servers; } /** * <p>Return a prioritized unmodifiable list of host handling mail * for the domain.</p> * * <p>First lookup MX hosts, then MX hosts of the CNAME adress, and * if no server is found return the IP of the hostname</p> * * @param hostname domain name to look up * * @return a unmodifiable list of handling servers corresponding to * this mail domain name */ public Collection findMXRecords(String hostname) { List servers = new ArrayList(); try { servers = findMXRecordsRaw(hostname); return Collections.unmodifiableCollection(servers); } finally { //If we found no results, we'll add the original domain name if //it's a valid DNS entry if (servers.size () == 0) { StringBuffer logBuffer = new StringBuffer(128) .append("Couldn't resolve MX records for domain ") .append(hostname) .append("."); getLogger().info(logBuffer.toString()); Record cnames[] = lookup(hostname, Type.CNAME); Collection cnameMXrecords = null; if (cnames!=null && cnames.length > 0) { cnameMXrecords = findMXRecordsRaw(((CNAMERecord) cnames[0]).getTarget().toString()); } else { logBuffer = new StringBuffer(128) .append("Couldn't find CNAME records for domain ") .append(hostname) .append("."); getLogger().info(logBuffer.toString()); } if (cnameMXrecords==null) { try { getByName(hostname); servers.add(hostname); } catch (UnknownHostException uhe) { // The original domain name is not a valid host, // so we can't add it to the server list. In this // case we return an empty list of servers logBuffer = new StringBuffer(128) .append("Couldn't resolve IP address for host ") .append(hostname)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -