You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2004/09/18 06:16:58 UTC
svn commit: rev 46294 - in incubator/directory/seda/trunk/src: java/org/apache/seda/listener java/org/apache/seda/protocol test/org/apache/seda test/org/apache/seda/listener
Author: akarasulu
Date: Fri Sep 17 21:16:56 2004
New Revision: 46294
Added:
incubator/directory/seda/trunk/src/java/org/apache/seda/listener/AvailablePortFinder.java (contents, props changed)
incubator/directory/seda/trunk/src/test/org/apache/seda/listener/AvailablePortFinderTest.java (contents, props changed)
incubator/directory/seda/trunk/src/test/org/apache/seda/listener/TCPListenerManagerTest.java
- copied, changed from rev 46270, incubator/directory/seda/trunk/src/test/org/apache/seda/listener/DefaultListenerManagerTest.java
Removed:
incubator/directory/seda/trunk/src/test/org/apache/seda/listener/DefaultListenerManagerTest.java
Modified:
incubator/directory/seda/trunk/src/java/org/apache/seda/protocol/DefaultInetServicesDatabase.java
incubator/directory/seda/trunk/src/java/org/apache/seda/protocol/InetServicesDatabase.java
incubator/directory/seda/trunk/src/test/org/apache/seda/DefaultFrontendFactoryTest.java
Log:
Commit changes ...
Summary: added Trustin's patch for port scans
o added Trustin's port scanner patch for servers
o changed name of DefaultListenerManagerTest to TCPListenerManagerTest
o added code to allow DefaultInetServicesDatabase to add entries after
database creation for changes to non-standard service locations which
may be needed to test the code in test cases
o changes test cases to use Trustin's port scanner
o added more code to port scanner to make it just return next available free
port in addition to a set of ports - this makes it return faster
o changed test case in Trustin's patch to not scan the whole range and to
now test the new methods
o added ASF boiler plate for ASL 2.0 to Trustin's patches
Added: incubator/directory/seda/trunk/src/java/org/apache/seda/listener/AvailablePortFinder.java
==============================================================================
--- (empty file)
+++ incubator/directory/seda/trunk/src/java/org/apache/seda/listener/AvailablePortFinder.java Fri Sep 17 21:16:56 2004
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.seda.listener;
+
+
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.NoSuchElementException;
+import java.net.ServerSocket;
+import java.io.IOException;
+
+
+/**
+ * Finds currently available server ports.
+ *
+ * @author Trustin Lee
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ * @see <a href="http://www.iana.org/assignments/port-numbers">
+ */
+public class AvailablePortFinder {
+
+ /**
+ * The minimum number of server port number.
+ */
+ public static final int MIN_PORT_NUMBER = 0;
+
+ /**
+ * The maximum number of server port number.
+ */
+ public static final int MAX_PORT_NUMBER = 49151;
+
+
+ /**
+ * Creates a new instance.
+ */
+ public AvailablePortFinder()
+ {
+ }
+
+
+ /**
+ * Returns the {@link Set} of currently available port numbers
+ * ({@link Integer}). This method is identical to
+ * <code>getAvailablePorts(MIN_PORT_NUMBER, MAX_PORT_NUMBER)</code>.
+ *
+ * WARNING: this can take a very long time.
+ */
+ public Set getAvailablePorts()
+ {
+ return getAvailablePorts( MIN_PORT_NUMBER, MAX_PORT_NUMBER ) ;
+ }
+
+
+ /**
+ * Gets the next available port starting at the lowest port number.
+ *
+ * @throws NoSuchElementException if there are no ports available
+ */
+ public static int getNextAvailable()
+ {
+ return getNextAvailable( MIN_PORT_NUMBER );
+ }
+
+
+ /**
+ * Gets the next available port starting at a port.
+ *
+ * @param fromPort the port to scan for availability
+ * @throws NoSuchElementException if there are no ports available
+ */
+ public static int getNextAvailable( int fromPort )
+ {
+ if ( fromPort < MIN_PORT_NUMBER || fromPort > MAX_PORT_NUMBER )
+ {
+ throw new IllegalArgumentException( "Invalid start port: " +
+ fromPort );
+ }
+
+ for ( int i = fromPort; i <= MAX_PORT_NUMBER; i++ )
+ {
+ ServerSocket s = null;
+
+ try
+ {
+ s = new ServerSocket( i );
+ return i;
+ }
+ catch ( IOException e )
+ {
+ }
+ finally
+ {
+ if ( s != null )
+ {
+ try
+ {
+ s.close();
+ }
+ catch ( IOException e )
+ {
+ /* should not be thrown */
+ }
+ }
+ }
+ }
+
+ throw new NoSuchElementException( "Could not find an available port " +
+ "above " + fromPort );
+ }
+
+
+ /**
+ * Returns the {@link Set| of currently avaliable port numbers ({@link Integer})
+ * between the specified port range.
+ *
+ * @throws IllegalArgumentException if port range is not between
+ * {@link MIN_PORT_NUMBER} and {@link MAX_PORT_NUMBER} or
+ * <code>fromPort</code> if greater than <code>toPort</code>.
+ */
+ public Set getAvailablePorts( int fromPort, int toPort )
+ {
+ if ( fromPort < MIN_PORT_NUMBER ||
+ toPort > MAX_PORT_NUMBER ||
+ fromPort > toPort )
+ {
+ throw new IllegalArgumentException( "Invalid port range: " +
+ fromPort + " ~ " + toPort );
+ }
+
+ Set result = new TreeSet();
+
+ for ( int i = fromPort; i <= toPort; i++ )
+ {
+ ServerSocket s = null;
+
+ try
+ {
+ s = new ServerSocket( i );
+ result.add( new Integer( i ) );
+ }
+ catch ( IOException e )
+ {
+ }
+ finally
+ {
+ if ( s != null )
+ {
+ try
+ {
+ s.close();
+ }
+ catch ( IOException e )
+ {
+ /* should not be thrown */
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+}
Modified: incubator/directory/seda/trunk/src/java/org/apache/seda/protocol/DefaultInetServicesDatabase.java
==============================================================================
--- incubator/directory/seda/trunk/src/java/org/apache/seda/protocol/DefaultInetServicesDatabase.java (original)
+++ incubator/directory/seda/trunk/src/java/org/apache/seda/protocol/DefaultInetServicesDatabase.java Fri Sep 17 21:16:56 2004
@@ -35,6 +35,7 @@
/** maps a port number to the authoritative service protocol name */
private final Map protoByPort = new HashMap();
+
public DefaultInetServicesDatabase( InetServiceEntry[] entries )
{
for ( int ii = 0; ii < entries.length; ii++ )
@@ -60,6 +61,69 @@
// now map the port to the auth service name (protocol)
protoByPort.put( iport, entries[ii].getName() );
+ }
+ }
+
+
+ /**
+ * Adds an entry to this database removing any other entry with the same
+ * port and authoritative service protocol identifier.
+ *
+ * @param entry the entry to add
+ */
+ public void addEntry( InetServiceEntry entry )
+ {
+ Integer iport = new Integer( entry.getPort() );
+
+ if ( protoByPort.containsKey( iport ) )
+ {
+ protoByPort.remove( iport );
+ }
+ protoByPort.put( iport, entry.getName() );
+
+ ArrayList list = null;
+ if ( entriesByPort.containsKey( iport ) )
+ {
+ list = ( ArrayList ) entriesByPort.get( iport );
+ for ( int ii = 0; ii < list.size(); ii++ )
+ {
+ InetServiceEntry ise = ( InetServiceEntry ) list.get( ii );
+ if ( ise != null && ise.getProtocol() == entry.getProtocol() )
+ {
+ list.remove( ise );
+ }
+ }
+
+ list.add( entry );
+ }
+ else
+ {
+ list = new ArrayList( 2 );
+ list.add( entry );
+ entriesByPort.put( iport, list );
+ }
+
+
+ if ( entriesByName.containsKey( entry.getName() ) )
+ {
+ list = ( ArrayList ) entriesByName.get( entry.getName() );
+
+ for ( int ii = 0; ii < list.size(); ii++ )
+ {
+ InetServiceEntry ise = ( InetServiceEntry ) list.get( ii );
+ if ( ise != null && ise.getProtocol() == entry.getProtocol() )
+ {
+ list.remove( ise );
+ }
+ }
+
+ list.add( entry );
+ }
+ else
+ {
+ list = new ArrayList( 2 );
+ list.add( entry );
+ entriesByName.put( entry.getName(), list );
}
}
Modified: incubator/directory/seda/trunk/src/java/org/apache/seda/protocol/InetServicesDatabase.java
==============================================================================
--- incubator/directory/seda/trunk/src/java/org/apache/seda/protocol/InetServicesDatabase.java (original)
+++ incubator/directory/seda/trunk/src/java/org/apache/seda/protocol/InetServicesDatabase.java Fri Sep 17 21:16:56 2004
@@ -17,14 +17,12 @@
package org.apache.seda.protocol;
-import org.apache.seda.protocol.InetServiceEntry;
-
import java.util.Iterator;
/**
* Interface for the internet services database. The database is used by
- * jinetd to associate services with ports and transport protocols.
+ * seda to associate services with ports and transport protocols.
*
* @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
* @version $Rev$
@@ -51,7 +49,7 @@
Iterator getByPort( int port );
/**
- * Gets the protocol associated with a port.
+ * Gets the service/protocol associated with a port.
*
* @param port the port one which the service resides
*/
Modified: incubator/directory/seda/trunk/src/test/org/apache/seda/DefaultFrontendFactoryTest.java
==============================================================================
--- incubator/directory/seda/trunk/src/test/org/apache/seda/DefaultFrontendFactoryTest.java (original)
+++ incubator/directory/seda/trunk/src/test/org/apache/seda/DefaultFrontendFactoryTest.java Fri Sep 17 21:16:56 2004
@@ -21,7 +21,9 @@
import org.apache.seda.listener.ListenerConfig;
import org.apache.seda.listener.TCPListenerConfig;
import org.apache.seda.listener.SocketListenerAddress;
+import org.apache.seda.listener.AvailablePortFinder;
import org.apache.seda.protocol.InetServiceEntry;
+import org.apache.seda.protocol.DefaultInetServicesDatabase;
import org.apache.seda.examples.EchoProtocolProvider;
import org.apache.commons.net.EchoTCPClient;
@@ -89,9 +91,10 @@
*/
public void testBind() throws IOException
{
+ int port = AvailablePortFinder.getNextAvailable();
ListenerConfig config = null;
config = new TCPListenerConfig( new SocketListenerAddress(
- InetAddress.getLocalHost() ), new InetServiceEntry( "ldap", 10389 ) );
+ InetAddress.getLocalHost() ), new InetServiceEntry( "ldap", port ) );
fe.getListenerManager().bind( config );
fe.getListenerManager().unbind( config );
}
@@ -99,14 +102,18 @@
public void testEcho() throws IOException, InterruptedException
{
+ InetServiceEntry srvEntry = new InetServiceEntry( "echo",
+ AvailablePortFinder.getNextAvailable( 6666 ) );
+ ( ( DefaultInetServicesDatabase ) fe.getInetServicesDatabase() )
+ .addEntry( srvEntry );
ListenerConfig config = null;
config = new TCPListenerConfig( new SocketListenerAddress(
- InetAddress.getLocalHost() ), new InetServiceEntry( "echo", 7 ) );
+ InetAddress.getLocalHost() ), srvEntry );
fe.getListenerManager().bind( config );
fe.register( new EchoProtocolProvider() );
EchoTCPClient client = new EchoTCPClient();
- client.connect( InetAddress.getLocalHost(), 7 );
+ client.connect( InetAddress.getLocalHost(), srvEntry.getPort() );
byte[] toSend = "Hello world!".getBytes();
byte[] recieved = new byte[toSend.length];
client.getOutputStream().write( toSend );
Added: incubator/directory/seda/trunk/src/test/org/apache/seda/listener/AvailablePortFinderTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/seda/trunk/src/test/org/apache/seda/listener/AvailablePortFinderTest.java Fri Sep 17 21:16:56 2004
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.seda.listener;
+
+
+import junit.framework.TestCase;
+import junit.framework.Assert;
+
+
+/**
+ * Tests {@link AvailablePortFinder}.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class AvailablePortFinderTest extends TestCase
+{
+ public void testDefault()
+ {
+ AvailablePortFinder finder = new AvailablePortFinder();
+ // this just scan just takes too much time
+ //finder.getAvailablePorts();
+
+ // keep range short so it does not take too long
+ finder.getAvailablePorts( 1024, 1048 );
+ }
+
+
+ public void testExceptions()
+ {
+ AvailablePortFinder finder = new AvailablePortFinder();
+
+ try
+ {
+ finder.getAvailablePorts(
+ AvailablePortFinder.MIN_PORT_NUMBER - 1, 10 );
+ Assert.fail( "IllegalArgumentException must be thrown." );
+ }
+ catch ( IllegalArgumentException e )
+ {
+ }
+
+ try
+ {
+ finder.getAvailablePorts( AvailablePortFinder.MAX_PORT_NUMBER - 1,
+ AvailablePortFinder.MAX_PORT_NUMBER + 1 );
+ Assert.fail( "IllegalArgumentException must be thrown." );
+ }
+ catch ( IllegalArgumentException e )
+ {
+ }
+
+ try
+ {
+ finder.getAvailablePorts( 10, 5 );
+ Assert.fail( "IllegalArgumentException must be thrown." );
+ }
+ catch ( IllegalArgumentException e )
+ {
+ }
+ }
+
+
+ public void testNextAvailable()
+ {
+ int port = AvailablePortFinder.getNextAvailable(
+ AvailablePortFinder.MIN_PORT_NUMBER );
+ assertTrue( port >= AvailablePortFinder.MIN_PORT_NUMBER );
+ assertTrue( port <= AvailablePortFinder.MAX_PORT_NUMBER );
+ assertEquals( port, AvailablePortFinder.getNextAvailable() );
+ }
+}
Copied: incubator/directory/seda/trunk/src/test/org/apache/seda/listener/TCPListenerManagerTest.java (from rev 46270, incubator/directory/seda/trunk/src/test/org/apache/seda/listener/DefaultListenerManagerTest.java)
==============================================================================
--- incubator/directory/seda/trunk/src/test/org/apache/seda/listener/DefaultListenerManagerTest.java (original)
+++ incubator/directory/seda/trunk/src/test/org/apache/seda/listener/TCPListenerManagerTest.java Fri Sep 17 21:16:56 2004
@@ -32,7 +32,7 @@
* @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
* @version $Rev$
*/
-public class DefaultListenerManagerTest extends TestCase
+public class TCPListenerManagerTest extends TestCase
{
/** An event router to use for testing */
private EventRouter router = null;
@@ -40,7 +40,6 @@
private TCPListenerManager listener = null;
-
/*
* @see TestCase#setUp()
*/
@@ -71,7 +70,7 @@
* Constructor for DefaultListenerManagerTest.
* @param arg0
*/
- public DefaultListenerManagerTest( String arg0 )
+ public TCPListenerManagerTest( String arg0 )
{
super( arg0 );
}
@@ -79,18 +78,22 @@
public void testBind() throws Exception
{
- listener.bind( new TCPListenerConfig(
- new SocketListenerAddress(InetAddress.getLocalHost()),
- new InetServiceEntry( "ldap", 10389 ) ) );
+ int port = AvailablePortFinder.getNextAvailable();
+ ListenerConfig config = new TCPListenerConfig(
+ new SocketListenerAddress( InetAddress.getLocalHost() ),
+ new InetServiceEntry( "ldap", port ) );
+ listener.bind( config );
+ listener.unbind( config );
}
public void testUnbind() throws Exception
{
- ListenerConfig sl = new TCPListenerConfig(
+ int port = AvailablePortFinder.getNextAvailable();
+ ListenerConfig config = new TCPListenerConfig(
new SocketListenerAddress(InetAddress.getLocalHost()),
- new InetServiceEntry( "ldap", 10389 ) );
- listener.bind( sl );
- listener.unbind( sl );
+ new InetServiceEntry( "ldap", port ) );
+ listener.bind( config );
+ listener.unbind( config );
}
}