blob: d5950b4a77472da4e5a7f01547fbd031bbdaef93 [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
Ray Milkey269ffb92014-04-03 14:43:30 -07002 * Copyright 2011, Big Switch Networks, Inc.
3 * Originally created by David Erickson, Stanford University
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License. You may obtain
7 * a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations
15 * under the License.
16 **/
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080017
18package net.floodlightcontroller.core.internal;
19
20import java.util.concurrent.TimeUnit;
21
22import net.floodlightcontroller.core.internal.OFChannelState.HandshakeState;
23
24import org.jboss.netty.channel.ChannelHandlerContext;
25import org.jboss.netty.channel.ChannelStateEvent;
26import org.jboss.netty.channel.Channels;
27import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
28import org.jboss.netty.util.ExternalResourceReleasable;
29import org.jboss.netty.util.Timeout;
30import org.jboss.netty.util.Timer;
31import org.jboss.netty.util.TimerTask;
32
33/**
34 * Trigger a timeout if a switch fails to complete handshake soon enough
35 */
Ray Milkey269ffb92014-04-03 14:43:30 -070036public class HandshakeTimeoutHandler
37 extends SimpleChannelUpstreamHandler
38 implements ExternalResourceReleasable {
39 static final HandshakeTimeoutException EXCEPTION =
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080040 new HandshakeTimeoutException();
Ray Milkey269ffb92014-04-03 14:43:30 -070041
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080042 final OFChannelState state;
43 final Timer timer;
44 final long timeoutNanos;
45 volatile Timeout timeout;
Ray Milkey269ffb92014-04-03 14:43:30 -070046
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080047 public HandshakeTimeoutHandler(OFChannelState state, Timer timer,
48 long timeoutSeconds) {
49 super();
50 this.state = state;
51 this.timer = timer;
52 this.timeoutNanos = TimeUnit.SECONDS.toNanos(timeoutSeconds);
53
54 }
Ray Milkey269ffb92014-04-03 14:43:30 -070055
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080056 @Override
57 public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
58 throws Exception {
59 if (timeoutNanos > 0) {
Ray Milkey269ffb92014-04-03 14:43:30 -070060 timeout = timer.newTimeout(new HandshakeTimeoutTask(ctx),
61 timeoutNanos, TimeUnit.NANOSECONDS);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080062 }
63 ctx.sendUpstream(e);
64 }
Ray Milkey269ffb92014-04-03 14:43:30 -070065
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080066 @Override
67 public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
68 throws Exception {
69 if (timeout != null) {
70 timeout.cancel();
71 timeout = null;
72 }
73 }
74
75 @Override
76 public void releaseExternalResources() {
77 timer.stop();
78 }
Ray Milkey269ffb92014-04-03 14:43:30 -070079
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080080 private final class HandshakeTimeoutTask implements TimerTask {
81
82 private final ChannelHandlerContext ctx;
83
84 HandshakeTimeoutTask(ChannelHandlerContext ctx) {
85 this.ctx = ctx;
86 }
87
88 @Override
89 public void run(Timeout timeout) throws Exception {
90 if (timeout.isCancelled()) {
91 return;
92 }
93
94 if (!ctx.getChannel().isOpen()) {
95 return;
96 }
97 if (!state.hsState.equals(HandshakeState.READY))
98 Channels.fireExceptionCaught(ctx, EXCEPTION);
99 }
100 }
101}