/hazelcast/src/main/java/com/hazelcast/nio/SocketPacketReader.java
https://bitbucket.org/gabral6_gmailcom/hazelcast · Java · 214 lines · 177 code · 22 blank · 15 comment · 39 complexity · d81ee77714b9cfefb3cdf0eb0a24e8ce MD5 · raw file
- /*
- * Copyright (c) 2008-2013, Hazelcast, Inc. All Rights Reserved.
- *
- * 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 com.hazelcast.nio;
- import com.hazelcast.logging.ILogger;
- import javax.crypto.Cipher;
- import javax.crypto.ShortBufferException;
- import java.nio.ByteBuffer;
- import java.util.logging.Level;
- import static com.hazelcast.nio.IOUtil.copyToHeapBuffer;
- class SocketPacketReader implements SocketReader {
- Packet packet = null;
- final PacketReader packetReader;
- final Connection connection;
- final IOService ioService;
- final SocketChannelWrapper socketChannel;
- final ILogger logger;
- public SocketPacketReader(SocketChannelWrapper socketChannel, Connection connection) {
- this.connection = connection;
- this.ioService = connection.getConnectionManager().ioService;
- this.socketChannel = socketChannel;
- this.logger = ioService.getLogger(SocketPacketReader.class.getName());
- boolean symmetricEncryptionEnabled = CipherHelper.isSymmetricEncryptionEnabled(ioService);
- boolean asymmetricEncryptionEnabled = CipherHelper.isAsymmetricEncryptionEnabled(ioService);
- if (asymmetricEncryptionEnabled || symmetricEncryptionEnabled) {
- if (asymmetricEncryptionEnabled && symmetricEncryptionEnabled) {
- packetReader = new ComplexCipherPacketReader();
- logger.log(Level.INFO, "Reader started with ComplexEncryption");
- } else if (symmetricEncryptionEnabled) {
- packetReader = new SymmetricCipherPacketReader();
- logger.log(Level.INFO, "Reader started with SymmetricEncryption");
- } else {
- packetReader = new AsymmetricCipherPacketReader();
- logger.log(Level.INFO, "Reader started with AsymmetricEncryption");
- }
- } else {
- packetReader = new DefaultPacketReader();
- }
- }
- public void read(ByteBuffer inBuffer) throws Exception {
- packetReader.readPacket(inBuffer);
- }
- public void enqueueFullPacket(final Packet p) {
- p.flipBuffers();
- p.read();
- p.setFromConnection(connection);
- if (p.client) {
- connection.setType(Connection.Type.CLIENT);
- ioService.handleClientPacket(p);
- } else {
- connection.setType(Connection.Type.MEMBER);
- ioService.handleMemberPacket(p);
- }
- }
- interface PacketReader {
- void readPacket(ByteBuffer inBuffer) throws Exception;
- }
- class DefaultPacketReader implements PacketReader {
- public void readPacket(ByteBuffer inBuffer) {
- while (inBuffer.hasRemaining()) {
- if (packet == null) {
- packet = obtainReadable();
- }
- boolean complete = packet.read(inBuffer);
- if (complete) {
- enqueueFullPacket(packet);
- packet = null;
- }
- }
- }
- }
- class ComplexCipherPacketReader implements PacketReader {
- ComplexCipherPacketReader() {
- }
- public void readPacket(ByteBuffer inBuffer) throws Exception {
- }
- }
- class AsymmetricCipherPacketReader implements PacketReader {
- Cipher cipher = null;
- ByteBuffer cipherBuffer = ByteBuffer.allocate(128);
- ByteBuffer bbAlias = null;
- boolean aliasSizeSet = false;
- public void readPacket(ByteBuffer inBuffer) throws Exception {
- if (cipher == null) {
- if (!aliasSizeSet) {
- if (inBuffer.remaining() < 4) {
- return;
- } else {
- int aliasSize = inBuffer.getInt();
- bbAlias = ByteBuffer.allocate(aliasSize);
- }
- }
- copyToHeapBuffer(inBuffer, bbAlias);
- if (!bbAlias.hasRemaining()) {
- bbAlias.flip();
- String remoteAlias = new String(bbAlias.array(), 0, bbAlias.limit());
- cipher = CipherHelper.createAsymmetricReaderCipher(connection.getConnectionManager().ioService, remoteAlias);
- }
- }
- while (inBuffer.remaining() >= 128) {
- if (cipherBuffer.position() > 0) throw new RuntimeException();
- int oldLimit = inBuffer.limit();
- inBuffer.limit(inBuffer.position() + 128);
- int cipherReadSize = cipher.doFinal(inBuffer, cipherBuffer);
- inBuffer.limit(oldLimit);
- cipherBuffer.flip();
- while (cipherBuffer.hasRemaining()) {
- if (packet == null) {
- packet = obtainReadable();
- }
- boolean complete = packet.read(cipherBuffer);
- if (complete) {
- enqueueFullPacket(packet);
- packet = null;
- }
- }
- cipherBuffer.clear();
- }
- }
- }
- class SymmetricCipherPacketReader implements PacketReader {
- int size = -1;
- final Cipher cipher;
- ByteBuffer cipherBuffer = ByteBuffer.allocate(2 * RECEIVE_SOCKET_BUFFER_SIZE);
- SymmetricCipherPacketReader() {
- cipher = init();
- }
- Cipher init() {
- Cipher c = null;
- try {
- c = CipherHelper.createSymmetricReaderCipher(connection.getConnectionManager().ioService);
- } catch (Exception e) {
- logger.log(Level.SEVERE, "Symmetric Cipher for ReadHandler cannot be initialized.", e);
- }
- return c;
- }
- public void readPacket(ByteBuffer inBuffer) throws Exception {
- while (inBuffer.hasRemaining()) {
- try {
- if (size == -1) {
- if (inBuffer.remaining() < 4) return;
- size = inBuffer.getInt();
- }
- int remaining = inBuffer.remaining();
- if (remaining < size) {
- cipher.update(inBuffer, cipherBuffer);
- size -= remaining;
- } else if (remaining == size) {
- cipher.doFinal(inBuffer, cipherBuffer);
- size = -1;
- } else {
- int oldLimit = inBuffer.limit();
- int newLimit = inBuffer.position() + size;
- inBuffer.limit(newLimit);
- cipher.doFinal(inBuffer, cipherBuffer);
- inBuffer.limit(oldLimit);
- size = -1;
- }
- } catch (ShortBufferException e) {
- logger.log(Level.WARNING, e.getMessage(), e);
- }
- cipherBuffer.flip();
- while (cipherBuffer.hasRemaining()) {
- if (packet == null) {
- packet = obtainReadable();
- }
- boolean complete = packet.read(cipherBuffer);
- if (complete) {
- enqueueFullPacket(packet);
- packet = null;
- }
- }
- cipherBuffer.clear();
- }
- }
- }
- public Packet obtainReadable() {
- return connection.obtainPacket();
- }
- }