You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@zookeeper.apache.org by kofemann <gi...@git.apache.org> on 2018/01/12 10:30:59 UTC

[GitHub] zookeeper pull request #448: client: do not try to connect to an unreachable...

GitHub user kofemann opened a pull request:

    https://github.com/apache/zookeeper/pull/448

    client: do not try to connect to an unreachable server

    Motivation:
    When the client wants to connect to a server it lookups the all IP
    addresses of servers in the **connectString** and randomly picks one of
    them. However, if the client has only IPv4 configured of IPv6 with link
    local only, then connection will fail:
    
    ---
    Welcome to ZooKeeper!
    JLine support is enabled
    2018-01-12 11:19:02,902 [myid:] - INFO  [main-SendThread(lab004:2181):ClientCnxn$SendThread@1035] - Opening socket connection to server lab004/xxxx:xxx:xxx:1062:0:0:1:60:2181. Will not attempt to authenticate using SASL (unknown error)
    [zk: lab004:2181(CONNECTING) 0] ls /
    2018-01-12 11:19:17,853 [myid:] - WARN  [main-SendThread(lab004:2181):ClientCnxn$SendThread@1111] - Client session timed out, have not heard from server in 15011ms for sessionid 0x0
    2018-01-12 11:19:17,853 [myid:] - INFO  [main-SendThread(lab004:2181):ClientCnxn$SendThread@1159] - Client session timed out, have not heard from server in 15011ms for sessionid 0x0, closing socket connection and attempting reconnect
    2018-01-12 11:19:17,956 [myid:] - INFO  [main-SendThread(lab004:2181):ClientCnxn$SendThread@1035] - Opening socket connection to server lab004/x.x.x.x:2181. Will not attempt to authenticate using SASL (unknown error)
    2018-01-12 11:19:17,956 [myid:] - INFO  [main-SendThread(lab004:2181):ClientCnxn$SendThread@877] - Socket connection established to lab004/x.x.x.x:2181, initiating session
    Exception in thread "main" org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /
    	at org.apache.zookeeper.KeeperException.create(KeeperException.java:102)
    	at org.apache.zookeeper.KeeperException.create(KeeperException.java:54)
    	at org.apache.zookeeper.ZooKeeper.getChildren(ZooKeeper.java:1535)
    	at org.apache.zookeeper.ZooKeeper.getChildren(ZooKeeper.java:1563)
    	at org.apache.zookeeper.ZooKeeperMain.processZKCmd(ZooKeeperMain.java:732)
    	at org.apache.zookeeper.ZooKeeperMain.processCmd(ZooKeeperMain.java:600)
    	at org.apache.zookeeper.ZooKeeperMain.executeLine(ZooKeeperMain.java:372)
    	at org.apache.zookeeper.ZooKeeperMain.run(ZooKeeperMain.java:332)
    	at org.apache.zookeeper.ZooKeeperMain.main(ZooKeeperMain.java:291)
    
    ----
    
    Modification:
    Auto-discover supported IP version and filter out server IP addresses
    which can't be reached. If Auto-discovery failed, then client will have
    the old behaviour.
    
    Result:
    Client does not attempts to use IPv6 if it's not configured.
    
    Signed-off-by: Tigran Mkrtchyan <ti...@desy.de>

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/kofemann/zookeeper filter-out-ipv6

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/zookeeper/pull/448.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #448
    
