View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.dns.service;
21  
22  
23  import java.util.ArrayList;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Set;
27  
28  import org.apache.directory.server.dns.DnsException;
29  import org.apache.directory.server.dns.messages.DnsMessage;
30  import org.apache.directory.server.dns.messages.DnsMessageModifier;
31  import org.apache.directory.server.dns.messages.MessageType;
32  import org.apache.directory.server.dns.messages.OpCode;
33  import org.apache.directory.server.dns.messages.QuestionRecord;
34  import org.apache.directory.server.dns.messages.ResourceRecord;
35  import org.apache.directory.server.dns.messages.ResponseCode;
36  import org.apache.directory.server.dns.store.RecordStore;
37  import org.slf4j.Logger;
38  import org.slf4j.LoggerFactory;
39  
40  
41  /**
42   * Domain Name Service (DNS) Protocol (RFC 1034, 1035)
43   * 
44   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
45   * @version $Rev: 591064 $, $Date: 2007-11-01 17:03:46 +0100 (Do, 01 Nov 2007) $
46   */
47  public class DomainNameService
48  {
49      /** the log for this class */
50      private static final Logger LOG = LoggerFactory.getLogger( DomainNameService.class );
51  
52  
53      /**
54       * Creates a new instance of DomainNameService.
55       */
56      public static void execute( DnsContext dnsContext, DnsMessage request ) throws Exception
57      {
58          if ( LOG.isDebugEnabled() )
59          {
60              monitorRequest( request );
61          }
62  
63          getResourceRecords( dnsContext, request );
64  
65          if ( LOG.isDebugEnabled() )
66          {
67              monitorContext( dnsContext );
68          }
69  
70          buildReply( dnsContext, request );
71  
72          if ( LOG.isDebugEnabled() )
73          {
74              monitorReply( dnsContext );
75          }
76      }
77      
78      private static void monitorRequest( DnsMessage request ) throws Exception
79      {
80          try
81          {
82              LOG.debug( monitorMessage( request, "request" ) );
83          }
84          catch ( Exception e )
85          {
86              // This is a monitor.  No exceptions should bubble up.
87              LOG.error( "Error in request monitor", e );
88          }
89      }
90      
91  
92      private static void getResourceRecords( DnsContext dnsContext, DnsMessage request ) throws Exception
93      {
94          RecordStore store = dnsContext.getStore();
95  
96          List<QuestionRecord> questions = request.getQuestionRecords();
97  
98          Iterator<QuestionRecord> it = questions.iterator();
99  
100         while ( it.hasNext() )
101         {
102             dnsContext.addResourceRecords( getEntry( store, it.next() ) );
103         }
104     }
105     
106     
107     /**
108      * Returns a set of {@link ResourceRecord}s from a {@link RecordStore}, given a DNS {@link QuestionRecord}.
109      *
110      * @param store
111      * @param question
112      * @return The set of {@link ResourceRecord}s.
113      * @throws DNSException
114      */
115     private static Set<ResourceRecord> getEntry( RecordStore store, QuestionRecord question ) throws DnsException
116     {
117         Set<ResourceRecord> records = null;
118 
119         records = store.getRecords( question );
120 
121         if ( records == null || records.isEmpty() )
122         {
123             LOG.debug( "The domain name referenced in the query does not exist." );
124 
125             throw new DnsException( ResponseCode.NAME_ERROR );
126         }
127 
128         return records;
129     }
130     
131     
132     private static void monitorContext( DnsContext dnsContext ) throws Exception
133     {
134         try
135         {
136             RecordStore store = dnsContext.getStore();
137             List<ResourceRecord> records = dnsContext.getResourceRecords();
138 
139             StringBuffer sb = new StringBuffer();
140             sb.append( "Monitoring context:" );
141             sb.append( "\n\t" + "store:                     " + store );
142             sb.append( "\n\t" + "records:                   " + records );
143 
144             LOG.debug( sb.toString() );
145         }
146         catch ( Exception e )
147         {
148             // This is a monitor.  No exceptions should bubble up.
149             LOG.error( "Error in context monitor", e );
150         }
151     }
152     
153     
154     private static void buildReply( DnsContext dnsContext, DnsMessage request ) throws Exception
155     {
156         List<ResourceRecord> records = dnsContext.getResourceRecords();
157 
158         DnsMessageModifier modifier = new DnsMessageModifier();
159 
160         modifier.setTransactionId( request.getTransactionId() );
161         modifier.setMessageType( MessageType.RESPONSE );
162         modifier.setOpCode( OpCode.QUERY );
163         modifier.setAuthoritativeAnswer( false );
164         modifier.setTruncated( false );
165         modifier.setRecursionDesired( request.isRecursionDesired() );
166         modifier.setRecursionAvailable( false );
167         modifier.setReserved( false );
168         modifier.setAcceptNonAuthenticatedData( false );
169         modifier.setResponseCode( ResponseCode.NO_ERROR );
170         modifier.setQuestionRecords( request.getQuestionRecords() );
171 
172         modifier.setAnswerRecords( records );
173         modifier.setAuthorityRecords( new ArrayList<ResourceRecord>() );
174         modifier.setAdditionalRecords( new ArrayList<ResourceRecord>() );
175 
176         dnsContext.setReply( modifier.getDnsMessage() );
177     }
178  
179     
180     private static void monitorReply( DnsContext dnsContext ) throws Exception
181     {
182         try
183         {
184             DnsMessage reply = dnsContext.getReply();
185 
186             LOG.debug( monitorMessage( reply, "reply" ) );
187         }
188         catch ( Exception e )
189         {
190             // This is a monitor.  No exceptions should bubble up.
191             LOG.error( "Error in reply monitor", e );
192         }
193     }
194     
195     
196     private static String monitorMessage( DnsMessage message, String direction )
197     {
198         MessageType messageType = message.getMessageType();
199         OpCode opCode = message.getOpCode();
200         ResponseCode responseCode = message.getResponseCode();
201         int transactionId = message.getTransactionId();
202 
203         StringBuffer sb = new StringBuffer();
204         sb.append( "Monitoring " + direction + ":" );
205         sb.append( "\n\t" + "messageType                " + messageType );
206         sb.append( "\n\t" + "opCode                     " + opCode );
207         sb.append( "\n\t" + "responseCode               " + responseCode );
208         sb.append( "\n\t" + "transactionId              " + transactionId );
209 
210         sb.append( "\n\t" + "authoritativeAnswer        " + message.isAuthoritativeAnswer() );
211         sb.append( "\n\t" + "truncated                  " + message.isTruncated() );
212         sb.append( "\n\t" + "recursionDesired           " + message.isRecursionDesired() );
213         sb.append( "\n\t" + "recursionAvailable         " + message.isRecursionAvailable() );
214         sb.append( "\n\t" + "reserved                   " + message.isReserved() );
215         sb.append( "\n\t" + "acceptNonAuthenticatedData " + message.isAcceptNonAuthenticatedData() );
216 
217         List<QuestionRecord> questions = message.getQuestionRecords();
218 
219         sb.append( "\n\t" + "questions:                 " + questions );
220 
221         return sb.toString();
222     }
223 }