KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xsocket > stream > io > impl > IoActivateableSSLHandler


1 // $Id: IoSSLHandler.java 1219 2007-05-05 07:36:36Z grro $
2
/*
3  * Copyright (c) xsocket.org, 2006 - 2007. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Please refer to the LGPL license at: http://www.gnu.org/copyleft/lesser.txt
20  * The latest copy of this software may be found on http://www.xsocket.org/
21  */

22 package org.xsocket.stream.io.impl;
23
24
25 import java.io.IOException JavaDoc;
26 import java.nio.ByteBuffer JavaDoc;
27 import java.util.LinkedList JavaDoc;
28 import java.util.logging.Level JavaDoc;
29 import java.util.logging.Logger JavaDoc;
30
31 import javax.net.ssl.SSLContext;
32
33 import org.xsocket.ByteBufferQueue;
34 import org.xsocket.ClosedConnectionException;
35 import org.xsocket.stream.io.spi.IIoHandlerCallback;
36
37
38
39
40 /**
41  * activateable SSL io handler
42  *
43  * @author grro@xsocket.org
44  */

45 final class IoActivateableSSLHandler extends ChainableIoHandler implements SSLProcessor.EventHandler {
46     
47     
48     private static final Logger JavaDoc LOG = Logger.getLogger(IoSSLHandler.class.getName());
49     
50     private enum Mode { OFF, NON_RECEIVING, NON_RECEIVING_AND_WRITING, SSL };
51     
52     private Mode mode = Mode.OFF;
53
54     
55     // read & write queue
56
private final ByteBufferQueue inNetDataQueue = new ByteBufferQueue();
57     private final ByteBufferQueue outAppDataQueue = new ByteBufferQueue();
58     private final ByteBufferQueue inAppDataQueue = new ByteBufferQueue();
59     
60     // event handling
61
private final IOEventHandler ioEventHandler = new IOEventHandler();
62
63     // ssl stuff
64
private SSLProcessor sslProcessor = null;
65
66     
67     
68     
69     /**
70      * constructor
71      *
72      * @param successor the successor
73      * @param sslContext the ssl context to use
74      * @param isClientMode true, if is in client mode
75      * @param memoryManager the memory manager to use
76      * @throws IOException If some other I/O error occurs
77      */

78     IoActivateableSSLHandler(ChainableIoHandler successor, SSLContext sslContext,boolean isClientMode, IMemoryManager memoryManager) throws IOException JavaDoc {
79         super(successor);
80         
81         sslProcessor = new SSLProcessor(sslContext, isClientMode, memoryManager, this);
82     }
83
84     
85     public void init(IIoHandlerCallback callbackHandler) throws IOException JavaDoc {
86         setPreviousCallback(callbackHandler);
87         getSuccessor().init(ioEventHandler);
88     }
89     
90     
91     /**
92      * {@inheritDoc}
93      */

94     public void setPreviousCallback(IIoHandlerCallback callbackHandler) {
95         super.setPreviousCallback(callbackHandler);
96         getSuccessor().setPreviousCallback(ioEventHandler);
97     }
98     
99     
100     /**
101      * {@inheritDoc}
102      */

103     public final void close(boolean immediate) throws IOException JavaDoc {
104         if (!immediate) {
105             flushOutgoing();
106         }
107
108         getSuccessor().close(immediate);
109     }
110     
111     
112     public boolean isSSLActivated() {
113         return (mode == Mode.SSL);
114     }
115     
116
117     /**
118      * {@inheritDoc}
119      */

120     @Override JavaDoc
121     public int getPendingWriteDataSize() {
122         return outAppDataQueue.getSize() + super.getPendingWriteDataSize();
123     }
124
125     int getPendingReceiveDataSize() {
126         return inAppDataQueue.getSize() + super.getPendingReceiveDataSize();
127     }
128
129     
130     
131     /**
132      * {@inheritDoc}
133      */

134     public final LinkedList JavaDoc<ByteBuffer JavaDoc> drainIncoming() {
135         if (mode == Mode.OFF) {
136             return getSuccessor().drainIncoming();
137         } else {
138             return inAppDataQueue.drain();
139         }
140     }
141     
142     
143     
144
145     
146
147     /**
148      * {@inheritDoc}
149      */

150     public final void writeOutgoing(ByteBuffer JavaDoc buffer) throws ClosedConnectionException, IOException JavaDoc {
151         LinkedList JavaDoc<ByteBuffer JavaDoc> buffers = new LinkedList JavaDoc<ByteBuffer JavaDoc>();
152         buffers.add(buffer);
153         writeOutgoing(buffers);
154     }
155     
156     
157     
158     /**
159      * {@inheritDoc}
160      */

161     public final void writeOutgoing(LinkedList JavaDoc<ByteBuffer JavaDoc> buffers) throws ClosedConnectionException, IOException JavaDoc {
162         outAppDataQueue.append(buffers);
163         flushOutgoing();
164     }
165
166     /**
167      * {@inheritDoc}
168      */

169     public void flushOutgoing() throws IOException JavaDoc {
170         if (mode == Mode.SSL) {
171             synchronized (sslProcessor) {
172                 if (sslProcessor.isHandshaking()) {
173                     sslProcessor.processOutAppData();
174
175                 } else {
176                     if (!outAppDataQueue.isEmpty()) {
177                         sslProcessor.processOutAppData(outAppDataQueue.drain());
178                     }
179                 }
180             }
181
182     
183         } else if ((mode == Mode.OFF) || (mode == Mode.NON_RECEIVING)) {
184             LinkedList JavaDoc<ByteBuffer JavaDoc> data = outAppDataQueue.drain();
185             getSuccessor().writeOutgoing(data);
186         }
187     }
188
189     
190     public boolean preStartSecuredMode() {
191         if (mode == Mode.OFF) {
192             mode = Mode.NON_RECEIVING;
193             return true;
194             
195         } else {
196             LOG.warning("connection is already in ssl mode (mode=" + mode + "). Ignore (pre)startSecured Mode");
197             return false;
198         }
199     }
200     
201
202     /**
203      *
204      *
205      * Return already received data to ssl handler (this data
206      * will be interpreted as encrypted data). <br>
207      *
208      * @param readQueue the queue with already received data
209      * @throws IOException if an io exception occurs
210      */

211     public void startSecuredMode(LinkedList JavaDoc<ByteBuffer JavaDoc> data) throws IOException JavaDoc {
212         if (mode != Mode.NON_RECEIVING) {
213             LOG.warning("connection is not in non_receiving mode (mode=" + mode + ")");
214             return;
215         }
216
217         mode = Mode.NON_RECEIVING_AND_WRITING;
218
219         inNetDataQueue.addFirst(data);
220         
221         sslProcessor.start();
222         mode = Mode.SSL;
223         
224         flushOutgoing();
225         readIncomingEncryptedData();
226     }
227     
228     
229     
230     public void onHandshakeFinished() throws IOException JavaDoc {
231         flushOutgoing();
232         readIncomingEncryptedData();
233     }
234     
235
236     protected final void readIncomingEncryptedData() throws ClosedConnectionException, IOException JavaDoc {
237         inNetDataQueue.append(getSuccessor().drainIncoming());
238         readIncomingEncryptedData(inNetDataQueue.drain());
239     }
240     
241
242     
243     private synchronized void readIncomingEncryptedData(LinkedList JavaDoc<ByteBuffer JavaDoc> inNetDataList) throws ClosedConnectionException, IOException JavaDoc {
244         if (inNetDataList != null) {
245             if (LOG.isLoggable(Level.FINE)) {
246                 int size = 0;
247                 for (ByteBuffer JavaDoc buffer : inNetDataList) {
248                     size += buffer.remaining();
249                 }
250                 
251                 LOG.fine("received " + size + " bytes encrypted data");
252             }
253             
254             sslProcessor.processInNetData(inNetDataList);
255         }
256     }
257
258     
259     public void onSSLProcessorClosed() throws IOException JavaDoc {
260         close(true);
261     }
262     
263     public void onInAppDataReceived(LinkedList JavaDoc<ByteBuffer JavaDoc> appDataList) {
264         inAppDataQueue.append(appDataList);
265         
266         if (!inAppDataQueue.isEmpty()) {
267             getPreviousCallback().onDataRead();
268         }
269     }
270     
271     
272     public void onOutNetDataToWrite(ByteBuffer JavaDoc netData) throws IOException JavaDoc {
273         if (netData.hasRemaining()) {
274             getSuccessor().writeOutgoing(netData);
275         }
276     }
277
278     
279     
280     private final class IOEventHandler implements IIoHandlerCallback {
281                     
282         public void onDataRead() {
283             try {
284                 if (mode == Mode.OFF) {
285                     getPreviousCallback().onDataRead();
286                         
287                 } else if (mode == Mode.SSL) {
288                     readIncomingEncryptedData();
289     
290                 } else {
291                     assert (mode == Mode.NON_RECEIVING) || (mode == Mode.NON_RECEIVING_AND_WRITING);
292                     return;
293                 }
294             } catch (Exception JavaDoc e) {
295                 if (LOG.isLoggable(Level.FINE)) {
296                     LOG.fine("[" + getId() + "] error occured while receiving data. Reason: " + e.toString());
297                 }
298             }
299         }
300
301         public void onConnect() {
302             getPreviousCallback().onConnect();
303         }
304         
305         public void onWriteException(IOException JavaDoc ioException) {
306             getPreviousCallback().onWriteException(ioException);
307         }
308
309         public void onWritten() {
310             getPreviousCallback().onWritten();
311         }
312         
313         public void onDisconnect() {
314             //getSSLProcessor().destroy();
315
getPreviousCallback().onDisconnect();
316         }
317
318         public void onConnectionAbnormalTerminated() {
319             getPreviousCallback().onConnectionAbnormalTerminated();
320         }
321         
322
323         public void onConnectionTimeout() {
324             getPreviousCallback().onConnectionTimeout();
325         }
326         
327         public void onIdleTimeout() {
328             getPreviousCallback().onIdleTimeout();
329         }
330     }
331 }
332
Popular Tags