From 429580e62f54cd54fa1ecf76d70ba2173eb05efe 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.

---
 opendj-sdk/opends/src/messages/messages/protocol.properties                              |    4 ++--
 opendj-sdk/opends/src/server/org/opends/server/protocols/jmx/JmxConnectionHandler.java   |   37 ++++++++++++++++++++++++++++++++++++-
 opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java |    4 ++--
 3 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/opendj-sdk/opends/src/messages/messages/protocol.properties b/opendj-sdk/opends/src/messages/messages/protocol.properties
index 46d2ef4..b855f22 100644
--- a/opendj-sdk/opends/src/messages/messages/protocol.properties
+++ b/opendj-sdk/opends/src/messages/messages/protocol.properties
@@ -20,7 +20,7 @@
 #
 # CDDL HEADER END
 #
-#      Portions Copyright 2006-2007 Sun Microsystems, Inc.
+#      Portions Copyright 2006-2008 Sun Microsystems, Inc.
 
 
 
@@ -1434,4 +1434,4 @@
  from %s to %s:  %s
 SEVERE_ERR_LDIF_CONNHANDLER_CANNOT_DELETE_456=An error occurred while the \
  LDIF connection handler was attempting to delete processed file %s:  %s
-SEVERE_ERR_LDAP_CONNHANDLER_ADDRESS_INUSE_457=Address already in use
+SEVERE_ERR_CONNHANDLER_ADDRESS_INUSE_457=Address already in use
diff --git a/opendj-sdk/opends/src/server/org/opends/server/protocols/jmx/JmxConnectionHandler.java b/opendj-sdk/opends/src/server/org/opends/server/protocols/jmx/JmxConnectionHandler.java
index 6ac3305..d8166b0 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/protocols/jmx/JmxConnectionHandler.java
+++ b/opendj-sdk/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()));
diff --git a/opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java b/opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java
index 234ed02..527cd75 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
+ *      Portions Copyright 2006-2008 Sun Microsystems, Inc.
  */
 package org.opends.server.protocols.ldap;
 import org.opends.messages.Message;
@@ -744,7 +744,7 @@
             if (s.isConnected()) {
               s.close();
               throw new IOException(
-                ERR_LDAP_CONNHANDLER_ADDRESS_INUSE.get().toString());
+                ERR_CONNHANDLER_ADDRESS_INUSE.get().toString());
             }
           }
 

--
Gitblit v1.10.0