📄 tlsmanager.java
字号:
/************************************************************************
*
* $Id: TlsManager.java,v 1.2 2002/03/04 21:42:58 echtcherbina Exp $
*
* Copyright (c) 2001 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Sun Microsystems, Inc. for Project JXTA."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA"
* must not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact Project JXTA at http://www.jxta.org.
*
* 5. Products derived from this software may not be called "JXTA",
* nor may "JXTA" appear in their name, without prior written
* permission of Sun.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL SUN MICROSYSTEMS OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of Project JXTA. For more
* information on Project JXTA, please see
* <http://www.jxta.org/>.
*
* This license is based on the BSD license adopted by the Apache Foundation.
*********************************************************************************/
package net.jxta.impl.endpoint.tls;
import COM.claymoresystems.ptls.SSLDebug;
import net.jxta.exception.*;
import java.io.*;
import java.util.Hashtable;
import net.jxta.endpoint.*;
import org.apache.log4j.Category; import org.apache.log4j.Priority;
import java.lang.Thread;
/**
* This class implements the TLS connection between two peers.
*/
public class TlsManager {
private static final Category LOG = Category.getInstance(TlsManager.class.getName());
TlsTransport transport = null;
// Hash table for known connections
Hashtable cons = new Hashtable();
// Hash both connection object and create time
// If connections are idle for CONN_TIMEOUT
// then we restart the handshake.
// o This help handle the case where the remote end of a connection
// has exited, restarted, and we are trying to communicate with them again.
// They will be expecting a new handshake, seq#1, and will receive
// seq#n, n > 1.
private class TlsConnInfo {
TlsConn connection;
boolean handshakeDone;
long lastAccessed;
public TlsConnInfo(TlsConn conn, long lastAccessed) {
this.connection = conn;
this.handshakeDone = false;
this.lastAccessed = lastAccessed;
}
}
private final static int CONN_TIMEOUT = (60*60*1000); // 30 minutes in milliseconds
private static final int STARTOFHS = 1;
private static final int RETRSTARTOFHS = 2;
private static final int NOTSTARTOFHS = 0;
synchronized private boolean handshakeInprogress(TlsConnInfo cinfo)
{
if (cinfo.handshakeDone) return false;
else // handshake ongoing
return true;
}
synchronized private TlsConnInfo setTlsConnTable(String paddr, TlsConn conn)
{
TlsConnInfo cinfo = null;
if (cons.containsKey(paddr)) {
// Handshake in progress (already passed by here),
// or handshake is done.
cinfo = (TlsConnInfo)cons.get(paddr);
// See if it is done.
if (cinfo.handshakeDone) {
return cinfo;
} else {
// Nope, still waiting ...
if (LOG.isEnabledFor(Priority.INFO))
LOG.info("Handshake in progress for " + paddr);
return null;
}
}
// first thread to open
cinfo = new TlsConnInfo(conn, System.currentTimeMillis());
cons.put(paddr, cinfo);
return cinfo;
}
// This constructor is called by TlsTransport
public TlsManager (TlsTransport tp) {
this.transport = tp;
}
// getTlsConn is invoked by TlsTransport each time a service
// tries to open a TLS connection with a peer. Since TLS connection
// establishement is expensive, we cache already
// opened TLS connection for future use. Already opened connected then
// are associated to a life time (when not used) so we do not
// create a memory leak.
//
// @param dstAddr is the EndpointAddress of the remote peer
// @return TlsConn a TLS connection. null is return if the connection could not
// be opened.
//
// This is a client TLS Connection
public TlsConn getTlsConn (EndpointAddress dstAddr)
throws HandshakeInProgressException, IOException
{
TlsConn conn = null;
// see if we have an existing conn, and if so, then reuse it
// if it has not timed out.
String paddr = dstAddr.getProtocolAddress();
// System.out.println("\ngetTlsConn, dest = " + paddr);
TlsConnInfo cinfo = (TlsConnInfo)cons.get(paddr);
if (cinfo != null) { // info in our table for this destaddr
// See if another thread is doing a handshake
if (handshakeInprogress(cinfo)) {
if (LOG.isEnabledFor(Priority.INFO))
LOG.info("Handshake in progress for " + paddr);
throw new HandshakeInProgressException("Handshake in progress");
}
conn = cinfo.connection; // get the connection entry
// See if input is dead
if (conn.getInputDead() == true) {
if (LOG.isEnabledFor(Priority.INFO))
LOG.info("Input died for " + paddr);
throw new IOException("Input died");
}
// check for time out
long ctime = System.currentTimeMillis();
long maxIdleTime = cinfo.lastAccessed + CONN_TIMEOUT;
if (ctime > maxIdleTime) {
// Time expired. Restart
if (LOG.isEnabledFor(Priority.INFO)) {
long idletime = (ctime - cinfo.lastAccessed)/(1000*60); // in minutes
LOG.info("getTlsConn, idle time expired:\n Dest = " + paddr +
" minutes idle = " + idletime + "\n");
}
// reset cinfo entry
cinfo = null;
cons.remove(paddr);
} else { // Still active
cinfo.lastAccessed = ctime; // update idle timer
cons.put(paddr, cinfo); // replace hashtable entry
if (LOG.isEnabledFor(Priority.INFO)) {
LOG.info("getTlsConn: Continuing cached Tls session");
}
return conn;
}
}
// nope, this is not a continuation, or idle time expired
if (LOG.isEnabledFor(Priority.INFO)) {
LOG.info("getTlsConn, new TlsConn:\n" + " Addr = " + paddr);
}
try {
conn = new TlsConn(this, this.transport, dstAddr, true, null); // true means client
if (LOG.isEnabledFor(Priority.DEBUG))
LOG.info("new tls connection = " + paddr);
} catch (Exception e) {
if (LOG.isEnabledFor(Priority.INFO)) LOG.info("TlsManager:", e);
return null;
}
// Another critical region. Two threads can arrive here both
// wanting to open a TLS connection
cinfo = setTlsConnTable(paddr, conn);
if (cinfo == null) {
// Another in progress, and handshake not done.
// Toss connection.
conn = null;
throw new HandshakeInProgressException("Handshake in progress");
} else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -