Barrier turn on/off-add switcher value to Config-Subsystem
[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 import io.netty.util.concurrent.Future;
16 import io.netty.util.concurrent.GenericFutureListener;
17 import java.net.InetAddress;
18 import java.util.Iterator;
19 import java.util.concurrent.TimeUnit;
20 import javax.net.ssl.SSLEngine;
21 import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterFactory;
22 import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterFactoryImpl;
23 import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionFacade;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * Initializes TCP / TLS channel
29  * @author michal.polkorab
30  */
31 public class TcpChannelInitializer extends ProtocolChannelInitializer<SocketChannel> {
32
33     private static final Logger LOGGER = LoggerFactory
34             .getLogger(TcpChannelInitializer.class);
35     private final DefaultChannelGroup allChannels;
36     private final ConnectionAdapterFactory connectionAdapterFactory;
37
38     /**
39      * default ctor
40      */
41     public TcpChannelInitializer() {
42         this( new DefaultChannelGroup("netty-receiver", null), new ConnectionAdapterFactoryImpl() );
43     }
44
45     /**
46      * Testing Constructor
47      *
48      */
49     protected TcpChannelInitializer( final DefaultChannelGroup channelGroup, final ConnectionAdapterFactory connAdaptorFactory ) {
50         allChannels = channelGroup ;
51         connectionAdapterFactory = connAdaptorFactory ;
52     }
53
54     @Override
55     protected void initChannel(final SocketChannel ch) {
56         if (ch.remoteAddress() != null) {
57             final InetAddress switchAddress = ch.remoteAddress().getAddress();
58             final int port = ch.localAddress().getPort();
59             final int remotePort = ch.remoteAddress().getPort();
60             LOGGER.debug("Incoming connection from (remote address): {}:{} --> :{}",
61                             switchAddress.toString(), remotePort, port);
62
63             if (!getSwitchConnectionHandler().accept(switchAddress)) {
64                 ch.disconnect();
65                 LOGGER.debug("Incoming connection rejected");
66                 return;
67             }
68         }
69         LOGGER.debug("Incoming connection accepted - building pipeline");
70         allChannels.add(ch);
71         ConnectionFacade connectionFacade = null;
72         connectionFacade = connectionAdapterFactory.createConnectionFacade(ch, null, useBarrier());
73         try {
74             LOGGER.debug("calling plugin: {}", getSwitchConnectionHandler());
75             getSwitchConnectionHandler().onSwitchConnected(connectionFacade);
76             connectionFacade.checkListeners();
77             ch.pipeline().addLast(PipelineHandlers.IDLE_HANDLER.name(), new IdleHandler(getSwitchIdleTimeout(), TimeUnit.MILLISECONDS));
78             boolean tlsPresent = false;
79
80             // If this channel is configured to support SSL it will only support SSL
81             if (getTlsConfiguration() != null) {
82                 tlsPresent = true;
83                 final SslContextFactory sslFactory = new SslContextFactory(getTlsConfiguration());
84                 final SSLEngine engine = sslFactory.getServerContext().createSSLEngine();
85                 engine.setNeedClientAuth(true);
86                 engine.setUseClientMode(false);
87                 final SslHandler ssl = new SslHandler(engine);
88                 final Future<Channel> handshakeFuture = ssl.handshakeFuture();
89                 final ConnectionFacade finalConnectionFacade = connectionFacade;
90                 handshakeFuture.addListener(new GenericFutureListener<Future<? super Channel>>() {
91                     @Override
92                     public void operationComplete(final Future<? super Channel> future) throws Exception {
93                         finalConnectionFacade.fireConnectionReadyNotification();
94                     }
95                 });
96                 ch.pipeline().addLast(PipelineHandlers.SSL_HANDLER.name(), ssl);
97             }
98             ch.pipeline().addLast(PipelineHandlers.OF_FRAME_DECODER.name(),
99                     new OFFrameDecoder(connectionFacade, tlsPresent));
100             ch.pipeline().addLast(PipelineHandlers.OF_VERSION_DETECTOR.name(), new OFVersionDetector());
101             final OFDecoder ofDecoder = new OFDecoder();
102             ofDecoder.setDeserializationFactory(getDeserializationFactory());
103             ch.pipeline().addLast(PipelineHandlers.OF_DECODER.name(), ofDecoder);
104             final OFEncoder ofEncoder = new OFEncoder();
105             ofEncoder.setSerializationFactory(getSerializationFactory());
106             ch.pipeline().addLast(PipelineHandlers.OF_ENCODER.name(), ofEncoder);
107             ch.pipeline().addLast(PipelineHandlers.DELEGATING_INBOUND_HANDLER.name(), new DelegatingInboundHandler(connectionFacade));
108             if (!tlsPresent) {
109                 connectionFacade.fireConnectionReadyNotification();
110             }
111         } catch (final Exception e) {
112             LOGGER.warn("Failed to initialize channel", e);
113             ch.close();
114         }
115     }
116
117     /**
118      * @return iterator through active connections
119      */
120     public Iterator<Channel> getConnectionIterator() {
121         return allChannels.iterator();
122     }
123
124     /**
125      * @return amount of active channels
126      */
127     public int size() {
128         return allChannels.size();
129     }
130 }