6b97482569e0248dd3664e16c975d3cb97ca0dd0
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / core / TcpChannelInitializer.java
1 /*
2  * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.openflowjava.protocol.impl.core;
10
11 import io.netty.channel.Channel;
12 import io.netty.channel.group.DefaultChannelGroup;
13 import io.netty.channel.socket.SocketChannel;
14 import io.netty.handler.ssl.SslHandler;
15
16 import java.net.InetAddress;
17 import java.util.Iterator;
18 import java.util.concurrent.TimeUnit;
19
20 import javax.net.ssl.SSLEngine;
21
22 import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterFactory;
23 import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterFactoryImpl;
24 import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionFacade;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 /**
29  * Initializes TCP / TLS channel
30  * @author michal.polkorab
31  */
32 public class TcpChannelInitializer extends ProtocolChannelInitializer<SocketChannel> {
33
34     private static final Logger LOGGER = LoggerFactory
35             .getLogger(TcpChannelInitializer.class);
36     private final DefaultChannelGroup allChannels;
37     private ConnectionAdapterFactory connectionAdapterFactory;
38
39     /**
40      * default ctor
41      */
42     public TcpChannelInitializer() {
43         this( new DefaultChannelGroup("netty-receiver", null), new ConnectionAdapterFactoryImpl() );
44     }
45
46     /**
47      * Testing Constructor
48      * 
49      */
50     protected TcpChannelInitializer( DefaultChannelGroup channelGroup, ConnectionAdapterFactory connAdaptorFactory ) {
51         allChannels = channelGroup ;
52         connectionAdapterFactory = connAdaptorFactory ;
53     }
54     
55     @Override
56     protected void initChannel(final SocketChannel ch) {
57         InetAddress switchAddress = ch.remoteAddress().getAddress();
58         int port = ch.localAddress().getPort();
59         int remotePort = ch.remoteAddress().getPort();
60         LOGGER.debug("Incoming connection from (remote address): " + switchAddress.toString()
61                 + ":" + remotePort + " --> :" + port);
62         if (!getSwitchConnectionHandler().accept(switchAddress)) {
63             ch.disconnect();
64             LOGGER.debug("Incoming connection rejected");
65             return;
66         }
67         LOGGER.debug("Incoming connection accepted - building pipeline");
68         allChannels.add(ch);
69         ConnectionFacade connectionFacade = null;
70         connectionFacade = connectionAdapterFactory.createConnectionFacade(ch, null);
71         try {
72             LOGGER.debug("calling plugin: " + getSwitchConnectionHandler());
73             getSwitchConnectionHandler().onSwitchConnected(connectionFacade);
74             connectionFacade.checkListeners();
75             ch.pipeline().addLast(PipelineHandlers.IDLE_HANDLER.name(), new IdleHandler(getSwitchIdleTimeout(), TimeUnit.MILLISECONDS));
76             boolean tlsPresent = false;
77
78             // If this channel is configured to support SSL it will only support SSL
79             if (getTlsConfiguration() != null) {
80                 tlsPresent = true;
81                 SslContextFactory sslFactory = new SslContextFactory(getTlsConfiguration());
82                 SSLEngine engine = sslFactory.getServerContext().createSSLEngine();
83                 engine.setNeedClientAuth(true);
84                 engine.setUseClientMode(false);
85                 ch.pipeline().addLast(PipelineHandlers.SSL_HANDLER.name(), new SslHandler(engine));
86             }
87             ch.pipeline().addLast(PipelineHandlers.OF_FRAME_DECODER.name(),
88                     new OFFrameDecoder(connectionFacade, tlsPresent));
89             ch.pipeline().addLast(PipelineHandlers.OF_VERSION_DETECTOR.name(), new OFVersionDetector());
90             OFDecoder ofDecoder = new OFDecoder();
91             ofDecoder.setDeserializationFactory(getDeserializationFactory());
92             ch.pipeline().addLast(PipelineHandlers.OF_DECODER.name(), ofDecoder);
93             OFEncoder ofEncoder = new OFEncoder();
94             ofEncoder.setSerializationFactory(getSerializationFactory());
95             ch.pipeline().addLast(PipelineHandlers.OF_ENCODER.name(), ofEncoder);
96             ch.pipeline().addLast(PipelineHandlers.DELEGATING_INBOUND_HANDLER.name(), new DelegatingInboundHandler(connectionFacade));
97             if (!tlsPresent) {
98                 connectionFacade.fireConnectionReadyNotification();
99             }
100         } catch (Exception e) {
101             LOGGER.warn("Failed to initialize channel", e);
102             ch.close();
103         }
104     }
105
106     /**
107      * @return iterator through active connections
108      */
109     public Iterator<Channel> getConnectionIterator() {
110         return allChannels.iterator();
111     }
112
113     /**
114      * @return amount of active channels
115      */
116     public int size() {
117         return allChannels.size();
118     }
119 }