/** * Wait for the client to be connected (Passive) or Wait for the server to be connected to the * client (Active) * * @return True if the connection is OK * @throws Reply425Exception */ public boolean openDataConnection() throws Reply425Exception { // Prepare this Data channel to be closed ;-) // In fact, prepare the future close op which should occur since it is // now opened closedDataChannel = new WaarpFuture(true); FtpDataAsyncConn dataAsyncConn = session.getDataConn(); if (!dataAsyncConn.isStreamFile()) { // FIXME isConnected or isDNHReady ? if (dataAsyncConn.isConnected()) { // Already connected // logger.debug("Connection already open"); session.setReplyCode( ReplyCode.REPLY_125_DATA_CONNECTION_ALREADY_OPEN, dataAsyncConn.getType().name() + " mode data connection already open"); return true; } } else { // Stream, Data Connection should not be opened if (dataAsyncConn.isConnected()) { logger.error("Connection already open but should not since in Stream mode"); setTransferAbortedFromInternal(false); throw new Reply425Exception("Connection already open but should not since in Stream mode"); } } // Need to open connection session.setReplyCode( ReplyCode.REPLY_150_FILE_STATUS_OKAY, "Opening " + dataAsyncConn.getType().name() + " mode data connection"); if (dataAsyncConn.isPassiveMode()) { if (!dataAsyncConn.isBind()) { // No passive connection prepared throw new Reply425Exception("No passive data connection prepared"); } // Wait for the connection to be done by the client // logger.debug("Passive mode standby"); try { dataChannel = waitForOpenedDataChannel(); dataAsyncConn.setNewOpenedDataChannel(dataChannel); } catch (InterruptedException e) { logger.warn("Connection abort in passive mode", e); // Cannot open connection throw new Reply425Exception("Cannot open passive data connection"); } // logger.debug("Passive mode connected"); } else { // Wait for the server to be connected to the client InetAddress inetAddress = dataAsyncConn.getLocalAddress().getAddress(); InetSocketAddress inetSocketAddress = dataAsyncConn.getRemoteAddress(); if (session .getConfiguration() .getFtpInternalConfiguration() .hasFtpSession(inetAddress, inetSocketAddress)) { throw new Reply425Exception( "Cannot open active data connection since remote address is already in use: " + inetSocketAddress); } // logger.debug("Active mode standby"); ClientBootstrap clientBootstrap = session .getConfiguration() .getFtpInternalConfiguration() .getActiveBootstrap(session.isDataSsl()); session.getConfiguration().setNewFtpSession(inetAddress, inetSocketAddress, session); // Set the session for the future dataChannel String mylog = session.toString(); logger.debug( "DataConn for: " + session.getCurrentCommand().getCommand() + " to " + inetSocketAddress.toString()); ChannelFuture future = clientBootstrap.connect(inetSocketAddress, dataAsyncConn.getLocalAddress()); try { future.await(); } catch (InterruptedException e1) { } if (!future.isSuccess()) { logger.warn( "Connection abort in active mode from future while session: " + session.toString() + "\nTrying connect to: " + inetSocketAddress.toString() + "\nWas: " + mylog, future.getCause()); // Cannot open connection session.getConfiguration().delFtpSession(inetAddress, inetSocketAddress); throw new Reply425Exception("Cannot open active data connection"); } try { dataChannel = waitForOpenedDataChannel(); dataAsyncConn.setNewOpenedDataChannel(dataChannel); } catch (InterruptedException e) { logger.warn("Connection abort in active mode", e); // Cannot open connection session.getConfiguration().delFtpSession(inetAddress, inetSocketAddress); throw new Reply425Exception("Cannot open active data connection"); } // logger.debug("Active mode connected"); } if (dataChannel == null) { // Cannot have a new Data connection since shutdown if (!dataAsyncConn.isPassiveMode()) { session .getConfiguration() .getFtpInternalConfiguration() .delFtpSession( dataAsyncConn.getLocalAddress().getAddress(), dataAsyncConn.getRemoteAddress()); } throw new Reply425Exception("Cannot open data connection, shuting down"); } return true; }