blob: de4da0fde28cb07d9c269df7a6482cb8e9e30c97 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
tom7ef8ff92014-09-17 13:08:06 -070019
tom9c94c5b2014-09-17 13:14:42 -070020package org.onlab.onos.openflow.controller.impl;
tom7ef8ff92014-09-17 13:08:06 -070021
22import java.util.concurrent.TimeUnit;
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.Timeout;
29import org.jboss.netty.util.Timer;
30import org.jboss.netty.util.TimerTask;
31
32/**
33 * Trigger a timeout if a switch fails to complete handshake soon enough.
34 */
35public class HandshakeTimeoutHandler
36 extends SimpleChannelUpstreamHandler {
37 static final HandshakeTimeoutException EXCEPTION =
38 new HandshakeTimeoutException();
39
40 final OFChannelHandler channelHandler;
41 final Timer timer;
42 final long timeoutNanos;
43 volatile Timeout timeout;
44
45 public HandshakeTimeoutHandler(OFChannelHandler channelHandler,
46 Timer timer,
47 long timeoutSeconds) {
48 super();
49 this.channelHandler = channelHandler;
50 this.timer = timer;
51 this.timeoutNanos = TimeUnit.SECONDS.toNanos(timeoutSeconds);
52
53 }
54
55 @Override
56 public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
57 throws Exception {
58 if (timeoutNanos > 0) {
59 timeout = timer.newTimeout(new HandshakeTimeoutTask(ctx),
60 timeoutNanos, TimeUnit.NANOSECONDS);
61 }
62 ctx.sendUpstream(e);
63 }
64
65 @Override
66 public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
67 throws Exception {
68 if (timeout != null) {
69 timeout.cancel();
70 timeout = null;
71 }
72 }
73
74 private final class HandshakeTimeoutTask implements TimerTask {
75
76 private final ChannelHandlerContext ctx;
77
78 HandshakeTimeoutTask(ChannelHandlerContext ctx) {
79 this.ctx = ctx;
80 }
81
82 @Override
83 public void run(Timeout t) throws Exception {
84 if (t.isCancelled()) {
85 return;
86 }
87
88 if (!ctx.getChannel().isOpen()) {
89 return;
90 }
91 if (!channelHandler.isHandshakeComplete()) {
92 Channels.fireExceptionCaught(ctx, EXCEPTION);
93 }
94 }
95 }
96}