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 12:27:15 +0100 (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 }