001: /*
002: * This file is part of DrFTPD, Distributed FTP Daemon.
003: *
004: * DrFTPD is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * DrFTPD is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with DrFTPD; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018: package org.drftpd;
019:
020: import java.io.IOException;
021: import java.net.ServerSocket;
022: import java.net.Socket;
023: import java.net.SocketException;
024:
025: import javax.net.ServerSocketFactory;
026: import javax.net.ssl.SSLContext;
027: import javax.net.ssl.SSLSocket;
028:
029: import net.sf.drftpd.util.PortRange;
030:
031: import org.apache.log4j.Logger;
032: import org.drftpd.slave.Connection;
033:
034: /**
035: * @author mog
036: * @version $Id: PassiveConnection.java 1593 2007-01-31 22:56:52Z zubov $
037: */
038: public class PassiveConnection extends Connection {
039: private static final Logger logger = Logger
040: .getLogger(PassiveConnection.class);
041: private ServerSocket _serverSocket;
042: // Default is to initiate the handshake
043: private boolean _useSSLClientMode = false;
044:
045: /**
046: * @param ctx
047: * @param portRange
048: * @throws IOException
049: * Creates a PassiveConnection
050: * - If ctx==null, the Connection will not use SSL
051: */
052: public PassiveConnection(SSLContext ctx, PortRange portRange,
053: boolean useSSLClientMode) throws IOException {
054: _useSSLClientMode = useSSLClientMode;
055: if (ctx != null) {
056: _serverSocket = portRange.getPort(ctx
057: .getServerSocketFactory());
058: } else {
059: _serverSocket = portRange.getPort(ServerSocketFactory
060: .getDefault());
061: }
062: _serverSocket.setSoTimeout(TIMEOUT);
063: }
064:
065: public Socket connect(int bufferSize) throws IOException {
066: Socket sock = null;
067: try {
068: sock = _serverSocket.accept();
069: } finally {
070: if (_serverSocket != null) {
071: _serverSocket.close();
072: }
073: _serverSocket = null;
074: }
075:
076: setSockOpts(sock);
077:
078: if (sock instanceof SSLSocket) {
079: SSLSocket sslsock = (SSLSocket) sock;
080: sslsock.setUseClientMode(_useSSLClientMode);
081: sslsock.startHandshake();
082: }
083: if (sock == null) {
084: // can happen if abort() is called while serverSocket.accept() is waiting
085: throw new SocketException(
086: "abort() was called while waiting for a connection");
087: }
088:
089: return sock;
090: }
091:
092: public int getLocalPort() {
093: if (_serverSocket == null) {
094: throw new NullPointerException("_serverSocket == null");
095: }
096:
097: return _serverSocket.getLocalPort();
098: }
099:
100: public void abort() {
101: try {
102: if (_serverSocket != null) {
103: _serverSocket.close();
104: }
105: } catch (IOException e) {
106: logger.error("failed to close() server socket", e);
107: }
108: _serverSocket = null;
109: }
110:
111: protected void finalize() throws Throwable {
112: if (_serverSocket != null) {
113: logger
114: .debug("Closing extraneous ServerSocket - "
115: + _serverSocket.getLocalPort()
116: + ", accept() was never called on the ServerSocket");
117: _serverSocket.close();
118: _serverSocket = null;
119: }
120: }
121:
122: }
|