/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

  1. /*
  2. * Copyright (c) 2008-2013, Hazelcast, Inc. All Rights Reserved.
  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. */
  16. package com.hazelcast.nio;
  17. import com.hazelcast.logging.ILogger;
  18. import javax.crypto.Cipher;
  19. import javax.crypto.ShortBufferException;
  20. import java.nio.ByteBuffer;
  21. import java.util.logging.Level;
  22. import static com.hazelcast.nio.IOUtil.copyToHeapBuffer;
  23. class SocketPacketReader implements SocketReader {
  24. Packet packet = null;
  25. final PacketReader packetReader;
  26. final Connection connection;
  27. final IOService ioService;
  28. final SocketChannelWrapper socketChannel;
  29. final ILogger logger;
  30. public SocketPacketReader(SocketChannelWrapper socketChannel, Connection connection) {
  31. this.connection = connection;
  32. this.ioService = connection.getConnectionManager().ioService;
  33. this.socketChannel = socketChannel;
  34. this.logger = ioService.getLogger(SocketPacketReader.class.getName());
  35. boolean symmetricEncryptionEnabled = CipherHelper.isSymmetricEncryptionEnabled(ioService);
  36. boolean asymmetricEncryptionEnabled = CipherHelper.isAsymmetricEncryptionEnabled(ioService);
  37. if (asymmetricEncryptionEnabled || symmetricEncryptionEnabled) {
  38. if (asymmetricEncryptionEnabled && symmetricEncryptionEnabled) {
  39. packetReader = new ComplexCipherPacketReader();
  40. logger.log(Level.INFO, "Reader started with ComplexEncryption");
  41. } else if (symmetricEncryptionEnabled) {
  42. packetReader = new SymmetricCipherPacketReader();
  43. logger.log(Level.INFO, "Reader started with SymmetricEncryption");
  44. } else {
  45. packetReader = new AsymmetricCipherPacketReader();
  46. logger.log(Level.INFO, "Reader started with AsymmetricEncryption");
  47. }
  48. } else {
  49. packetReader = new DefaultPacketReader();
  50. }
  51. }
  52. public void read(ByteBuffer inBuffer) throws Exception {
  53. packetReader.readPacket(inBuffer);
  54. }
  55. public void enqueueFullPacket(final Packet p) {
  56. p.flipBuffers();
  57. p.read();
  58. p.setFromConnection(connection);
  59. if (p.client) {
  60. connection.setType(Connection.Type.CLIENT);
  61. ioService.handleClientPacket(p);
  62. } else {
  63. connection.setType(Connection.Type.MEMBER);
  64. ioService.handleMemberPacket(p);
  65. }
  66. }
  67. interface PacketReader {
  68. void readPacket(ByteBuffer inBuffer) throws Exception;
  69. }
  70. class DefaultPacketReader implements PacketReader {
  71. public void readPacket(ByteBuffer inBuffer) {
  72. while (inBuffer.hasRemaining()) {
  73. if (packet == null) {
  74. packet = obtainReadable();
  75. }
  76. boolean complete = packet.read(inBuffer);
  77. if (complete) {
  78. enqueueFullPacket(packet);
  79. packet = null;
  80. }
  81. }
  82. }
  83. }
  84. class ComplexCipherPacketReader implements PacketReader {
  85. ComplexCipherPacketReader() {
  86. }
  87. public void readPacket(ByteBuffer inBuffer) throws Exception {
  88. }
  89. }
  90. class AsymmetricCipherPacketReader implements PacketReader {
  91. Cipher cipher = null;
  92. ByteBuffer cipherBuffer = ByteBuffer.allocate(128);
  93. ByteBuffer bbAlias = null;
  94. boolean aliasSizeSet = false;
  95. public void readPacket(ByteBuffer inBuffer) throws Exception {
  96. if (cipher == null) {
  97. if (!aliasSizeSet) {
  98. if (inBuffer.remaining() < 4) {
  99. return;
  100. } else {
  101. int aliasSize = inBuffer.getInt();
  102. bbAlias = ByteBuffer.allocate(aliasSize);
  103. }
  104. }
  105. copyToHeapBuffer(inBuffer, bbAlias);
  106. if (!bbAlias.hasRemaining()) {
  107. bbAlias.flip();
  108. String remoteAlias = new String(bbAlias.array(), 0, bbAlias.limit());
  109. cipher = CipherHelper.createAsymmetricReaderCipher(connection.getConnectionManager().ioService, remoteAlias);
  110. }
  111. }
  112. while (inBuffer.remaining() >= 128) {
  113. if (cipherBuffer.position() > 0) throw new RuntimeException();
  114. int oldLimit = inBuffer.limit();
  115. inBuffer.limit(inBuffer.position() + 128);
  116. int cipherReadSize = cipher.doFinal(inBuffer, cipherBuffer);
  117. inBuffer.limit(oldLimit);
  118. cipherBuffer.flip();
  119. while (cipherBuffer.hasRemaining()) {
  120. if (packet == null) {
  121. packet = obtainReadable();
  122. }
  123. boolean complete = packet.read(cipherBuffer);
  124. if (complete) {
  125. enqueueFullPacket(packet);
  126. packet = null;
  127. }
  128. }
  129. cipherBuffer.clear();
  130. }
  131. }
  132. }
  133. class SymmetricCipherPacketReader implements PacketReader {
  134. int size = -1;
  135. final Cipher cipher;
  136. ByteBuffer cipherBuffer = ByteBuffer.allocate(2 * RECEIVE_SOCKET_BUFFER_SIZE);
  137. SymmetricCipherPacketReader() {
  138. cipher = init();
  139. }
  140. Cipher init() {
  141. Cipher c = null;
  142. try {
  143. c = CipherHelper.createSymmetricReaderCipher(connection.getConnectionManager().ioService);
  144. } catch (Exception e) {
  145. logger.log(Level.SEVERE, "Symmetric Cipher for ReadHandler cannot be initialized.", e);
  146. }
  147. return c;
  148. }
  149. public void readPacket(ByteBuffer inBuffer) throws Exception {
  150. while (inBuffer.hasRemaining()) {
  151. try {
  152. if (size == -1) {
  153. if (inBuffer.remaining() < 4) return;
  154. size = inBuffer.getInt();
  155. }
  156. int remaining = inBuffer.remaining();
  157. if (remaining < size) {
  158. cipher.update(inBuffer, cipherBuffer);
  159. size -= remaining;
  160. } else if (remaining == size) {
  161. cipher.doFinal(inBuffer, cipherBuffer);
  162. size = -1;
  163. } else {
  164. int oldLimit = inBuffer.limit();
  165. int newLimit = inBuffer.position() + size;
  166. inBuffer.limit(newLimit);
  167. cipher.doFinal(inBuffer, cipherBuffer);
  168. inBuffer.limit(oldLimit);
  169. size = -1;
  170. }
  171. } catch (ShortBufferException e) {
  172. logger.log(Level.WARNING, e.getMessage(), e);
  173. }
  174. cipherBuffer.flip();
  175. while (cipherBuffer.hasRemaining()) {
  176. if (packet == null) {
  177. packet = obtainReadable();
  178. }
  179. boolean complete = packet.read(cipherBuffer);
  180. if (complete) {
  181. enqueueFullPacket(packet);
  182. packet = null;
  183. }
  184. }
  185. cipherBuffer.clear();
  186. }
  187. }
  188. }
  189. public Packet obtainReadable() {
  190. return connection.obtainPacket();
  191. }
  192. }