----
commit 270dc8e4e5cc302845a4f9cd80002ad32edd60da
Author: Tigran Mkrtchyan <ti...@...>
Date:   2018-01-12T10:14:13Z

    client: do not try to connect to an unreachable server
    
    Motivation:
    When the client wants to connect to a server it lookups the all IP
    addresses of servers in the **connectString** and randomly picks one of
    them. However, if the client has only IPv4 configured of IPv6 with link
    local only, then connection will fail:
    
    ---
    Welcome to ZooKeeper!
    JLine support is enabled
    2018-01-12 11:19:02,902 [myid:] - INFO  [main-SendThread(lab004:2181):ClientCnxn$SendThread@1035] - Opening socket connection to server lab004/xxxx:xxx:xxx:1062:0:0:1:60:2181. Will not attempt to authenticate using SASL (unknown error)
    [zk: lab004:2181(CONNECTING) 0] ls /
    2018-01-12 11:19:17,853 [myid:] - WARN  [main-SendThread(lab004:2181):ClientCnxn$SendThread@1111] - Client session timed out, have not heard from server in 15011ms for sessionid 0x0
    2018-01-12 11:19:17,853 [myid:] - INFO  [main-SendThread(lab004:2181):ClientCnxn$SendThread@1159] - Client session timed out, have not heard from server in 15011ms for sessionid 0x0, closing socket connection and attempting reconnect
    2018-01-12 11:19:17,956 [myid:] - INFO  [main-SendThread(lab004:2181):ClientCnxn$SendThread@1035] - Opening socket connection to server lab004/x.x.x.x:2181. Will not attempt to authenticate using SASL (unknown error)
    2018-01-12 11:19:17,956 [myid:] - INFO  [main-SendThread(lab004:2181):ClientCnxn$SendThread@877] - Socket connection established to lab004/x.x.x.x:2181, initiating session
    Exception in thread "main" org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /
    	at org.apache.zookeeper.KeeperException.create(KeeperException.java:102)
    	at org.apache.zookeeper.KeeperException.create(KeeperException.java:54)
    	at org.apache.zookeeper.ZooKeeper.getChildren(ZooKeeper.java:1535)
    	at org.apache.zookeeper.ZooKeeper.getChildren(ZooKeeper.java:1563)
    	at org.apache.zookeeper.ZooKeeperMain.processZKCmd(ZooKeeperMain.java:732)
    	at org.apache.zookeeper.ZooKeeperMain.processCmd(ZooKeeperMain.java:600)
    	at org.apache.zookeeper.ZooKeeperMain.executeLine(ZooKeeperMain.java:372)
    	at org.apache.zookeeper.ZooKeeperMain.run(ZooKeeperMain.java:332)
    	at org.apache.zookeeper.ZooKeeperMain.main(ZooKeeperMain.java:291)
    
    ----
    
    Modification:
    Auto-discover supported IP version and filter out server IP addresses
    which can't be reached. If Auto-discovery failed, then client will have
    the old behaviour.
    
    Result:
    Client does not attempts to use IPv6 if it's not configured.
    
    Signed-off-by: Tigran Mkrtchyan <ti...@desy.de>

----


---

[GitHub] zookeeper pull request #448: client: do not try to connect to an unreachable...

