KickJava   Java API By Example, From Geeks To Geeks.

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


1 // $Id: IoSSLHandler.java 1316 2007-06-10 08:51:18Z 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 import java.io.IOException JavaDoc;
25 import java.nio.ByteBuffer JavaDoc;
26 import java.util.LinkedList JavaDoc;
27 import java.util.logging.Level JavaDoc;
28 import java.util.logging.Logger JavaDoc;
29
30 import javax.net.ssl.SSLContext;
31
32 import org.xsocket.ByteBufferQueue;
33 import org.xsocket.ClosedConnectionException;
34 import org.xsocket.stream.io.spi.IIoHandlerCallback;
35
36
37 /**
38  * SSL io handler
39  *
40  * @author grro@xsocket.org
41  */

42 final class IoSSLHandler extends ChainableIoHandler implements SSLProcessor.EventHandler {
43     
44     private static final Logger JavaDoc LOG = Logger.getLogger(IoSSLHandler.class.getName());
45
46     // read & write queue
47
private final ByteBufferQueue outAppDataQueue = new ByteBufferQueue();
48     private final ByteBufferQueue inAppDataQueue = new ByteBufferQueue();
49
50     
51     private final IOEventHandler ioEventHandler = new IOEventHandler();
52     
53     
54     // ssl stuff
55
private SSLProcessor sslProcessor = null;
56     private boolean isClientMode = false;
57     private boolean isSSLConnected = false;
58     
59     
60
61         
62     /**
63      * constructor
64      *
65      * @param successor the successor
66      * @param sslContext the ssl context to use
67      * @param isClientMode true, if is in client mode
68      * @param memoryManager the memory manager to use
69      * @throws IOException If some other I/O error occurs
70      */

71     IoSSLHandler(ChainableIoHandler successor, SSLContext sslContext,boolean isClientMode, IMemoryManager memoryManager) throws IOException JavaDoc {
72         super(successor);
73
74         this.isClientMode = isClientMode;
75         sslProcessor = new SSLProcessor(sslContext, isClientMode, memoryManager, this);
76     }
77
78     
79     public void init(IIoHandlerCallback callbackHandler) throws IOException JavaDoc {
80         setPreviousCallback(callbackHandler);
81         getSuccessor().init(ioEventHandler);
82         
83         startSSL();
84     }
85     
86     
87     /**
88      * {@inheritDoc}
89      */

90     public void setPreviousCallback(IIoHandlerCallback callbackHandler) {
91         super.setPreviousCallback(callbackHandler);
92         getSuccessor().setPreviousCallback(ioEventHandler);
93     }
94
95     
96
97     /**
98      * {@inheritDoc}
99      */

100     @Override JavaDoc
101     public int getPendingWriteDataSize() {
102         return outAppDataQueue.getSize() + super.getPendingWriteDataSize();
103     }
104
105
106     int getPendingReceiveDataSize() {
107         return inAppDataQueue.getSize() + super.getPendingReceiveDataSize();
108     }
109
110     
111     
112     /**
113      * start the ssl mode
114      *
115      * @throws IOException If some other I/O error occurs
116      */

117     void startSSL() throws IOException JavaDoc {
118         if (!isSSLConnected) {
119             sslProcessor.start();
120         }
121         
122         readIncomingEncryptedData();
123     }
124     
125
126
127     
128     /**
129      * {@inheritDoc}
130      */

131     public LinkedList JavaDoc<ByteBuffer JavaDoc> drainIncoming() {
132         return inAppDataQueue.drain();
133     }
134     
135     
136     /**
137      * {@inheritDoc}
138      */

139     public final void close(boolean immediate) throws IOException JavaDoc {
140         
141         if (!immediate) {
142             flushOutgoing();
143         }
144         
145         getSuccessor().close(immediate);
146     }
147     
148
149     /**
150      * {@inheritDoc}
151      */

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

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

171     public void flushOutgoing() throws IOException JavaDoc {
172         synchronized (sslProcessor) {
173             if (!sslProcessor.isHandshaking()) {
174                 if (!outAppDataQueue.isEmpty()) {
175                     sslProcessor.processOutAppData(outAppDataQueue.drain());
176                 }
177             } else {
178                 sslProcessor.processOutAppData();
179             }
180         }
181     }
182         
183     
184     
185
186     protected final void readIncomingEncryptedData() throws ClosedConnectionException, IOException JavaDoc {
187         readIncomingEncryptedData(getSuccessor().drainIncoming());
188     }
189     
190
191     
192     private synchronized void readIncomingEncryptedData(LinkedList JavaDoc<ByteBuffer JavaDoc> inNetDataList) throws ClosedConnectionException, IOException JavaDoc {
193         if (inNetDataList != null) {
194             if (LOG.isLoggable(Level.FINE)) {
195                 int size = 0;
196                 for (ByteBuffer JavaDoc buffer : inNetDataList) {
197                     size += buffer.remaining();
198                 }
199                 
200                 LOG.fine("received " + size + " bytes encrypted data");
201             }
202             
203             sslProcessor.processInNetData(inNetDataList);
204         }
205     }
206     
207     
208     public void onHandshakeFinished() throws IOException JavaDoc {
209         if (!isSSLConnected) {
210             if (LOG.isLoggable(Level.FINE)) {
211                 if (isClientMode) {
212                     LOG.fine("[" + getId() + "] handshake has been finished (clientMode)");
213                 } else {
214                     LOG.fine("[" + getId() + "] handshake has been finished (serverMode)");
215                 }
216             }
217
218             isSSLConnected = true;
219             getPreviousCallback().onConnect();
220         }
221             
222         flushOutgoing();
223         readIncomingEncryptedData();
224     }
225
226     
227     public void onSSLProcessorClosed() throws IOException JavaDoc {
228         close(true);
229     }
230
231
232     public void onInAppDataReceived(LinkedList JavaDoc<ByteBuffer JavaDoc> appDataList) {
233         inAppDataQueue.append(appDataList);
234         
235         if (!inAppDataQueue.isEmpty()) {
236             getPreviousCallback().onDataRead();
237         }
238     }
239     
240     
241     
242     public void onOutNetDataToWrite(ByteBuffer JavaDoc netData) throws IOException JavaDoc {
243         if (netData.hasRemaining()) {
244             getSuccessor().writeOutgoing(netData);
245         }
246     }
247
248     
249     
250     private final class IOEventHandler implements IIoHandlerCallback {
251                     
252         public void onDataRead() {
253             try {
254                 readIncomingEncryptedData();
255             } catch (Exception JavaDoc e) {
256                 if (LOG.isLoggable(Level.FINE)) {
257                     LOG.fine("[" + getId() + "] error occured while receiving data. Reason: " + e.toString());
258                 }
259             }
260         }
261         
262
263         public void onConnect() {
264             
265         }
266         
267         public void onWriteException(IOException JavaDoc ioException) {
268             getPreviousCallback().onWriteException(ioException);
269         }
270
271         public void onWritten() {
272             getPreviousCallback().onWritten();
273         }
274         
275         public void onDisconnect() {
276             sslProcessor.destroy();
277             getPreviousCallback().onDisconnect();
278         }
279
280         public void onConnectionAbnormalTerminated() {
281             getPreviousCallback().onConnectionAbnormalTerminated();
282         }
283         
284
285         public void onConnectionTimeout() {
286             getPreviousCallback().onConnectionTimeout();
287         }
288         
289         public void onIdleTimeout() {
290             getPreviousCallback().onIdleTimeout();
291         }
292     }
293 }
294
Popular Tags