001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020
021 package org.apache.directory.server.dns.protocol;
022
023
024 import java.util.ArrayList;
025
026 import org.apache.directory.server.dns.DnsServer;
027 import org.apache.directory.server.dns.DnsException;
028 import org.apache.directory.server.dns.messages.DnsMessage;
029 import org.apache.directory.server.dns.messages.DnsMessageModifier;
030 import org.apache.directory.server.dns.messages.MessageType;
031 import org.apache.directory.server.dns.messages.OpCode;
032 import org.apache.directory.server.dns.messages.ResourceRecord;
033 import org.apache.directory.server.dns.messages.ResponseCode;
034 import org.apache.directory.server.dns.service.DnsContext;
035 import org.apache.directory.server.dns.service.DomainNameService;
036 import org.apache.directory.server.dns.store.RecordStore;
037 import org.apache.mina.core.service.IoHandler;
038 import org.apache.mina.core.session.IdleStatus;
039 import org.apache.mina.core.session.IoSession;
040 import org.apache.mina.filter.codec.ProtocolCodecFilter;
041 import org.slf4j.Logger;
042 import org.slf4j.LoggerFactory;
043
044
045 /**
046 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
047 * @version $Rev: 901657 $, $Date: 2010-01-21 13:27:15 +0200 (Thu, 21 Jan 2010) $
048 */
049 public class DnsProtocolHandler implements IoHandler
050 {
051 private static final Logger LOG = LoggerFactory.getLogger( DnsProtocolHandler.class );
052
053 private DnsServer config;
054 private RecordStore store;
055 private String contextKey = "context";
056
057
058 /**
059 * Creates a new instance of DnsProtocolHandler.
060 *
061 * @param config
062 * @param store
063 */
064 public DnsProtocolHandler( DnsServer config, RecordStore store )
065 {
066 this.config = config;
067 this.store = store;
068 }
069
070
071 public void sessionCreated( IoSession session ) throws Exception
072 {
073 if ( LOG.isDebugEnabled() )
074 {
075 LOG.debug( "{} CREATED: {}", session.getRemoteAddress(), session.getTransportMetadata() );
076 }
077
078 if ( session.getTransportMetadata().isConnectionless() )
079 {
080 session.getFilterChain().addFirst( "codec",
081 new ProtocolCodecFilter( DnsProtocolUdpCodecFactory.getInstance() ) );
082 }
083 else
084 {
085 session.getFilterChain().addFirst( "codec",
086 new ProtocolCodecFilter( DnsProtocolTcpCodecFactory.getInstance() ) );
087 }
088 }
089
090
091 public void sessionOpened( IoSession session )
092 {
093 LOG.debug( "{} OPENED", session.getRemoteAddress() );
094 }
095
096
097 public void sessionClosed( IoSession session )
098 {
099 LOG.debug( "{} CLOSED", session.getRemoteAddress() );
100 }
101
102
103 public void sessionIdle( IoSession session, IdleStatus status )
104 {
105 LOG.debug( "{} IDLE ({})", session.getRemoteAddress(), status );
106 }
107
108
109 public void exceptionCaught( IoSession session, Throwable cause )
110 {
111 LOG.error( session.getRemoteAddress() + " EXCEPTION", cause );
112 session.close( true );
113 }
114
115
116 public void messageReceived( IoSession session, Object message )
117 {
118 LOG.debug( "{} RCVD: {}", session.getRemoteAddress(), message );
119
120 try
121 {
122 DnsContext dnsContext = new DnsContext();
123 dnsContext.setConfig( config );
124 dnsContext.setStore( store );
125 session.setAttribute( getContextKey(), dnsContext );
126
127 DomainNameService.execute( dnsContext, (DnsMessage)message );
128
129 DnsMessage response = dnsContext.getReply();
130
131 session.write( response );
132 }
133 catch ( Exception e )
134 {
135 LOG.error( e.getLocalizedMessage(), e );
136
137 DnsMessage request = ( DnsMessage ) message;
138 DnsException de = ( DnsException ) e;
139
140 DnsMessageModifier modifier = new DnsMessageModifier();
141
142 modifier.setTransactionId( request.getTransactionId() );
143 modifier.setMessageType( MessageType.RESPONSE );
144 modifier.setOpCode( OpCode.QUERY );
145 modifier.setAuthoritativeAnswer( false );
146 modifier.setTruncated( false );
147 modifier.setRecursionDesired( request.isRecursionDesired() );
148 modifier.setRecursionAvailable( false );
149 modifier.setReserved( false );
150 modifier.setAcceptNonAuthenticatedData( false );
151 modifier.setResponseCode( ResponseCode.convert( ( byte ) de.getResponseCode() ) );
152 modifier.setQuestionRecords( request.getQuestionRecords() );
153 modifier.setAnswerRecords( new ArrayList<ResourceRecord>() );
154 modifier.setAuthorityRecords( new ArrayList<ResourceRecord>() );
155 modifier.setAdditionalRecords( new ArrayList<ResourceRecord>() );
156
157 session.write( modifier.getDnsMessage() );
158 }
159 }
160
161
162 public void messageSent( IoSession session, Object message )
163 {
164 LOG.debug( "{} SENT: {}", session.getRemoteAddress(), message );
165 }
166
167
168 protected String getContextKey()
169 {
170 return ( this.contextKey );
171 }
172 }