Initial support for RFC2385
[bgpcep.git] / tcp-md5 / jni / src / main / java / org / opendaylight / bgpcep / tcpmd5 / jni / NativeKeyAccess.java
1 /*
2  * Copyright (c) 2013 Robert Varga. All rights reserved.
3  *
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
7  */
8 package org.opendaylight.bgpcep.tcpmd5.jni;
9
10 import java.io.IOException;
11 import java.nio.channels.Channel;
12
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
15
16 import com.google.common.base.Preconditions;
17
18 /**
19  * Implementation of KeyAccess using Java Native Interface plugin to talk
20  * directly to the underlying operating system.
21  */
22 public final class NativeKeyAccess implements KeyAccess {
23         private static final Logger LOG = LoggerFactory.getLogger(NativeKeyAccess.class);
24
25         static {
26                 NarSystem.loadLibrary();
27
28                 int rt = NarSystem.runUnitTests();
29                 if (rt == 0) {
30                         LOG.warn("Run-time initialization failed");
31                 } else {
32                         LOG.debug("Run-time found {} supported channel classes", rt);
33                 }
34         }
35
36         private static native boolean isClassSupported0(Class<?> channel);
37         private static native byte[] getChannelKey0(Channel channel) throws IOException;
38         private static native void setChannelKey0(Channel channel, byte[] key) throws IOException;
39
40         private final Channel channel;
41
42         private NativeKeyAccess(final Channel channel) {
43                 this.channel = Preconditions.checkNotNull(channel);
44         }
45
46         public static KeyAccess create(final Channel channel) {
47                 if (isClassSupported0(channel.getClass())) {
48                         return new NativeKeyAccess(channel);
49                 } else {
50                         return null;
51                 }
52         }
53
54         public static boolean isAvailableForClass(final Class<?> clazz) {
55                 return isClassSupported0(clazz);
56         }
57
58         @Override
59         public byte[] getKey() throws IOException {
60                 synchronized (channel) {
61                         return getChannelKey0(channel);
62                 }
63         }
64
65         @Override
66         public void setKey(final byte[] key) throws IOException {
67                 synchronized (channel) {
68                         setChannelKey0(channel, Preconditions.checkNotNull(key));
69                 }
70         }
71 }