private synchronized Socket createDataSocket()

in core/src/main/java/org/apache/ftpserver/impl/IODataConnectionFactory.java [237:364]


    private synchronized Socket createDataSocket() throws Exception {
        // get socket depending on the selection
        dataSoc = null;
        DataConnectionConfiguration dataConfig = session.getListener().getDataConnectionConfiguration();
        try {
            if (!passive) {
                if (secure) {
                    LOG.debug("Opening secure active data connection");
                    SslConfiguration ssl = getSslConfiguration();
                    
                    if (ssl == null) {
                        throw new FtpException("Data connection SSL not configured");
                    }
        
                    // get socket factory
                    SSLSocketFactory socFactory = ssl.getSocketFactory();
        
                    // create socket
                    SSLSocket ssoc = (SSLSocket) socFactory.createSocket();
                    ssoc.setUseClientMode(false);
        
                    // initialize socket
                    if (ssl.getEnabledCipherSuites() != null) {
                        ssoc.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
                    }
        
                    if (ssl.getEnabledProtocols() != null) {
                        ssoc.setEnabledProtocols(ssl.getEnabledProtocols());
                    }
                    
                    dataSoc = ssoc;
                } else {
                    LOG.debug("Opening active data connection");
                    dataSoc = new Socket();
                }
        
                dataSoc.setReuseAddress(true);
        
                InetAddress localAddr = resolveAddress(dataConfig.getActiveLocalAddress());
        
                // if no local address has been configured, make sure we use the same as the client connects from
                if (localAddr == null) {
                    localAddr = ((InetSocketAddress) session.getLocalAddress()).getAddress();
                }
        
                SocketAddress localSocketAddress = new InetSocketAddress(localAddr, dataConfig.getActiveLocalPort());
        
                LOG.debug("Binding active data connection to {}", localSocketAddress);
                dataSoc.bind(localSocketAddress);
        
                dataSoc.connect(new InetSocketAddress(address, port));
            } else {
    
            if (secure) {
                LOG.debug("Opening secure passive data connection");
                // this is where we wrap the unsecured socket as a SSLSocket. This is
                // due to the JVM bug described in FTPSERVER-241.
    
                // get server socket factory
                SslConfiguration ssl = getSslConfiguration();
    
                // we've already checked this, but let's do it again
                if (ssl == null) {
                throw new FtpException("Data connection SSL not configured");
                }
    
                SSLSocketFactory ssocketFactory = ssl.getSocketFactory();
    
                Socket serverSocket = servSoc.accept();
    
                SSLSocket sslSocket = (SSLSocket) ssocketFactory.createSocket(serverSocket, serverSocket.getInetAddress().getHostAddress(), serverSocket.getPort(), true);
                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());
                }
    
                if (ssl.getEnabledProtocols() != null) {
                    sslSocket.setEnabledProtocols(ssl.getEnabledProtocols());
                }
    
                dataSoc = sslSocket;
            } else {
                LOG.debug("Opening passive data connection");
    
                dataSoc = servSoc.accept();
            }
    
            if (dataConfig.isPassiveIpCheck()) {
                // Let's make sure we got the connection from the same
                // client that we are expecting
                InetAddress remoteAddress = ((InetSocketAddress) session.getRemoteAddress()).getAddress();
                InetAddress dataSocketAddress = dataSoc.getInetAddress();
                if (!dataSocketAddress.equals(remoteAddress)) {
                LOG.warn("Passive IP Check failed. Closing data connection from " + dataSocketAddress + " as it does not match the expected address " + remoteAddress);
                closeDataConnection();
                return null;
                }
            }
    
            DataConnectionConfiguration dataCfg = session.getListener().getDataConnectionConfiguration();
    
            dataSoc.setSoTimeout(dataCfg.getIdleTime() * 1000);
            LOG.debug("Passive data connection opened");
            }
        } catch (Exception ex) {
            closeDataConnection();
            LOG.warn("FtpDataConnection.getDataSocket()", ex);
            throw ex;
        }
        dataSoc.setSoTimeout(dataConfig.getIdleTime() * 1000);
    
        // Make sure we initiate the SSL handshake, or we'll
        // get an error if we turn out not to send any data
        // e.g. during the listing of an empty directory
        if (dataSoc instanceof SSLSocket) {
            ((SSLSocket) dataSoc).startHandshake();
        }
    
        return dataSoc;
    }