Author: ngn
Date: Sun Dec 14 13:53:19 2008
New Revision: 726546
URL: http://svn.apache.org/viewvc?rev=726546&view=rev
Log:
Fix for FTPSERVER-241 where the JVM leaks file handles when using the
SSLServerSocket (http://bugs.sun.com/view_bug.do?bug_id=6764972). While this
bugs seems to be fixed in 1.6u12, we should fix it for users of other JVMs.
Using the workaround described here
http://www.nabble.com/-security-dev-00402-:-Re:-NullPointerException-at%09sun.security.ssl.OutputRecord.writeBuffer-td20492154.html.
It's based on using a wrapper SSLSocket rather than creating an
SSLServerSocket. Using this, the number of used file handles seems to be
consistent and low when debugged using lsof -p <the PID> | grep sock | wc -l
Modified:
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/IODataConnectionFactory.java
Modified:
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/IODataConnectionFactory.java
URL:
http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/IODataConnectionFactory.java?rev=726546&r1=726545&r2=726546&view=diff
==============================================================================
---
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/IODataConnectionFactory.java
(original)
+++
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/IODataConnectionFactory.java
Sun Dec 14 13:53:19 2008
@@ -198,7 +198,7 @@
throw new DataConnectionException(
"Data connection SSL required but not
configured.");
}
- servSoc = createServerSocket(ssl, address, passivePort);
+ servSoc = createSecureServerSocket(address, passivePort);
port = servSoc.getLocalPort();
LOG
.debug(
@@ -232,35 +232,22 @@
}
}
- private ServerSocket createServerSocket(final SslConfiguration ssl,
+ private ServerSocket createSecureServerSocket(
final InetAddress address2, final int passivePort)
throws IOException, GeneralSecurityException {
- // get server socket factory
- SSLContext ctx = ssl.getSSLContext();
- SSLServerSocketFactory ssocketFactory = ctx.getServerSocketFactory();
-
- // create server socket
- SSLServerSocket sslServerSocket = null;
+ // this method does not actually create the SSL socket, due to a JVM
bug
+ // (https://issues.apache.org/jira/browse/FTPSERVER-241).
+ // Instead, it creates a regular
+ // ServerSocket that will be wrapped as a SSL socket in
createDataSocket()
+
+ ServerSocket internalServerSocket ;
if (address2 == null) {
- sslServerSocket = (SSLServerSocket) ssocketFactory
- .createServerSocket(passivePort, 100);
+ internalServerSocket = new ServerSocket(passivePort);
} else {
- sslServerSocket = (SSLServerSocket) ssocketFactory
- .createServerSocket(passivePort, 100, address2);
- }
-
- // initialize server socket
- if (ssl.getClientAuth() == ClientAuth.NEED) {
- sslServerSocket.setNeedClientAuth(true);
- } else if (ssl.getClientAuth() == ClientAuth.WANT) {
- sslServerSocket.setWantClientAuth(true);
- }
-
- if (ssl.getEnabledCipherSuites() != null) {
- sslServerSocket
- .setEnabledCipherSuites(ssl.getEnabledCipherSuites());
+ internalServerSocket = new ServerSocket(passivePort, 100,
address2);
}
- return sslServerSocket;
+
+ return internalServerSocket;
}
/*
@@ -329,7 +316,36 @@
}
} else {
LOG.debug("Opening passive data connection");
- dataSoc = servSoc.accept();
+
+ if(secure) {
+ // get server socket factory
+ SslConfiguration ssl = getSslConfiguration();
+
+ SSLContext ctx = ssl.getSSLContext();
+ SSLSocketFactory ssocketFactory = ctx.getSocketFactory();
+
+ Socket serverSocket = servSoc.accept();
+
+ SSLSocket sslSocket = (SSLSocket)
ssocketFactory.createSocket(serverSocket,
+ serverSocket.getInetAddress().getHostName(),
serverSocket.getPort(), false);
+ sslSocket.setUseClientMode(false);
+
+ // initialize server socket
+ if (ssl.getClientAuth() == ClientAuth.NEED) {
+ sslSocket.setNeedClientAuth(true);
+ } else if (ssl.getClientAuth() == ClientAuth.WANT) {
+ sslSocket.setWantClientAuth(true);
+ }
+
+ if (ssl.getEnabledCipherSuites() != null) {
+ sslSocket
+
.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
+ }
+
+ dataSoc = sslSocket;
+ } else {
+ dataSoc = servSoc.accept();
+ }
LOG.debug("Passive data connection opened");
}
} catch (Exception ex) {