Repository: ignite Updated Branches: refs/heads/master 28079cdbd -> 6c3a486f0
IGNITE-9657 IGNITE-9657 Fixed socket leak in TcpDiscoverySpi Signed-off-by: Andrey Gura <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/6c3a486f Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/6c3a486f Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/6c3a486f Branch: refs/heads/master Commit: 6c3a486f0d7f0dd55c377af233d7c525d86f600a Parents: 28079cd Author: ezhuravl <[email protected]> Authored: Fri Sep 21 17:38:28 2018 +0300 Committer: Andrey Gura <[email protected]> Committed: Fri Sep 21 17:39:21 2018 +0300 ---------------------------------------------------------------------- .../spi/discovery/tcp/TcpDiscoverySpi.java | 44 +++++--- .../TcpClientDiscoveryUnresolvedHostTest.java | 111 +++++++++++++++++++ .../IgniteSpiDiscoverySelfTestSuite.java | 2 + 3 files changed, 142 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/6c3a486f/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java index d8dc8f8..048abf6 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java @@ -1498,18 +1498,25 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter implements IgniteDiscovery assert remAddr != null; - InetSocketAddress resolved = remAddr.isUnresolved() ? - new InetSocketAddress(InetAddress.getByName(remAddr.getHostName()), remAddr.getPort()) : remAddr; + try { + InetSocketAddress resolved = remAddr.isUnresolved() ? + new InetSocketAddress(InetAddress.getByName(remAddr.getHostName()), remAddr.getPort()) : remAddr; + + InetAddress addr = resolved.getAddress(); - InetAddress addr = resolved.getAddress(); + assert addr != null; - assert addr != null; + sock.connect(resolved, (int)timeoutHelper.nextTimeoutChunk(sockTimeout)); - sock.connect(resolved, (int)timeoutHelper.nextTimeoutChunk(sockTimeout)); + writeToSocket(sock, null, U.IGNITE_HEADER, timeoutHelper.nextTimeoutChunk(sockTimeout)); - writeToSocket(sock, null, U.IGNITE_HEADER, timeoutHelper.nextTimeoutChunk(sockTimeout)); + return sock; + } catch (IOException | IgniteSpiOperationTimeoutException e) { + if (sock != null) + U.closeQuiet(sock); - return sock; + throw e; + } } /** @@ -1519,18 +1526,25 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter implements IgniteDiscovery * @throws IOException If failed. */ Socket createSocket() throws IOException { - Socket sock; + Socket sock = null; - if (isSslEnabled()) - sock = sslSockFactory.createSocket(); - else - sock = new Socket(); + try { + if (isSslEnabled()) + sock = sslSockFactory.createSocket(); + else + sock = new Socket(); + + sock.bind(new InetSocketAddress(locHost, 0)); - sock.bind(new InetSocketAddress(locHost, 0)); + sock.setTcpNoDelay(true); - sock.setTcpNoDelay(true); + return sock; + } catch (IOException e) { + if (sock != null) + U.closeQuiet(sock); - return sock; + throw e; + } } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/6c3a486f/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpClientDiscoveryUnresolvedHostTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpClientDiscoveryUnresolvedHostTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpClientDiscoveryUnresolvedHostTest.java new file mode 100644 index 0000000..4dc1604 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpClientDiscoveryUnresolvedHostTest.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.spi.discovery.tcp; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.spi.IgniteSpiOperationTimeoutException; +import org.apache.ignite.spi.IgniteSpiOperationTimeoutHelper; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +/** + * Client-based discovery SPI test with unresolved server hosts. + */ +public class TcpClientDiscoveryUnresolvedHostTest extends GridCommonAbstractTest { + /** */ + TestTcpDiscoverySpi spi; + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); + + spi = new TestTcpDiscoverySpi(); + + cfg.setDiscoverySpi(spi.setJoinTimeout(5000).setIpFinder(new TcpDiscoveryVmIpFinder() + .setAddresses(Collections.singletonList("test:47500")))); + + cfg.setCacheConfiguration(); + + cfg.setClientMode(true); + + return cfg; + } + + /** + * Test that sockets closed after exception. + * + * @throws Exception in case of error. + */ + public void test() throws Exception { + try { + startGrid(0); + } catch (IgniteCheckedException e) { + //Ignore. + } + + assertEquals(0, spi.getSockets().size()); + } + + /** + * TcpDiscoverySpi implementation with additional storing of created sockets. + */ + private static class TestTcpDiscoverySpi extends TcpDiscoverySpi { + /** */ + Set<Socket> sockets = new HashSet<>(); + + /** {@inheritDoc} */ + @Override Socket createSocket() throws IOException { + Socket socket = super.createSocket(); + + sockets.add(socket); + + return socket; + } + + /** {@inheritDoc} */ + @Override protected Socket openSocket(Socket sock, InetSocketAddress remAddr, IgniteSpiOperationTimeoutHelper timeoutHelper) + throws IOException, IgniteSpiOperationTimeoutException { + + try { + return super.openSocket(sock, remAddr, timeoutHelper); + } + catch (IgniteSpiOperationTimeoutException | IOException e) { + if (sock.isClosed()) + sockets.remove(sock); + + throw e; + } + } + + /** + * Gets list of sockets opened by this discovery spi. + * + * @return List of sockets. + */ + public Set<Socket> getSockets() { + return sockets; + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6c3a486f/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java index 39d5421..04869f9 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java @@ -30,6 +30,7 @@ import org.apache.ignite.spi.discovery.tcp.TcpClientDiscoveryMarshallerCheckSelf import org.apache.ignite.spi.discovery.tcp.TcpClientDiscoverySpiFailureTimeoutSelfTest; import org.apache.ignite.spi.discovery.tcp.TcpClientDiscoverySpiMulticastTest; import org.apache.ignite.spi.discovery.tcp.TcpClientDiscoverySpiSelfTest; +import org.apache.ignite.spi.discovery.tcp.TcpClientDiscoveryUnresolvedHostTest; import org.apache.ignite.spi.discovery.tcp.TcpDiscoveryClientSuspensionSelfTest; import org.apache.ignite.spi.discovery.tcp.TcpDiscoveryMarshallerCheckSelfTest; import org.apache.ignite.spi.discovery.tcp.TcpDiscoveryMultiThreadedTest; @@ -99,6 +100,7 @@ public class IgniteSpiDiscoverySelfTestSuite extends TestSuite { suite.addTest(new TestSuite(TcpClientDiscoveryMarshallerCheckSelfTest.class)); suite.addTest(new TestSuite(TcpClientDiscoverySpiMulticastTest.class)); suite.addTest(new TestSuite(TcpClientDiscoverySpiFailureTimeoutSelfTest.class)); + suite.addTest(new TestSuite(TcpClientDiscoveryUnresolvedHostTest.class)); suite.addTest(new TestSuite(TcpDiscoveryNodeConsistentIdSelfTest.class)); suite.addTest(new TestSuite(TcpDiscoveryNodeConfigConsistentIdSelfTest.class));
