KryoExtra no longer depends on concrete 'connection' implementation,

now uses crypto + rmi interfaces
This commit is contained in:
nathan 2016-03-20 08:02:30 +01:00
parent 2988ae4bb0
commit 0d768dd321
5 changed files with 105 additions and 15 deletions

View File

@ -63,7 +63,7 @@ import java.util.concurrent.atomic.AtomicLong;
@SuppressWarnings("unused")
@Sharable
public
class ConnectionImpl extends ChannelInboundHandlerAdapter implements Connection, ListenerBridge, ConnectionBridge {
class ConnectionImpl extends ChannelInboundHandlerAdapter implements ICryptoConnection, Connection, ListenerBridge, ConnectionBridge {
private final org.slf4j.Logger logger;
@ -155,7 +155,7 @@ class ConnectionImpl extends ChannelInboundHandlerAdapter implements Connection,
* because multiple protocols can be performing crypto AT THE SAME TIME, and so we have to make sure that operations don't
* clobber each other
*/
final
public final
ParametersWithIV getCryptoParameters() {
return this.channelWrapper.cryptoParameters();
}
@ -167,7 +167,7 @@ class ConnectionImpl extends ChannelInboundHandlerAdapter implements Connection,
* The 12 bytes IV is created during connection registration, and during the AES-GCM crypto, we override the last 8 with this
* counter, which is also transmitted as an optimized int. (which is why it starts at 0, so the transmitted bytes are small)
*/
final
public final
long getNextGcmSequence() {
return aes_gcm_iv.getAndIncrement();
}
@ -1104,6 +1104,12 @@ class ConnectionImpl extends ChannelInboundHandlerAdapter implements Connection,
}
}
/**
* Used by RMI
*
* @return the registered ID for a specific object. This is used by the "local" side when setting up the to fetch an object for the
* "remote" side for RMI
*/
public
<T> int getRegisteredId(final T object) {
// always check local before checking global, because less contention on the synchronization
@ -1122,7 +1128,7 @@ class ConnectionImpl extends ChannelInboundHandlerAdapter implements Connection,
}
/**
* Used by the LOCAL side, to get the proxy object as an interface
* Used by RMI for the LOCAL side, to get the proxy object as an interface
*
* @param type must be the interface the proxy will bind to
*/
@ -1142,7 +1148,7 @@ class ConnectionImpl extends ChannelInboundHandlerAdapter implements Connection,
}
/**
* This is used by the REMOTE side, to get the implementation
* This is used by RMI for the REMOTE side, to get the implementation
*/
public
Object getImplementationObject(final int objectID) {

View File

@ -0,0 +1,42 @@
/*
* Copyright 2010 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.connection;
import org.bouncycastle.crypto.params.ParametersWithIV;
/**
* Supporting methods for encrypting data to a remote endpoint
*/
public
interface ICryptoConnection extends IRmiConnection {
/**
* This is the per-message sequence number.
*
* The IV for AES-GCM must be 12 bytes, since it's 4 (salt) + 8 (external counter) + 4 (GCM counter)
* The 12 bytes IV is created during connection registration, and during the AES-GCM crypto, we override the last 8 with this
* counter, which is also transmitted as an optimized int. (which is why it starts at 0, so the transmitted bytes are small)
*/
long getNextGcmSequence();
/**
* @return a threadlocal AES key + IV. key=32 byte, iv=12 bytes (AES-GCM implementation). This is a threadlocal
* because multiple protocols can be performing crypto AT THE SAME TIME, and so we have to make sure that operations don't
* clobber each other
*/
ParametersWithIV getCryptoParameters();
}

View File

@ -0,0 +1,45 @@
/*
* Copyright 2010 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.connection;
import dorkbox.network.rmi.RemoteObject;
/**
* Supporting methods for RMI connections
*/
public
interface IRmiConnection {
/**
* Used by RMI for the LOCAL side, to get the proxy object as an interface
*
* @param type must be the interface the proxy will bind to
*/
RemoteObject getProxyObject(final int objectID, final Class<?> type);
/**
* This is used by RMI for the REMOTE side, to get the implementation
*/
Object getImplementationObject(final int objectID);
/**
* Used by RMI
*
* @return the registered ID for a specific object. This is used by the "local" side when setting up the to fetch an object for the
* "remote" side for RMI
*/
<T> int getRegisteredId(final T object);
}

View File

@ -36,7 +36,7 @@ import java.io.IOException;
* Nothing in this class is thread safe
*/
public
class KryoExtra extends Kryo {
class KryoExtra<C extends ICryptoConnection> extends Kryo {
/**
* bit masks
*/
@ -53,7 +53,7 @@ class KryoExtra extends Kryo {
private final ByteBufOutput writer = new ByteBufOutput();
// volatile to provide object visibility for entire class
public volatile ConnectionImpl connection;
public volatile IRmiConnection connection;
private final GCMBlockCipher aesEngine = new GCMBlockCipher(new AESFastEngine());
@ -124,7 +124,7 @@ class KryoExtra extends Kryo {
}
public synchronized
void writeCompressed(final ConnectionImpl connection, final ByteBuf buffer, final Object message) throws IOException {
void writeCompressed(final C connection, final ByteBuf buffer, final Object message) throws IOException {
// required by RMI and some serializers to determine which connection wrote (or has info about) this object
this.connection = connection;
@ -217,7 +217,7 @@ class KryoExtra extends Kryo {
}
public
Object readCompressed(final ConnectionImpl connection, final ByteBuf buffer, int length) throws IOException {
Object readCompressed(final C connection, final ByteBuf buffer, int length) throws IOException {
// required by RMI and some serializers to determine which connection wrote (or has info about) this object
this.connection = connection;
@ -305,7 +305,7 @@ class KryoExtra extends Kryo {
}
public synchronized
void writeCrypto(final ConnectionImpl connection, final ByteBuf buffer, final Object message) throws IOException {
void writeCrypto(final C connection, final ByteBuf buffer, final Object message) throws IOException {
// required by RMI and some serializers to determine which connection wrote (or has info about) this object
this.connection = connection;
@ -443,7 +443,7 @@ class KryoExtra extends Kryo {
}
public
Object readCrypto(final ConnectionImpl connection, final ByteBuf buffer, int length) throws IOException {
Object readCrypto(final C connection, final ByteBuf buffer, int length) throws IOException {
// required by RMI and some serializers to determine which connection wrote (or has info about) this object
this.connection = connection;

View File

@ -38,7 +38,6 @@ import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import dorkbox.network.connection.ConnectionImpl;
import dorkbox.network.connection.KryoExtra;
/**
@ -72,8 +71,6 @@ class RemoteObjectSerializer<T> extends Serializer<T> {
T read(Kryo kryo, Input input, Class type) {
KryoExtra kryoExtra = (KryoExtra) kryo;
int objectID = input.readInt(true);
final ConnectionImpl connection = kryoExtra.connection;
return (T) connection.getProxyObject(objectID, type);
return (T) kryoExtra.connection.getProxyObject(objectID, type);
}
}