Posted by anmolnar <gi...@git.apache.org>.
Github user anmolnar commented on a diff in the pull request:

    https://github.com/apache/zookeeper/pull/448#discussion_r165844761
  
    --- Diff: src/java/main/org/apache/zookeeper/client/StaticHostProvider.java ---
    @@ -107,16 +112,43 @@ public StaticHostProvider(Collection<InetSocketAddress> serverAddresses,
             lastIndex = -1;              
         }
     
    +    private Set<Class<? extends InetAddress>> supportedAddressTypes() {
    +        Set<Class<? extends InetAddress>> types = new HashSet<>();
    +        try {
    +            Enumeration<NetworkInterface> inets = NetworkInterface.getNetworkInterfaces();
    +            while (inets.hasMoreElements()) {
    +                NetworkInterface ne = inets.nextElement();
    +
    +                Enumeration<InetAddress> addrs = ne.getInetAddresses();
    +                while (addrs.hasMoreElements()) {
    +                    InetAddress addr = addrs.nextElement();
    +                    if (addr.isLinkLocalAddress() || addr.isLoopbackAddress()) {
    +                        continue;
    +                    }
    +                    types.add(addr.getClass());
    +                }
    +            }
    +        } catch (SocketException e) {
    +            LOG.error("Failed to resolve supported address types: ", e);
    --- End diff --
    
    Catching this exception here could result the method returning empty list of supported address types which later will make the client unable to connect to any servers.
    I think the client should be terminated either in the case of empty list or the first time when this is exception is caught. 


---

[GitHub] zookeeper pull request #448: client: do not try to connect to an unreachable...

Posted by anmolnar <gi...@git.apache.org>.
Github user anmolnar commented on a diff in the pull request:

    https://github.com/apache/zookeeper/pull/448#discussion_r165844805
  
    --- Diff: src/java/main/org/apache/zookeeper/client/StaticHostProvider.java ---
    @@ -107,16 +112,43 @@ public StaticHostProvider(Collection<InetSocketAddress> serverAddresses,
             lastIndex = -1;              
         }
     
    +    private Set<Class<? extends InetAddress>> supportedAddressTypes() {
    +        Set<Class<? extends InetAddress>> types = new HashSet<>();
    +        try {
    +            Enumeration<NetworkInterface> inets = NetworkInterface.getNetworkInterfaces();
    +            while (inets.hasMoreElements()) {
    +                NetworkInterface ne = inets.nextElement();
    +
    +                Enumeration<InetAddress> addrs = ne.getInetAddresses();
    +                while (addrs.hasMoreElements()) {
    +                    InetAddress addr = addrs.nextElement();
    +                    if (addr.isLinkLocalAddress() || addr.isLoopbackAddress()) {
    +                        continue;
    +                    }
    +                    types.add(addr.getClass());
    +                }
    +            }
    +        } catch (SocketException e) {
    +            LOG.error("Failed to resolve supported address types: ", e);
    +        }
    +        return types;
    +    }
    +
         private List<InetSocketAddress> resolveAndShuffle(Collection<InetSocketAddress> serverAddresses) {
    -        List<InetSocketAddress> tmpList = new ArrayList<InetSocketAddress>(serverAddresses.size());       
    +        List<InetSocketAddress> tmpList = new ArrayList<InetSocketAddress>(serverAddresses.size());
    +        Set<Class<? extends InetAddress>> supprtedInetTypes = supportedAddressTypes();
    +
             for (InetSocketAddress address : serverAddresses) {
                 try {
                     InetAddress ia = address.getAddress();
                     String addr = (ia != null) ? ia.getHostAddress() : address.getHostString();
                     InetAddress resolvedAddresses[] = InetAddress.getAllByName(addr);
                     for (InetAddress resolvedAddress : resolvedAddresses) {
                         InetAddress taddr = InetAddress.getByAddress(address.getHostString(), resolvedAddress.getAddress());
    -                    tmpList.add(new InetSocketAddress(taddr, address.getPort()));
    +                    // try to use IP address only if it's supported by our network stack
    +                    if (!supprtedInetTypes.isEmpty() && supprtedInetTypes.contains(taddr.getClass())) {
    --- End diff --
    
    It'd also work to skip the validation if supportedInetTypes is empty.


---

[GitHub] zookeeper pull request #448: client: do not try to connect to an unreachable...

Posted by anmolnar <gi...@git.apache.org>.
Github user anmolnar commented on a diff in the pull request:

    https://github.com/apache/zookeeper/pull/448#discussion_r165844811
  
    --- Diff: src/java/main/org/apache/zookeeper/client/StaticHostProvider.java ---
    @@ -107,16 +112,43 @@ public StaticHostProvider(Collection<InetSocketAddress> serverAddresses,
             lastIndex = -1;              
         }
     
    +    private Set<Class<? extends InetAddress>> supportedAddressTypes() {
    +        Set<Class<? extends InetAddress>> types = new HashSet<>();
    +        try {
    +            Enumeration<NetworkInterface> inets = NetworkInterface.getNetworkInterfaces();
    +            while (inets.hasMoreElements()) {
    +                NetworkInterface ne = inets.nextElement();
    +
    +                Enumeration<InetAddress> addrs = ne.getInetAddresses();
    +                while (addrs.hasMoreElements()) {
    +                    InetAddress addr = addrs.nextElement();
    +                    if (addr.isLinkLocalAddress() || addr.isLoopbackAddress()) {
    +                        continue;
    +                    }
    +                    types.add(addr.getClass());
    +                }
    +            }
    +        } catch (SocketException e) {
    +            LOG.error("Failed to resolve supported address types: ", e);
    +        }
    +        return types;
    +    }
    +
         private List<InetSocketAddress> resolveAndShuffle(Collection<InetSocketAddress> serverAddresses) {
    -        List<InetSocketAddress> tmpList = new ArrayList<InetSocketAddress>(serverAddresses.size());       
    +        List<InetSocketAddress> tmpList = new ArrayList<InetSocketAddress>(serverAddresses.size());
    +        Set<Class<? extends InetAddress>> supprtedInetTypes = supportedAddressTypes();
    --- End diff --
    
    typo in the variable name


---