[kaffe] Bug Report: multiple sockets can't bind to same multicast address
Everton da Silva Marques
everton@lab.ipaccess.diveo.net.br
Wed Oct 29 14:08:02 2003
--liOOAslEiF7prFVr
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On Wed, Oct 29, 2003 at 02:02:54PM -0200, Everton da Silva Marques wrote:
> On Tue, Oct 07, 2003 at 02:46:22PM -0300, Everton da Silva Marques wrote:
> >
> > Kaffe (1.1.1 and 1.1.2) does not allow multiple multicast
> > sockets to bind to the same address/port pair.
>
> I think the problem is, MulticastSocket constructors call setReuseAddress(true)
> _after_ the invokation of super(). But super() (DatagramSocket) tries to
> bind the socket, and gets an exception.
>
> Thus, the fix for this problem requires to setReuseAddress(true) before
> binding the socket.
Please find attached a possible patch for this issue.
Regards,
Everton
--liOOAslEiF7prFVr
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="MulticastSocket.java.diff"
--- kaffe-1.1.2-orig/libraries/javalib/java/net/MulticastSocket.java 2003-08-30 11:18:32.000000000 -0300
+++ kaffe-1.1.2/libraries/javalib/java/net/MulticastSocket.java 2003-10-29 15:15:15.000000000 -0200
@@ -80,8 +80,7 @@
*/
public MulticastSocket() throws IOException
{
- super(0, null);
- setReuseAddress (true);
+ super(0, null, true);
}
/**
@@ -95,8 +94,7 @@
*/
public MulticastSocket(int port) throws IOException
{
- super(port, null);
- setReuseAddress (true);
+ super(port, null, true);
}
/**
@@ -112,8 +110,7 @@
*/
public MulticastSocket(SocketAddress address) throws IOException
{
- super(address);
- setReuseAddress (true);
+ super(address, true);
}
/**
--liOOAslEiF7prFVr
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="DatagramSocket.java.diff"
--- kaffe-1.1.2-orig/libraries/javalib/java/net/DatagramSocket.java 2003-09-28 16:54:10.000000000 -0300
+++ kaffe-1.1.2/libraries/javalib/java/net/DatagramSocket.java 2003-10-29 17:48:19.000000000 -0200
@@ -98,7 +98,7 @@
*
* @since 1.4
*/
- protected DatagramSocket (DatagramSocketImpl impl)
+ protected DatagramSocket(DatagramSocketImpl impl)
{
this.impl = impl;
this.remoteAddress = null;
@@ -133,42 +133,37 @@
this(port, null);
}
- /**
- * Initializes a new instance of <code>DatagramSocket</code> that binds to
- * the specified local port and address.
- *
- * @param port The local port number to bind to.
- * @param laddr The local address to bind to.
- *
- * @exception SecurityException If a security manager exists and its
- * checkListen method doesn't allow the operation.
- * @exception SocketException If an error occurs.
- */
- public DatagramSocket(int port, InetAddress laddr) throws SocketException
+ private void loadSocketImpl() throws SocketException
{
- if (port < 0 || port > 65535)
- throw new IllegalArgumentException("Invalid port: " + port);
-
- SecurityManager s = System.getSecurityManager();
- if (s != null)
- s.checkListen(port);
-
String propVal = System.getProperty("impl.prefix");
if (propVal == null || propVal.equals(""))
impl = new PlainDatagramSocketImpl();
else
try
- {
+ {
impl = (DatagramSocketImpl) Class.forName
("java.net." + propVal + "DatagramSocketImpl").newInstance();
- }
+ }
catch (Exception e)
- {
- System.err.println("Could not instantiate class: java.net." +
- propVal + "DatagramSocketImpl");
- impl = new PlainDatagramSocketImpl();
- }
+ {
+ System.err.println("Could not instantiate class: java.net." +
+ propVal + "DatagramSocketImpl");
+ impl = new PlainDatagramSocketImpl();
+ }
impl.create();
+ }
+
+ private void initDatagramSocket(int port, InetAddress laddr) throws SocketException
+ {
+ if (port < 0 || port > 65535)
+ throw new IllegalArgumentException("Invalid port: " + port);
+
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkListen(port);
+
+ if (impl == null)
+ loadSocketImpl();
if (laddr == null)
laddr = InetAddress.ANY_IF;
@@ -194,6 +189,41 @@
}
}
+ DatagramSocket(int port, InetAddress laddr, boolean reuseAddr) throws SocketException
+ {
+ setReuseAddress(reuseAddr);
+ initDatagramSocket(port, laddr);
+ }
+
+ DatagramSocket(InetAddress laddr, boolean reuseAddr) throws SocketException
+ {
+ setReuseAddress(reuseAddr);
+ initDatagramSocket(0, laddr);
+ }
+
+ /**
+ * Initializes a new instance of <code>DatagramSocket</code> that binds to
+ * the specified local port and address.
+ *
+ * @param port The local port number to bind to.
+ * @param laddr The local address to bind to.
+ *
+ * @exception SecurityException If a security manager exists and its
+ * checkListen method doesn't allow the operation.
+ * @exception SocketException If an error occurs.
+ */
+ public DatagramSocket(int port, InetAddress laddr) throws SocketException
+ {
+ initDatagramSocket(port, laddr);
+ }
+
+ DatagramSocket(SocketAddress address, boolean reuseAddr) throws SocketException
+ {
+ this (((InetSocketAddress) address).getPort (),
+ ((InetSocketAddress) address).getAddress (),
+ reuseAddr);
+ }
+
/**
* Initializes a new instance of <code>DatagramSocket</code> that binds to
* the specified local port and address.
@@ -207,7 +237,7 @@
*
* @since 1.4
*/
- public DatagramSocket (SocketAddress address) throws SocketException
+ public DatagramSocket(SocketAddress address) throws SocketException
{
this (((InetSocketAddress) address).getPort (),
((InetSocketAddress) address).getAddress ());
@@ -714,7 +744,7 @@
public void setReuseAddress(boolean on) throws SocketException
{
if (impl == null)
- throw new SocketException ("Cannot initialize Socket implementation");
+ loadSocketImpl();
impl.setOption (SocketOptions.SO_REUSEADDR, new Boolean (on));
}
--liOOAslEiF7prFVr--