blob: 406d09c1ca7be85dd9077957d3f0fbde6f18a18e [file] [log] [blame]
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * 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
7 *
8 * 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.
15 */
16package org.onosproject.isis.controller.impl;
17
18import com.fasterxml.jackson.databind.JsonNode;
19import org.jboss.netty.bootstrap.ClientBootstrap;
20import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictor;
21import org.jboss.netty.channel.ChannelFuture;
sunish vk4b5ce002016-05-09 20:18:35 +053022import org.jboss.netty.channel.ChannelFutureListener;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053023import org.jboss.netty.channel.ChannelPipelineFactory;
24import org.jboss.netty.channel.FixedReceiveBufferSizePredictorFactory;
25import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
26import org.onlab.packet.Ip4Address;
27import org.onlab.packet.MacAddress;
28import org.onlab.packet.TpPort;
29import org.onosproject.isis.controller.IsisInterface;
30import org.onosproject.isis.controller.IsisNetworkType;
31import org.onosproject.isis.controller.IsisProcess;
32import org.onosproject.isis.controller.IsisRouterType;
sunish vk7bdf4d42016-06-24 12:29:43 +053033import org.onosproject.isis.controller.topology.IsisAgent;
34import org.onosproject.isis.controller.topology.IsisLink;
35import org.onosproject.isis.controller.topology.IsisRouter;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053036import org.onosproject.isis.io.util.IsisConstants;
37import org.slf4j.Logger;
38import org.slf4j.LoggerFactory;
39
40import java.net.InetAddress;
41import java.net.InetSocketAddress;
sunish vk4b5ce002016-05-09 20:18:35 +053042import java.net.NetworkInterface;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053043import java.net.UnknownHostException;
44import java.util.ArrayList;
sunish vk4b5ce002016-05-09 20:18:35 +053045import java.util.Enumeration;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053046import java.util.List;
47import java.util.concurrent.Executors;
sunish vk4b5ce002016-05-09 20:18:35 +053048import java.util.concurrent.ScheduledExecutorService;
sunish vk7bdf4d42016-06-24 12:29:43 +053049import java.util.concurrent.ScheduledFuture;
sunish vk4b5ce002016-05-09 20:18:35 +053050import java.util.concurrent.TimeUnit;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053051
52import static org.onlab.util.Tools.groupedThreads;
53
54/**
55 * Representation of an ISIS controller.
56 */
57public class Controller {
58 protected static final int BUFFER_SIZE = 4 * 1024 * 1024;
59 private static final Logger log = LoggerFactory.getLogger(Controller.class);
sunish vk4b5ce002016-05-09 20:18:35 +053060 private static final int RETRY_INTERVAL = 4;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053061 private final int peerWorkerThreads = 16;
sunish vk4b5ce002016-05-09 20:18:35 +053062 byte[] configPacket = null;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053063 private List<IsisProcess> processes = null;
64 private IsisChannelHandler isisChannelHandler;
65 private NioClientSocketChannelFactory peerExecFactory;
66 private ClientBootstrap peerBootstrap = null;
67 private TpPort isisPort = TpPort.tpPort(IsisConstants.SPORT);
sunish vk4b5ce002016-05-09 20:18:35 +053068 private ScheduledExecutorService connectExecutor = null;
69 private int connectRetryCounter = 0;
70 private int connectRetryTime;
sunish vk7bdf4d42016-06-24 12:29:43 +053071 private ScheduledFuture future = null;
72 private IsisAgent agent;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053073
74 /**
75 * Deactivates ISIS controller.
76 */
77 public void isisDeactivate() {
sunish vk7bdf4d42016-06-24 12:29:43 +053078 disconnectExecutor();
79 processes = null;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053080 peerExecFactory.shutdown();
81 }
82
83 /**
sunish vk7bdf4d42016-06-24 12:29:43 +053084 * Sets ISIS agent.
85 *
86 * @param agent ISIS agent instance
87 */
88 public void setAgent(IsisAgent agent) {
89 this.agent = agent;
90 }
91
92
93 /**
tejeshwer degala3fe1ed52016-04-22 17:04:01 +053094 * Updates the processes configuration.
95 *
96 * @param jsonNode json node instance
97 * @throws Exception might throws parse exception
98 */
99 public void updateConfig(JsonNode jsonNode) throws Exception {
100 log.debug("Controller::UpdateConfig called");
sunish vk4b5ce002016-05-09 20:18:35 +0530101 configPacket = new byte[IsisConstants.CONFIG_LENGTH];
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530102 byte numberOfInterface = 0; // number of interfaces to configure
103
104 configPacket[0] = (byte) 0xFF; // its a conf packet - identifier
105 List<IsisProcess> isisProcesses = getConfig(jsonNode);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530106 for (IsisProcess isisProcess : isisProcesses) {
107 log.debug("IsisProcessDetails : " + isisProcess);
108 for (IsisInterface isisInterface : isisProcess.isisInterfaceList()) {
109 DefaultIsisInterface isisInterfaceImpl = (DefaultIsisInterface) isisInterface;
110 log.debug("IsisInterfaceDetails : " + isisInterface);
111 numberOfInterface++;
112 configPacket[2 * numberOfInterface] = (byte) isisInterfaceImpl.interfaceIndex();
113 if (isisInterface.networkType() == IsisNetworkType.BROADCAST &&
114 isisInterfaceImpl.reservedPacketCircuitType() == IsisRouterType.L1.value()) {
115 configPacket[(2 * numberOfInterface) + 1] = (byte) 0;
116 } else if (isisInterface.networkType() == IsisNetworkType.BROADCAST &&
117 isisInterfaceImpl.reservedPacketCircuitType() == IsisRouterType.L2.value()) {
118 configPacket[(2 * numberOfInterface) + 1] = (byte) 1;
119 } else if (isisInterface.networkType() == IsisNetworkType.P2P) {
120 configPacket[(2 * numberOfInterface) + 1] = (byte) 2;
121 } else if (isisInterface.networkType() == IsisNetworkType.BROADCAST &&
122 isisInterfaceImpl.reservedPacketCircuitType() == IsisRouterType.L1L2.value()) {
123 configPacket[(2 * numberOfInterface) + 1] = (byte) 3;
124 }
125 }
126 }
127 configPacket[1] = numberOfInterface;
128 //First time configuration
129 if (processes == null) {
sunish vk4b5ce002016-05-09 20:18:35 +0530130 if (isisProcesses.size() > 0) {
131 processes = isisProcesses;
132 connectPeer();
sunish vk4b5ce002016-05-09 20:18:35 +0530133 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530134 } else {
135 isisChannelHandler.updateInterfaceMap(isisProcesses);
sunish vk4b5ce002016-05-09 20:18:35 +0530136 //Send the config packet
137 isisChannelHandler.sentConfigPacket(configPacket);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530138 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530139 }
140
141 /**
142 * Initializes the netty client channel connection.
143 */
144 private void initConnection() {
145 if (peerBootstrap != null) {
146 return;
147 }
148 peerBootstrap = createPeerBootStrap();
149
150 peerBootstrap.setOption("reuseAddress", true);
151 peerBootstrap.setOption("tcpNoDelay", true);
152 peerBootstrap.setOption("keepAlive", true);
153 peerBootstrap.setOption("receiveBufferSize", Controller.BUFFER_SIZE);
154 peerBootstrap.setOption("receiveBufferSizePredictorFactory",
sunish vk7bdf4d42016-06-24 12:29:43 +0530155 new FixedReceiveBufferSizePredictorFactory(
156 Controller.BUFFER_SIZE));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530157 peerBootstrap.setOption("receiveBufferSizePredictor",
sunish vk7bdf4d42016-06-24 12:29:43 +0530158 new AdaptiveReceiveBufferSizePredictor(64, 1024, 65536));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530159 peerBootstrap.setOption("child.keepAlive", true);
160 peerBootstrap.setOption("child.tcpNoDelay", true);
161 peerBootstrap.setOption("child.sendBufferSize", Controller.BUFFER_SIZE);
162 peerBootstrap.setOption("child.receiveBufferSize", Controller.BUFFER_SIZE);
163 peerBootstrap.setOption("child.receiveBufferSizePredictorFactory",
sunish vk7bdf4d42016-06-24 12:29:43 +0530164 new FixedReceiveBufferSizePredictorFactory(
165 Controller.BUFFER_SIZE));
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530166 peerBootstrap.setOption("child.reuseAddress", true);
167
168 isisChannelHandler = new IsisChannelHandler(this, processes);
169 ChannelPipelineFactory pfact = new IsisPipelineFactory(isisChannelHandler);
170 peerBootstrap.setPipelineFactory(pfact);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530171 }
172
173 /**
174 * Creates peer boot strap.
175 *
176 * @return client bootstrap instance
177 */
178 private ClientBootstrap createPeerBootStrap() {
179
180 if (peerWorkerThreads == 0) {
181 peerExecFactory = new NioClientSocketChannelFactory(
182 Executors.newCachedThreadPool(groupedThreads("onos/isis", "boss-%d")),
183 Executors.newCachedThreadPool(groupedThreads("onos/isis", "worker-%d")));
184 return new ClientBootstrap(peerExecFactory);
185 } else {
186 peerExecFactory = new NioClientSocketChannelFactory(
187 Executors.newCachedThreadPool(groupedThreads("onos/isis", "boss-%d")),
188 Executors.newCachedThreadPool(groupedThreads("onos/isis", "worker-%d")),
189 peerWorkerThreads);
190 return new ClientBootstrap(peerExecFactory);
191 }
192 }
193
194 /**
195 * Gets all configured processes.
196 *
197 * @return all configured processes
198 */
199 public List<IsisProcess> getAllConfiguredProcesses() {
200 return processes;
201 }
202
203 /**
204 * Gets the list of processes configured.
205 *
206 * @param json posted json
207 * @return list of processes configured
208 */
209 private List<IsisProcess> getConfig(JsonNode json) throws Exception {
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530210 List<IsisProcess> isisProcessesList = new ArrayList<>();
211 JsonNode jsonNodes = json;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530212 if (jsonNodes == null) {
213 return isisProcessesList;
214 }
215 jsonNodes.forEach(jsonNode -> {
216 List<IsisInterface> interfaceList = new ArrayList<>();
217 for (JsonNode jsonNode1 : jsonNode.path(IsisConstants.INTERFACE)) {
218 IsisInterface isisInterface = new DefaultIsisInterface();
sunish vk4b5ce002016-05-09 20:18:35 +0530219 String index = jsonNode1.path(IsisConstants.INTERFACEINDEX).asText();
220 if (isPrimitive(index)) {
221 int input = Integer.parseInt(index);
222 if (input < 1 || input > 255) {
223 log.debug("Wrong interface index: {}", index);
224 continue;
225 }
226 isisInterface.setInterfaceIndex(Integer.parseInt(index));
227 } else {
228 log.debug("Wrong interface index {}", index);
229 continue;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530230 }
sunish vk4b5ce002016-05-09 20:18:35 +0530231 Ip4Address ipAddress = getInterfaceIp(isisInterface.interfaceIndex());
232 if (ipAddress != null && !ipAddress.equals(IsisConstants.DEFAULTIP)) {
233 isisInterface.setInterfaceIpAddress(ipAddress);
234 } else {
235 log.debug("Wrong interface index {}. No matching interface in system.", index);
236 continue;
237 }
238 MacAddress macAddress = getInterfaceMac(isisInterface.interfaceIndex());
239 if (macAddress != null) {
240 isisInterface.setInterfaceMacAddress(macAddress);
241 } else {
242 log.debug("Wrong interface index {}. No matching interface in system.", index);
243 continue;
244 }
245 String mask = getInterfaceMask(isisInterface.interfaceIndex());
246 if (mask != null) {
247 try {
248 isisInterface.setNetworkMask(InetAddress.getByName(mask).getAddress());
249 } catch (UnknownHostException e) {
250 log.debug("Wrong interface index {}. Error while getting network mask.", index);
251 }
252 } else {
253 log.debug("Wrong interface index {}. Error while getting network mask.", index);
254 continue;
255 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530256 isisInterface.setIntermediateSystemName(jsonNode1
sunish vk7bdf4d42016-06-24 12:29:43 +0530257 .path(IsisConstants.INTERMEDIATESYSTEMNAME)
258 .asText());
sunish vk4b5ce002016-05-09 20:18:35 +0530259 String systemId = jsonNode1.path(IsisConstants.SYSTEMID).asText();
260 if (isValidSystemId(systemId)) {
261 isisInterface.setSystemId(systemId);
262 } else {
263 log.debug("Wrong systemId: {} for interface index {}.", systemId, index);
264 continue;
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530265 }
sunish vk4b5ce002016-05-09 20:18:35 +0530266 String circuitType = jsonNode1.path(IsisConstants.RESERVEDPACKETCIRCUITTYPE).asText();
267 if (isPrimitive(circuitType)) {
268 int input = Integer.parseInt(circuitType);
269 if (input < 1 || input > 3) {
270 log.debug("Wrong ReservedPacketCircuitType: {} for interface index {}.", circuitType, index);
271 continue;
272 }
273 isisInterface.setReservedPacketCircuitType(input);
274 } else {
275 log.debug("Wrong ReservedPacketCircuitType: {} for interface index {}.", circuitType, index);
276 continue;
277 }
278 String networkType = jsonNode1.path(IsisConstants.NETWORKTYPE).asText();
279 if (isPrimitive(networkType)) {
280 int input = Integer.parseInt(networkType);
281 if (input < 1 || input > 2) {
282 log.debug("Wrong networkType: {} for interface index {}.", networkType, index);
283 continue;
284 }
285 isisInterface.setNetworkType(IsisNetworkType.get(input));
286 } else {
287 log.debug("Wrong networkType: {} for interface index {}.", networkType, index);
288 continue;
289 }
290 String areaAddress = jsonNode1.path(IsisConstants.AREAADDRESS).asText();
291 if (isPrimitive(areaAddress)) {
292 if (areaAddress.length() > 7) {
293 log.debug("Wrong areaAddress: {} for interface index {}.", areaAddress, index);
294 continue;
295 }
296 isisInterface.setAreaAddress(areaAddress);
297 } else {
298 log.debug("Wrong areaAddress: {} for interface index {}.", areaAddress, index);
299 continue;
300 }
301 String circuitId = jsonNode1.path(IsisConstants.CIRCUITID).asText();
302 if (isPrimitive(circuitId)) {
303 int input = Integer.parseInt(circuitId);
304 if (input < 1) {
305 log.debug("Wrong circuitId: {} for interface index {}.", circuitId, index);
306 continue;
307 }
308 isisInterface.setCircuitId(circuitId);
309 } else {
310 log.debug("Wrong circuitId: {} for interface index {}.", circuitId, index);
311 continue;
312 }
313 String holdingTime = jsonNode1.path(IsisConstants.HOLDINGTIME).asText();
314 if (isPrimitive(holdingTime)) {
315 int input = Integer.parseInt(holdingTime);
316 if (input < 1 || input > 255) {
317 log.debug("Wrong holdingTime: {} for interface index {}.", holdingTime, index);
318 continue;
319 }
320 isisInterface.setHoldingTime(input);
321 } else {
322 log.debug("Wrong holdingTime: {} for interface index {}.", holdingTime, index);
323 continue;
324 }
325 String helloInterval = jsonNode1.path(IsisConstants.HELLOINTERVAL).asText();
326 if (isPrimitive(helloInterval)) {
327 int interval = Integer.parseInt(helloInterval);
328 if (interval > 0 && interval <= 255) {
329 isisInterface.setHelloInterval(interval);
330 } else {
331 log.debug("Wrong hello interval: {} for interface index {}.", helloInterval, index);
332 continue;
333 }
334 } else {
335 log.debug("Wrong hello interval: {} for interface index {}.", helloInterval, index);
336 continue;
337 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530338 interfaceList.add(isisInterface);
339 }
sunish vk4b5ce002016-05-09 20:18:35 +0530340 if (interfaceList.size() > 0) {
341 IsisProcess process = new DefaultIsisProcess();
342 process.setProcessId(jsonNode.path(IsisConstants.PROCESSESID).asText());
343 process.setIsisInterfaceList(interfaceList);
344 isisProcessesList.add(process);
345 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530346 });
347
348 return isisProcessesList;
349 }
sunish vk4b5ce002016-05-09 20:18:35 +0530350
351 /**
352 * Returns interface MAC by index.
353 *
354 * @param interfaceIndex interface index
355 * @return interface IP by index
356 */
357 private MacAddress getInterfaceMac(int interfaceIndex) {
358 MacAddress macAddress = null;
359 try {
360 NetworkInterface networkInterface = NetworkInterface.getByIndex(interfaceIndex);
361 macAddress = MacAddress.valueOf(networkInterface.getHardwareAddress());
362 } catch (Exception e) {
363 log.debug("Error while getting Interface IP by index");
364 return macAddress;
365 }
366
367 return macAddress;
368 }
369
370 /**
371 * Returns interface IP by index.
372 *
373 * @param interfaceIndex interface index
374 * @return interface IP by index
375 */
376 private Ip4Address getInterfaceIp(int interfaceIndex) {
377 Ip4Address ipAddress = null;
378 try {
379 NetworkInterface networkInterface = NetworkInterface.getByIndex(interfaceIndex);
380 Enumeration ipAddresses = networkInterface.getInetAddresses();
381 while (ipAddresses.hasMoreElements()) {
382 InetAddress address = (InetAddress) ipAddresses.nextElement();
383 if (!address.isLinkLocalAddress()) {
384 ipAddress = Ip4Address.valueOf(address.getAddress());
385 break;
386 }
387 }
388 } catch (Exception e) {
389 log.debug("Error while getting Interface IP by index");
390 return IsisConstants.DEFAULTIP;
391 }
392 return ipAddress;
393 }
394
395 /**
396 * Returns interface MAC by index.
397 *
398 * @param interfaceIndex interface index
399 * @return interface IP by index
400 */
401 private String getInterfaceMask(int interfaceIndex) {
402 String subnetMask = null;
403 try {
404 Ip4Address ipAddress = getInterfaceIp(interfaceIndex);
405 NetworkInterface networkInterface = NetworkInterface.getByInetAddress(
406 InetAddress.getByName(ipAddress.toString()));
407 Enumeration ipAddresses = networkInterface.getInetAddresses();
408 int index = 0;
409 while (ipAddresses.hasMoreElements()) {
410 InetAddress address = (InetAddress) ipAddresses.nextElement();
411 if (!address.isLinkLocalAddress()) {
412 break;
413 }
414 index++;
415 }
416 int prfLen = networkInterface.getInterfaceAddresses().get(index).getNetworkPrefixLength();
417 int shft = 0xffffffff << (32 - prfLen);
418 int oct1 = ((byte) ((shft & 0xff000000) >> 24)) & 0xff;
419 int oct2 = ((byte) ((shft & 0x00ff0000) >> 16)) & 0xff;
420 int oct3 = ((byte) ((shft & 0x0000ff00) >> 8)) & 0xff;
421 int oct4 = ((byte) (shft & 0x000000ff)) & 0xff;
422 subnetMask = oct1 + "." + oct2 + "." + oct3 + "." + oct4;
423 } catch (Exception e) {
424 log.debug("Error while getting Interface network mask by index");
425 return subnetMask;
426 }
427 return subnetMask;
428 }
429
430 /**
431 * Checks if primitive or not.
432 *
433 * @param value input value
434 * @return true if number else false
435 */
436 private boolean isPrimitive(String value) {
437 boolean status = true;
438 value = value.trim();
439 if (value.length() < 1) {
440 return false;
441 }
442 for (int i = 0; i < value.length(); i++) {
443 char c = value.charAt(i);
444 if (!Character.isDigit(c)) {
445 status = false;
446 break;
447 }
448 }
449
450 return status;
451 }
452
453 /**
454 * Checks if system id is valid or not.
455 *
456 * @param value input value
457 * @return true if valid else false
458 */
459 private boolean isValidSystemId(String value) {
460 value = value.trim();
461 boolean status = true;
462 if (value.length() != 14) {
463 return false;
464 }
465 for (int i = 0; i < value.length(); i++) {
466 char c = value.charAt(i);
467 if (!Character.isDigit(c)) {
468 if (!((i == 4 || i == 9) && c == '.')) {
469 status = false;
470 break;
471 }
472 }
473 }
474
475 return status;
476 }
477
478 /**
479 * Disconnects the executor.
480 */
481 public void disconnectExecutor() {
482 if (connectExecutor != null) {
sunish vk7bdf4d42016-06-24 12:29:43 +0530483 future.cancel(true);
484 connectExecutor.shutdownNow();
sunish vk4b5ce002016-05-09 20:18:35 +0530485 connectExecutor = null;
486 }
487 }
488
489 /**
490 * Connects to peer.
491 */
492 public void connectPeer() {
493 scheduleConnectionRetry(this.connectRetryTime);
494 }
495
496 /**
497 * Retry connection with exponential back-off mechanism.
498 *
499 * @param retryDelay retry delay
500 */
501 private void scheduleConnectionRetry(long retryDelay) {
sunish vk7bdf4d42016-06-24 12:29:43 +0530502 if (connectExecutor == null) {
503 connectExecutor = Executors.newSingleThreadScheduledExecutor();
sunish vk4b5ce002016-05-09 20:18:35 +0530504 }
sunish vk7bdf4d42016-06-24 12:29:43 +0530505 future = connectExecutor.schedule(new ConnectionRetry(), retryDelay, TimeUnit.MINUTES);
506 }
507
508 /**
509 * Adds device details.
510 *
511 * @param isisRouter ISIS router instance
512 */
513 public void addDeviceDetails(IsisRouter isisRouter) {
514 agent.addConnectedRouter(isisRouter);
515 }
516
517 /**
518 * Removes device details.
519 *
520 * @param isisRouter Isis router instance
521 */
522 public void removeDeviceDetails(IsisRouter isisRouter) {
523 agent.removeConnectedRouter(isisRouter);
524 }
525
526 /**
527 * Adds link details.
528 *
529 * @param isisLink ISIS link instance
530 */
531 public void addLinkDetails(IsisLink isisLink) {
532 agent.addLink(isisLink);
533 }
534
535 /**
536 * Removes link details.
537 *
538 * @param isisLink ISIS link instance
539 */
540 public void removeLinkDetails(IsisLink isisLink) {
541 agent.deleteLink(isisLink);
542 }
543
544 /**
545 * Returns the isisAgent instance.
546 *
547 * @return agent
548 */
549 public IsisAgent agent() {
550 return this.agent;
sunish vk4b5ce002016-05-09 20:18:35 +0530551 }
552
553 /**
554 * Implements ISIS connection and manages connection to peer with back-off mechanism in case of failure.
555 */
556 class ConnectionRetry implements Runnable {
557 @Override
558 public void run() {
559 log.debug("Connect to peer {}", IsisConstants.SHOST);
560 initConnection();
sunish vkc3824e82016-05-11 19:38:24 +0530561 isisChannelHandler.sentConfigPacket(configPacket);
sunish vk4b5ce002016-05-09 20:18:35 +0530562 InetSocketAddress connectToSocket = new InetSocketAddress(IsisConstants.SHOST, isisPort.toInt());
563 try {
564 peerBootstrap.connect(connectToSocket).addListener(new ChannelFutureListener() {
565 @Override
566 public void operationComplete(ChannelFuture future) throws Exception {
567 if (!future.isSuccess()) {
568 connectRetryCounter++;
569 log.error("Connection failed, ConnectRetryCounter {} remote host {}", connectRetryCounter,
sunish vk7bdf4d42016-06-24 12:29:43 +0530570 IsisConstants.SHOST);
sunish vk4b5ce002016-05-09 20:18:35 +0530571 /*
572 * Reconnect to peer on failure is exponential till 4 mins, later on retry after every 4
573 * mins.
574 */
575 if (connectRetryTime < RETRY_INTERVAL) {
576 connectRetryTime = (connectRetryTime != 0) ? connectRetryTime * 2 : 1;
577 }
578 scheduleConnectionRetry(connectRetryTime);
579 } else {
sunish vkc3824e82016-05-11 19:38:24 +0530580 //Send the config packet
581 isisChannelHandler.sentConfigPacket(configPacket);
sunish vk4b5ce002016-05-09 20:18:35 +0530582 connectRetryCounter++;
583 log.info("Connected to remote host {}, Connect Counter {}", IsisConstants.SHOST,
sunish vk7bdf4d42016-06-24 12:29:43 +0530584 connectRetryCounter);
sunish vk4b5ce002016-05-09 20:18:35 +0530585 disconnectExecutor();
sunish vkc3824e82016-05-11 19:38:24 +0530586
sunish vk4b5ce002016-05-09 20:18:35 +0530587 return;
588 }
589 }
590 });
591 } catch (Exception e) {
592 log.info("Connect peer exception : " + e.toString());
593 disconnectExecutor();
594 }
595 }
596 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530597}