2 * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved.
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
9 package org.opendaylight.openflowjava.protocol.impl.core;
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 java.net.InetAddress;
17 import java.util.Arrays;
18 import java.util.Iterator;
19 import java.util.List;
20 import java.util.concurrent.TimeUnit;
21 import javax.net.ssl.SSLEngine;
22 import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration;
23 import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterFactory;
24 import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterFactoryImpl;
25 import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionFacade;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
30 * Initializes TCP / TLS channel.
31 * @author michal.polkorab
33 public class TcpChannelInitializer extends ProtocolChannelInitializer<SocketChannel> {
35 private static final Logger LOG = LoggerFactory.getLogger(TcpChannelInitializer.class);
36 private final DefaultChannelGroup allChannels;
37 private final ConnectionAdapterFactory connectionAdapterFactory;
40 * Default constructor.
42 public TcpChannelInitializer() {
43 this(new DefaultChannelGroup("netty-receiver", null), new ConnectionAdapterFactoryImpl());
47 * Testing constructor.
49 protected TcpChannelInitializer(final DefaultChannelGroup channelGroup,
50 final ConnectionAdapterFactory connAdaptorFactory) {
51 allChannels = channelGroup;
52 connectionAdapterFactory = connAdaptorFactory;
56 @SuppressWarnings("checkstyle:IllegalCatch")
57 protected void initChannel(final SocketChannel ch) {
58 if (ch.remoteAddress() != null) {
59 final InetAddress switchAddress = ch.remoteAddress().getAddress();
60 final int port = ch.localAddress().getPort();
61 final int remotePort = ch.remoteAddress().getPort();
62 LOG.debug("Incoming connection from (remote address): {}:{} --> :{}",
63 switchAddress.toString(), remotePort, port);
65 if (!getSwitchConnectionHandler().accept(switchAddress)) {
67 LOG.debug("Incoming connection rejected");
71 LOG.debug("Incoming connection accepted - building pipeline");
73 ConnectionFacade connectionFacade = null;
74 connectionFacade = connectionAdapterFactory.createConnectionFacade(ch, null, useBarrier(),
75 getChannelOutboundQueueSize());
77 LOG.debug("Calling OF plugin: {}", getSwitchConnectionHandler());
78 getSwitchConnectionHandler().onSwitchConnected(connectionFacade);
79 connectionFacade.checkListeners();
81 // If this channel is configured to support SSL it will only support SSL
82 final TlsConfiguration tlsConfig = getTlsConfiguration();
83 if (tlsConfig != null) {
84 final SslContextFactory sslFactory = new SslContextFactory(tlsConfig);
85 final SSLEngine engine = sslFactory.getServerContext().createSSLEngine();
86 engine.setNeedClientAuth(true);
87 engine.setUseClientMode(false);
88 List<String> suitesList = getTlsConfiguration().getCipherSuites();
89 if (suitesList != null && !suitesList.isEmpty()) {
90 LOG.debug("Requested Cipher Suites are: {}", suitesList);
91 engine.setEnabledCipherSuites(suitesList.toArray(new String[0]));
92 LOG.debug("Cipher suites enabled in SSLEngine are: {}",
93 Arrays.toString(engine.getEnabledCipherSuites()));
95 final SslHandler ssl = new SslHandler(engine);
96 final Future<Channel> handshakeFuture = ssl.handshakeFuture();
97 final ConnectionFacade finalConnectionFacade = connectionFacade;
98 handshakeFuture.addListener(future -> finalConnectionFacade.onSwitchCertificateIdentified(
99 sslFactory.getSwitchCertificateChain()));
100 handshakeFuture.addListener(future -> finalConnectionFacade.fireConnectionReadyNotification());
101 ch.pipeline().addLast(PipelineHandlers.SSL_HANDLER.name(), ssl);
103 ch.pipeline().addLast(PipelineHandlers.OF_FRAME_DECODER.name(),
104 new OFFrameDecoder(connectionFacade, tlsConfig != null));
105 ch.pipeline().addLast(PipelineHandlers.OF_VERSION_DETECTOR.name(), new OFVersionDetector());
106 final OFDecoder ofDecoder = new OFDecoder();
107 ofDecoder.setDeserializationFactory(getDeserializationFactory());
108 ch.pipeline().addLast(PipelineHandlers.OF_DECODER.name(), ofDecoder);
109 final OFEncoder ofEncoder = new OFEncoder();
110 ofEncoder.setSerializationFactory(getSerializationFactory());
111 ch.pipeline().addLast(PipelineHandlers.OF_ENCODER.name(), ofEncoder);
112 ch.pipeline().addLast(PipelineHandlers.IDLE_HANDLER.name(),
113 new IdleHandler(getSwitchIdleTimeout(), TimeUnit.MILLISECONDS));
114 ch.pipeline().addLast(PipelineHandlers.DELEGATING_INBOUND_HANDLER.name(),
115 new DelegatingInboundHandler(connectionFacade));
117 if (tlsConfig == null) {
118 connectionFacade.fireConnectionReadyNotification();
120 } catch (RuntimeException e) {
121 LOG.warn("Failed to initialize channel", e);
127 * Returns the connection iterator.
129 * @return iterator through active connections
131 public Iterator<Channel> getConnectionIterator() {
132 return allChannels.iterator();
136 * Returns the number of active channels.
138 * @return amount of active channels
141 return allChannels.size();