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) {


Reply via email to