From 64ad04811695411c23bc721c080719f5db355cf0 Mon Sep 17 00:00:00 2001
From: abobrov <abobrov@localhost>
Date: Fri, 25 Jan 2008 14:04:05 +0000
Subject: [PATCH] - complete fix for Issue 1231:   attempt to detect dual stack wildcard bind conflicts with dummy connect prior to the test bind.

---
 opends/src/server/org/opends/server/protocols/jmx/JmxConnectionHandler.java |   37 ++++++++++++++++++++++++++++++++++++-
 1 files changed, 36 insertions(+), 1 deletions(-)

diff --git a/opends/src/server/org/opends/server/protocols/jmx/JmxConnectionHandler.java b/opends/src/server/org/opends/server/protocols/jmx/JmxConnectionHandler.java
index 6ac3305..d8166b0 100644
--- a/opends/src/server/org/opends/server/protocols/jmx/JmxConnectionHandler.java
+++ b/opends/src/server/org/opends/server/protocols/jmx/JmxConnectionHandler.java
@@ -22,9 +22,10 @@
  * CDDL HEADER END
  *
  *
- *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
+ *      Portions Copyright 2006-2008 Sun Microsystems, Inc.
  */
 package org.opends.server.protocols.jmx;
+import java.io.IOException;
 import org.opends.messages.Message;
 
 
@@ -36,6 +37,7 @@
 
 import java.net.InetSocketAddress;
 import java.net.ServerSocket;
+import java.net.Socket;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedHashMap;
@@ -332,6 +334,39 @@
     ServerSocket s = null;
     try
     {
+      // HACK:
+      // With dual stacks we can have a situation when INADDR_ANY/PORT
+      // is bound in TCP4 space but available in TCP6 space and since
+      // JavaServerSocket implemantation will always use TCP46 on dual
+      // stacks the bind below will always succeed in such cases thus
+      // shadowing anything that is already bound to INADDR_ANY/PORT.
+      // While technically correct, with IPv4 and IPv6 being separate
+      // address spaces, it presents a problem to end users because a
+      // common case scenario is to have a single service serving both
+      // address spaces ie listening to the same port in both spaces
+      // on wildcard addresses 0 and ::. ServerSocket implemantation
+      // does not provide any means of working with each address space
+      // separately such as doing TCP4 or TCP6 only binds thus we have
+      // to do a dummy connect to INADDR_ANY/PORT to check if it is
+      // bound to something already. This is only needed for wildcard
+      // addresses as specific IPv4 or IPv6 addresses will always be
+      // handled in their respective address space.
+      Socket clientSocket = new Socket();
+      try {
+        // This might fail on some stacks but this is the best we
+        // can do. No need for explicit timeout since it is local
+        // address and we have to know for sure unless it fails.
+        clientSocket.connect(new InetSocketAddress(
+          config.getListenPort()));
+      } catch (IOException e) {
+        // Expected, ignore.
+      }
+      if (clientSocket.isConnected()) {
+        clientSocket.close();
+        throw new IOException(
+          ERR_CONNHANDLER_ADDRESS_INUSE.get().toString());
+      }
+
       s = new ServerSocket();
       s.setReuseAddress(true);
       s.bind(new InetSocketAddress(config.getListenPort()));

--
Gitblit v1.10.0