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;
21  
22  
23  import java.io.IOException;
24  
25  import org.apache.directory.server.dns.protocol.DnsProtocolHandler;
26  import org.apache.directory.server.dns.store.RecordStore;
27  import org.apache.directory.server.dns.store.jndi.JndiRecordStoreImpl;
28  import org.apache.directory.server.protocol.shared.DirectoryBackedService;
29  import org.apache.directory.server.protocol.shared.transport.Transport;
30  import org.apache.directory.server.protocol.shared.transport.UdpTransport;
31  import org.apache.mina.core.service.IoAcceptor;
32  import org.apache.mina.transport.socket.DatagramAcceptor;
33  import org.apache.mina.transport.socket.DatagramSessionConfig;
34  import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
35  import org.slf4j.Logger;
36  import org.slf4j.LoggerFactory;
37  
38  
39  /**
40   * Contains the configuration parameters for the DNS protocol provider.
41   *
42   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
43   */
44  public class DnsServer extends DirectoryBackedService
45  {
46      private static final long serialVersionUID = 6943138644427163149L;
47  
48      /** logger for this class */
49      private static final Logger LOG = LoggerFactory.getLogger( DnsServer.class );
50  
51      /** The default IP port. */
52      private static final int DEFAULT_IP_PORT = 53;
53  
54      /** The default service pid. */
55      private static final String SERVICE_PID_DEFAULT = "org.apache.directory.server.dns";
56  
57      /** The default service name. */
58      private static final String SERVICE_NAME_DEFAULT = "ApacheDS DNS Service";
59  
60  
61      /**
62       * Creates a new instance of DnsConfiguration.
63       */
64      public DnsServer()
65      {
66          super.setServiceId( SERVICE_PID_DEFAULT );
67          super.setServiceName( SERVICE_NAME_DEFAULT );
68      }
69  
70  
71      /**
72       * @throws IOException if we cannot bind to the specified ports
73       */
74      public void start() throws IOException
75      {
76          RecordStore store = new JndiRecordStoreImpl( getSearchBaseDn(), getSearchBaseDn(), getDirectoryService() );
77  
78          if ( ( transports == null ) || transports.isEmpty() )
79          {
80              // Default to UDP with port 53
81              // We have to create a DatagramAcceptor
82              UdpTransportol/shared/transport/UdpTransport.html#UdpTransport">UdpTransport transport = new UdpTransport( DEFAULT_IP_PORT );
83              setTransports( transport );
84  
85              DatagramAcceptor acceptor = transport.getAcceptor();
86  
87              // Set the handler
88              acceptor.setHandler( new DnsProtocolHandler( this, store ) );
89  
90              // Allow the port to be reused even if the socket is in TIME_WAIT state
91               acceptor.getSessionConfig().setReuseAddress( true );
92  
93              // Start the listener
94              acceptor.bind();
95          }
96          else
97          {
98              for ( Transport transport : transports )
99              {
100                 // Get the acceptor
101                 IoAcceptor acceptor = transport.getAcceptor();
102 
103                 // Set the handler
104                 acceptor.setHandler( new DnsProtocolHandler( this, store ) );
105 
106                 if ( transport instanceof UdpTransport )
107                 {
108                     // Allow the port to be reused even if the socket is in TIME_WAIT state
109                     ( ( DatagramSessionConfig ) acceptor.getSessionConfig() ).setReuseAddress( true );
110                 }
111                 else
112                 {
113                     // Disable the disconnection of the clients on unbind
114                     acceptor.setCloseOnDeactivation( false );
115 
116                     // Allow the port to be reused even if the socket is in TIME_WAIT state
117                     ( ( NioSocketAcceptor ) acceptor ).setReuseAddress( true );
118 
119                     // No Nagle's algorithm
120                     ( ( NioSocketAcceptor ) acceptor ).getSessionConfig().setTcpNoDelay( true );
121                 }
122 
123                 // Start the listener
124                 acceptor.bind();
125             }
126         }
127 
128         LOG.info( "DNS service started." );
129     }
130 
131 
132     public void stop()
133     {
134         for ( Transport transport : getTransports() )
135         {
136             IoAcceptor acceptor = transport.getAcceptor();
137 
138             if ( acceptor != null )
139             {
140                 acceptor.dispose();
141             }
142         }
143 
144         LOG.info( "DNS service stopped." );
145     }
146 
147 
148     /**
149      * @see Object#toString()
150      */
151     public String toString()
152     {
153         StringBuilder sb = new StringBuilder();
154 
155         sb.append( "DNSServer[" ).append( getServiceName() ).append( "], listening on :" ).append( '\n' );
156 
157         if ( getTransports() != null )
158         {
159             for ( Transport transport : getTransports() )
160             {
161                 sb.append( "    " ).append( transport ).append( '\n' );
162             }
163         }
164 
165         return sb.toString();
166     }
167 }