blob: d9f2886a8aeb4ef66bdf124aeabfd9c162248db4 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
tom7ef8ff92014-09-17 13:08:06 -070016
tom9c94c5b2014-09-17 13:14:42 -070017package org.onlab.onos.openflow.controller.impl;
tom7ef8ff92014-09-17 13:08:06 -070018
19import java.util.concurrent.TimeUnit;
20
21import org.jboss.netty.channel.ChannelHandlerContext;
22import org.jboss.netty.channel.ChannelStateEvent;
23import org.jboss.netty.channel.Channels;
24import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
25import org.jboss.netty.util.Timeout;
26import org.jboss.netty.util.Timer;
27import org.jboss.netty.util.TimerTask;
28
29/**
30 * Trigger a timeout if a switch fails to complete handshake soon enough.
31 */
32public class HandshakeTimeoutHandler
33 extends SimpleChannelUpstreamHandler {
34 static final HandshakeTimeoutException EXCEPTION =
35 new HandshakeTimeoutException();
36
37 final OFChannelHandler channelHandler;
38 final Timer timer;
39 final long timeoutNanos;
40 volatile Timeout timeout;
41
42 public HandshakeTimeoutHandler(OFChannelHandler channelHandler,
43 Timer timer,
44 long timeoutSeconds) {
45 super();
46 this.channelHandler = channelHandler;
47 this.timer = timer;
48 this.timeoutNanos = TimeUnit.SECONDS.toNanos(timeoutSeconds);
49
50 }
51
52 @Override
53 public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
54 throws Exception {
55 if (timeoutNanos > 0) {
56 timeout = timer.newTimeout(new HandshakeTimeoutTask(ctx),
57 timeoutNanos, TimeUnit.NANOSECONDS);
58 }
59 ctx.sendUpstream(e);
60 }
61
62 @Override
63 public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
64 throws Exception {
65 if (timeout != null) {
66 timeout.cancel();
67 timeout = null;
68 }
69 }
70
71 private final class HandshakeTimeoutTask implements TimerTask {
72
73 private final ChannelHandlerContext ctx;
74
75 HandshakeTimeoutTask(ChannelHandlerContext ctx) {
76 this.ctx = ctx;
77 }
78
79 @Override
80 public void run(Timeout t) throws Exception {
81 if (t.isCancelled()) {
82 return;
83 }
84
85 if (!ctx.getChannel().isOpen()) {
86 return;
87 }
88 if (!channelHandler.isHandshakeComplete()) {
89 Channels.fireExceptionCaught(ctx, EXCEPTION);
90 }
91 }
92 }
93}