ZooKeeper
  1. ZooKeeper
  2. ZOOKEEPER-667

java client doesn't allow ipv6 numeric connect string

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 3.2.2
    • Fix Version/s: 3.3.0
    • Component/s: java client
    • Labels:
      None
    • Tags:
      ipv6

      Description

      The java client doesn't handle ipv6 numeric addresses as they are colon ( delmited. After splitting the host/port on : we look for the port as the second entry in the array rather than the last entry in the array.

        Issue Links

          Activity

          Hide
          Patrick Hunt added a comment -

          I'm fixing this as part of ZOOKEEPER-635

          Show
          Patrick Hunt added a comment - I'm fixing this as part of ZOOKEEPER-635
          Hide
          Benjamin Reed added a comment -

          the source of all truth, aka wikipedia http://en.wikipedia.org/wiki/IPv6_address notes that for URLs with ipv6 addresses they use http://[blah:blah::blah]:port. perhaps we should use this syntax as well.

          btw, i also noticed with some testing that if you bind to ::1, you cannot connect to it using 127.0.0.1. binding to 127.0.0.1 you cannot connect using ::1, but you can use ::ffff:127.0.0.1. binding to ::ffff:127.0.0.1 you can connect using 127.0.0.1 and ::ffff:127.0.0.1 but not ::1.

          Show
          Benjamin Reed added a comment - the source of all truth, aka wikipedia http://en.wikipedia.org/wiki/IPv6_address notes that for URLs with ipv6 addresses they use http://[blah:blah::blah]:port . perhaps we should use this syntax as well. btw, i also noticed with some testing that if you bind to ::1, you cannot connect to it using 127.0.0.1. binding to 127.0.0.1 you cannot connect using ::1, but you can use ::ffff:127.0.0.1. binding to ::ffff:127.0.0.1 you can connect using 127.0.0.1 and ::ffff:127.0.0.1 but not ::1.
          Hide
          Patrick Hunt added a comment -

          turned out fixing this was a bit of a pita. java adds some %scope_id to the end of ipv6 addresses for getHostAddress() calls, however it does
          not allow specifying an address with this scopeid (so the code needs to look for this and strip it).

          re ben's comment on using [ipv6]:port the current patch on ZOOKEEPER-667 doesn't have this. I currently have ipv6:port, where the code looks
          for the trailing :# on the connect string to pull out the port number. I'm not convinced that [ipv6]:port is really the way to go

          1) parsing the connect string is more complicated
          2) anyone trying to generate the connect string (esp code) now has to handle this as a special case as well

          if we just always require ipv

          {4|6}

          :port and our code looks for trailing :port I think we are fine. the only small discrepancy
          is that we allow ipv4 w/o port, in which case we default the port to 2181. In the case of ipv6 we will always require
          the user to specify ipv6:port (ie no default for port in this case).

          what do you think? I don't want to change things later, so if you see a problem with this we should just switch to the
          [ipv6]:port stuff now rather than change things for users later.

          Show
          Patrick Hunt added a comment - turned out fixing this was a bit of a pita. java adds some %scope_id to the end of ipv6 addresses for getHostAddress() calls, however it does not allow specifying an address with this scopeid (so the code needs to look for this and strip it). re ben's comment on using [ipv6] :port the current patch on ZOOKEEPER-667 doesn't have this. I currently have ipv6:port, where the code looks for the trailing :# on the connect string to pull out the port number. I'm not convinced that [ipv6] :port is really the way to go 1) parsing the connect string is more complicated 2) anyone trying to generate the connect string (esp code) now has to handle this as a special case as well if we just always require ipv {4|6} :port and our code looks for trailing :port I think we are fine. the only small discrepancy is that we allow ipv4 w/o port, in which case we default the port to 2181. In the case of ipv6 we will always require the user to specify ipv6:port (ie no default for port in this case). what do you think? I don't want to change things later, so if you see a problem with this we should just switch to the [ipv6] :port stuff now rather than change things for users later.
          Hide
          Benjamin Reed added a comment -

          requiring the port for ipv6 sounds ok to me. i think we can support both for almost free: it turns out that the following are equivalent:

          InetAddress.getByName("[::1]")
          InetAddress.getByName("::1")

          the trick is that we have not look for a port if there is a ] after the last :

          Show
          Benjamin Reed added a comment - requiring the port for ipv6 sounds ok to me. i think we can support both for almost free: it turns out that the following are equivalent: InetAddress.getByName(" [::1] ") InetAddress.getByName("::1") the trick is that we have not look for a port if there is a ] after the last :
          Hide
          Mahadev konar added a comment -

          resolved in ZOOKEEPER-635.

          Show
          Mahadev konar added a comment - resolved in ZOOKEEPER-635 .
          Hide
          Gunnar Wagenknecht added a comment -

          I'm wondering if there is something else to do for proper connecting on IPv6 systems. I'm on Windows 7 with Java 6 and I do have the following exception in my logs.

          When connecting I specified localhost:2181.

          21:20:04.157 [Worker-0-SendThread()] INFO  org.apache.zookeeper.ClientCnxn - Opening socket connection to server localhost/0:0:0:0:0:0:0:1:2181
          21:20:04.188 [Worker-0-SendThread(localhost:2181)] WARN  org.apache.zookeeper.ClientCnxn - Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect
          java.net.SocketException: Address family not supported by protocol family: connect
          	at sun.nio.ch.Net.connect(Native Method) ~[na:1.6.0_21]
          	at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:507) ~[na:1.6.0_21]
          	at org.apache.zookeeper.ClientCnxn$SendThread.startConnect(ClientCnxn.java:1009) ~[na:na]
          	at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1036) ~[na:na]
          
          Show
          Gunnar Wagenknecht added a comment - I'm wondering if there is something else to do for proper connecting on IPv6 systems. I'm on Windows 7 with Java 6 and I do have the following exception in my logs. When connecting I specified localhost:2181 . 21:20:04.157 [Worker-0-SendThread()] INFO org.apache.zookeeper.ClientCnxn - Opening socket connection to server localhost/0:0:0:0:0:0:0:1:2181 21:20:04.188 [Worker-0-SendThread(localhost:2181)] WARN org.apache.zookeeper.ClientCnxn - Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect java.net.SocketException: Address family not supported by protocol family: connect at sun.nio.ch.Net.connect(Native Method) ~[na:1.6.0_21] at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:507) ~[na:1.6.0_21] at org.apache.zookeeper.ClientCnxn$SendThread.startConnect(ClientCnxn.java:1009) ~[na:na] at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1036) ~[na:na]
          Hide
          Gerben Kegel added a comment -

          Nio in Java 6 under Windows 7 doesn't support IPv6.

          You can create a server socket like this:

          ServerSocket socket;
          if (nioSupported(localEp)) {
            serverChannel = ServerSocketChannel.open();
            socket = serverChannel.socket();
          } else {
            socket = new ServerSocket();
          }
          
          private boolean nioSupported(InetAddress localEp) {
            String os = System.getProperty("os.name");
            return !(localEp instanceof Inet6Address && os.equals("Windows 7"));
          }
          
          Show
          Gerben Kegel added a comment - Nio in Java 6 under Windows 7 doesn't support IPv6. You can create a server socket like this: ServerSocket socket; if (nioSupported(localEp)) { serverChannel = ServerSocketChannel.open(); socket = serverChannel.socket(); } else { socket = new ServerSocket(); } private boolean nioSupported(InetAddress localEp) { String os = System .getProperty( "os.name" ); return !(localEp instanceof Inet6Address && os.equals( "Windows 7" )); }

            People

            • Assignee:
              Patrick Hunt
              Reporter:
              Patrick Hunt
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development