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 net.sf.drftpd.util;
019:
020: import org.apache.log4j.Logger;
021:
022: import java.io.IOException;
023:
024: import java.net.InetSocketAddress;
025: import java.net.ServerSocket;
026:
027: import java.util.Random;
028:
029: import javax.net.ServerSocketFactory;
030:
031: /**
032: * @author mog
033: * @version $Id: PortRange.java 1593 2007-01-31 22:56:52Z zubov $
034: */
035: public class PortRange {
036: private static final Logger logger = Logger
037: .getLogger(PortRange.class);
038: private int _minPort;
039: private int _maxPort;
040: private int _bufferSize;
041: Random rand = new Random();
042:
043: /**
044: * Creates a default port range for port 49152 to 65535.
045: */
046: public PortRange(int bufferSize) {
047: _minPort = 0;
048: _maxPort = 0;
049: _bufferSize = bufferSize;
050: }
051:
052: public PortRange(int minPort, int maxPort, int bufferSize) {
053: if (0 >= minPort || minPort > maxPort || maxPort > 65535) {
054: throw new RuntimeException(
055: "0 < minPort <= maxPort <= 65535");
056: }
057:
058: _maxPort = maxPort;
059: _minPort = minPort;
060: _bufferSize = bufferSize;
061: }
062:
063: public ServerSocket getPort(ServerSocketFactory ssf) {
064: if (_minPort == 0) {
065: try {
066: ServerSocket _serverSocket = ssf.createServerSocket();
067: if (_bufferSize > 0) {
068: _serverSocket.setReceiveBufferSize(_bufferSize);
069: }
070: _serverSocket.bind(new InetSocketAddress(0), 1);
071: return _serverSocket;
072: } catch (IOException e) {
073: logger.error("Unable to bind anonymous port", e);
074: throw new RuntimeException(e);
075: }
076: }
077:
078: int pos = rand.nextInt(_maxPort - _minPort + 1) + _minPort;
079: int initPos = pos;
080: boolean retry = true;
081: while (true) {
082: try {
083: ServerSocket _serverSocket = ssf.createServerSocket();
084: if (_bufferSize > 0) {
085: _serverSocket.setReceiveBufferSize(_bufferSize);
086: }
087: _serverSocket.bind(new InetSocketAddress(pos), 1);
088: return _serverSocket;
089: } catch (IOException e) {
090: }
091: pos++;
092: if (pos > _maxPort) {
093: pos = _minPort;
094: }
095: if (pos == initPos) {
096: if (retry == false) {
097: throw new RuntimeException("PortRange exhausted");
098: }
099: System.runFinalization();
100: retry = false;
101: }
102: }
103: }
104: }
|