KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > mina > filter > support > SSLByteBufferPool


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  *
19  */

20 package org.apache.mina.filter.support;
21
22 import java.nio.ByteBuffer JavaDoc;
23
24 import javax.net.ssl.SSLEngine;
25
26 import org.apache.mina.util.Stack;
27
28 /**
29  * Simple ByteBuffer pool used by SSLHandler.
30  * ByteBuffers are by default allocated as direct byte buffers. To use non-direct
31  * ByteBuffers, set system property mina.sslfilter.directbuffer to false.
32  *
33  * @author The Apache Directory Project (mina-dev@directory.apache.org)
34  * @version $Rev: 555855 $, $Date: 2007-07-13 12:19:00 +0900 (금, 13 7월 2007) $
35  */

36 class SSLByteBufferPool {
37     private static final int PACKET_BUFFER_INDEX = 0;
38
39     private static final int APPLICATION_BUFFER_INDEX = 1;
40
41     private static boolean initiated = false;
42
43     private static final String JavaDoc DIRECT_MEMORY_PROP = "mina.sslfilter.directbuffer";
44
45     private static boolean useDirectAllocatedBuffers = true;
46
47     private static int packetBufferSize;
48
49     private static int appBufferSize;
50
51     private static int[] bufferStackSizes;
52
53     private static final Stack[] bufferStacks = new Stack[] { new Stack(),
54             new Stack(), };
55
56     /**
57      * Initiate buffer pool and buffer sizes from SSLEngine session.
58      *
59      * @param sslEngine SSLEngine
60      */

61     static synchronized void initiate(SSLEngine sslEngine) {
62         if (!initiated) {
63             // Use direct allocated memory or not?
64
String JavaDoc prop = System.getProperty(DIRECT_MEMORY_PROP);
65             if (prop != null) {
66                 useDirectAllocatedBuffers = Boolean
67                         .getBoolean(DIRECT_MEMORY_PROP);
68             }
69
70             // init buffer sizes from SSLEngine
71
packetBufferSize = sslEngine.getSession().getPacketBufferSize();
72
73             // application buffer size has been doubled because SSLEngine
74
// returns BUFFER_OVERFLOW even if there is enough room for the buffer.
75
// So for now we use a size double the packet size as a workaround.
76
appBufferSize = packetBufferSize * 2;
77             initiateBufferStacks();
78             initiated = true;
79         }
80     }
81
82     /**
83      * Get bytebuffer with size the size of the largest SSL/TLS packet that may occur
84      * (as defined by SSLSession).
85      */

86     static ByteBuffer JavaDoc getPacketBuffer() {
87         if (!initiated) {
88             throw new IllegalStateException JavaDoc("Not initialized");
89         }
90         return allocate(PACKET_BUFFER_INDEX);
91     }
92
93     /**
94      * Get ByteBuffer with the size of the largest application buffer that may occur
95      * (as defined by SSLSession).
96      */

97     static ByteBuffer JavaDoc getApplicationBuffer() {
98         if (!initiated) {
99             throw new IllegalStateException JavaDoc("Not initialized");
100         }
101         return allocate(APPLICATION_BUFFER_INDEX);
102     }
103
104     /**
105      * Allocate or get the buffer which is capable of the specified size.
106      */

107     private static ByteBuffer JavaDoc allocate(int idx) {
108         Stack stack = bufferStacks[idx];
109
110         ByteBuffer JavaDoc buf;
111         synchronized (stack) {
112             buf = (ByteBuffer JavaDoc) stack.pop();
113             if (buf == null) {
114                 buf = createBuffer(bufferStackSizes[idx]);
115             }
116         }
117
118         buf.clear();
119         return buf;
120     }
121
122     /**
123      * Releases the specified buffer to buffer pool.
124      */

125     public static void release(ByteBuffer JavaDoc buf) {
126         // Sweep buffer for security.
127
org.apache.mina.common.ByteBuffer.wrap(buf).sweep().release();
128
129         int stackIndex = getBufferStackIndex(buf.capacity());
130         if (stackIndex >= PACKET_BUFFER_INDEX) {
131             Stack stack = bufferStacks[getBufferStackIndex(buf.capacity())];
132             synchronized (stack) {
133                 stack.push(buf);
134             }
135         }
136     }
137
138     /**
139      * Expand size of provided buffer
140      * @param buf buffer to be expande
141      * @param newCapacity new capacity
142      */

143     public static ByteBuffer JavaDoc expandBuffer(ByteBuffer JavaDoc buf, int newCapacity) {
144         ByteBuffer JavaDoc newBuf = createBuffer(newCapacity);
145         buf.flip();
146         newBuf.put(buf);
147         release(buf);
148         return newBuf;
149     }
150
151     private static void initiateBufferStacks() {
152         bufferStackSizes = new int[2];
153         bufferStackSizes[PACKET_BUFFER_INDEX] = packetBufferSize;
154         bufferStackSizes[APPLICATION_BUFFER_INDEX] = appBufferSize;
155     }
156
157     private static int getBufferStackIndex(int size) {
158         if (size == packetBufferSize)
159             return PACKET_BUFFER_INDEX;
160         if (size == appBufferSize)
161             return APPLICATION_BUFFER_INDEX;
162         return -1; // not reused
163
}
164
165     private static ByteBuffer JavaDoc createBuffer(int capacity) {
166         if (useDirectAllocatedBuffers) {
167             try {
168                 return ByteBuffer.allocateDirect(capacity);
169             } catch (OutOfMemoryError JavaDoc e) {
170                 useDirectAllocatedBuffers = false;
171                 System.err
172                         .println("OutOfMemoryError: No more direct buffers available; trying heap buffer instead");
173             }
174         }
175         return ByteBuffer.allocate(capacity);
176     }
177
178 }
179
Popular Tags