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.ntp;
21  
22  
23  import java.io.IOException;
24  
25  import org.apache.directory.server.ntp.protocol.NtpProtocolCodecFactory;
26  import org.apache.directory.server.ntp.protocol.NtpProtocolHandler;
27  import org.apache.directory.server.protocol.shared.AbstractProtocolService;
28  import org.apache.directory.server.protocol.shared.transport.Transport;
29  import org.apache.directory.server.protocol.shared.transport.UdpTransport;
30  import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
31  import org.apache.mina.core.service.IoAcceptor;
32  import org.apache.mina.core.service.IoHandler;
33  import org.apache.mina.filter.codec.ProtocolCodecFilter;
34  import org.apache.mina.transport.socket.DatagramAcceptor;
35  import org.apache.mina.transport.socket.DatagramSessionConfig;
36  import org.apache.mina.transport.socket.SocketAcceptor;
37  import org.slf4j.Logger;
38  import org.slf4j.LoggerFactory;
39  
40  
41  /**
42   * Contains the configuration parameters for the NTP protocol provider.
43   *
44   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
45   */
46  public class NtpServer extends AbstractProtocolService
47  {
48      /** logger for this class */
49      private static final Logger LOG = LoggerFactory.getLogger( NtpServer.class );
50  
51      /**
52       * The default IP port.
53       */
54      private static final int IP_PORT_DEFAULT = 123;
55  
56      /** The default service pid. */
57      private static final String SERVICE_PID_DEFAULT = "org.apache.directory.server.ntp";
58  
59      /** The default service name. */
60      private static final String SERVICE_NAME_DEFAULT = "ApacheDS NTP Service";
61  
62  
63      /**
64       * Creates a new instance of NtpConfiguration.
65       */
66      public NtpServer()
67      {
68          super.setServiceId( SERVICE_PID_DEFAULT );
69          super.setServiceName( SERVICE_NAME_DEFAULT );
70      }
71  
72  
73      /**
74       * Start the NTPServer. We initialize the Datagram and Socket, if necessary.
75       * 
76       * Note that we don't have any filter in the chain, everything is done
77       * in the handler.
78       * @throws IOException if there are issues binding
79       */
80      public void start() throws IOException
81      {
82          IoHandler ntpProtocolHandler = new NtpProtocolHandler();
83  
84          // Create the chain for the NTP server
85          DefaultIoFilterChainBuilder ntpChain = new DefaultIoFilterChainBuilder();
86          ntpChain.addLast( "codec", new ProtocolCodecFilter( NtpProtocolCodecFactory.getInstance() ) );
87  
88          if ( ( transports == null ) || transports.isEmpty() )
89          {
90              // Default to UDP with port 123
91              // We have to create a DatagramAcceptor
92              UdpTransportol/shared/transport/UdpTransport.html#UdpTransport">UdpTransport transport = new UdpTransport( IP_PORT_DEFAULT );
93              setTransports( transport );
94  
95              DatagramAcceptor acceptor = transport.getAcceptor();
96  
97              // Set the handler
98              acceptor.setHandler( ntpProtocolHandler );
99  
100             // Allow the port to be reused even if the socket is in TIME_WAIT state
101             acceptor.getSessionConfig().setReuseAddress( true );
102 
103             // Inject the chain
104             acceptor.setFilterChainBuilder( ntpChain );
105 
106             // Start the listener
107             acceptor.bind();
108         }
109         else
110         {
111             for ( Transport transport : transports )
112             {
113                 IoAcceptor acceptor = transport.getAcceptor();
114 
115                 // Set the handler
116                 acceptor.setHandler( ntpProtocolHandler );
117 
118                 if ( transport instanceof UdpTransport )
119                 {
120                     // Allow the port to be reused even if the socket is in TIME_WAIT state
121                     ( ( DatagramSessionConfig ) acceptor.getSessionConfig() ).setReuseAddress( true );
122                 }
123                 else
124                 {
125                     // Disable the disconnection of the clients on unbind
126                     acceptor.setCloseOnDeactivation( false );
127 
128                     // Allow the port to be reused even if the socket is in TIME_WAIT state
129                     ( ( SocketAcceptor ) acceptor ).setReuseAddress( true );
130 
131                     // No Nagle's algorithm
132                     ( ( SocketAcceptor ) acceptor ).getSessionConfig().setTcpNoDelay( true );
133                 }
134 
135                 // Inject the chain
136                 acceptor.setFilterChainBuilder( ntpChain );
137 
138                 // Start the listener
139                 acceptor.bind();
140             }
141         }
142 
143         LOG.info( "NTP server started." );
144     }
145 
146 
147     /**
148      * {@inheritDoc}
149      */
150     public void stop()
151     {
152         for ( Transport transport : getTransports() )
153         {
154             IoAcceptor acceptor = transport.getAcceptor();
155 
156             if ( acceptor != null )
157             {
158                 acceptor.dispose();
159             }
160         }
161 
162         LOG.info( "NTP Server stopped." );
163     }
164 
165 
166     /**
167      * @see Object#toString()
168      */
169     public String toString()
170     {
171         StringBuilder sb = new StringBuilder();
172 
173         sb.append( "NTPServer[" ).append( getServiceName() ).append( "], listening on :" ).append( '\n' );
174 
175         if ( getTransports() != null )
176         {
177             for ( Transport transport : getTransports() )
178             {
179                 sb.append( "    " ).append( transport ).append( '\n' );
180             }
181         }
182 
183         return sb.toString();
184     }
185 }