JDK-8238274 : (sctp) JDK-7118373 is not fixed for SctpChannel
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 14
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: linux_redhat_7.3
  • CPU: x86
  • Submitted: 2020-01-30
  • Updated: 2024-04-03
  • Resolved: 2021-09-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 17 JDK 18
11.0.23Fixed 17.0.8Fixed 18 b17Fixed
Related Reports
Relates :  
Relates :  
Description
                                
ADDITIONAL SYSTEM INFORMATION :
OS: 
Red Hat Linux 7.4 Linux 3.10.0-693.el7.x86_64 #1 SMP

Java: 
openjdk version "14-ea" 2020-03-17
OpenJDK Runtime Environment (build 14-ea+20-879)
OpenJDK 64-Bit Server VM (build 14-ea+20-879, mixed mode, sharing)

A DESCRIPTION OF THE PROBLEM :
JDK-7118373 is fixed for SocketChannel in JDK8, but is not fixed for SctpChannel in latest 
JDK release (JDK 14-ea+20).


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run test case as background process.
  java ESctp &
2. Repleat to invoke "lsof -U -a -p [PID]" during running above process 

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Number of unix socket keeps 1
ACTUAL -
Number of unix socket increases linearly

---------- BEGIN SOURCE ----------
import java.net.*;
import java.util.*;
import java.io.*;
import java.nio.channels.*;
import com.sun.nio.sctp.*;

class ESctp
{
  static Selector selector;
  static int NUM = 10;
  static SelectorThread selthread;

  public static void main(String[] args) throws Exception
  {
    int port = 12345;

    if (!isSCTPSupported()) {
      System.out.println("SCTP protocol is not supported");
      System.out.println("Test cannot be run");
      return;
    }

    if (args.length == 1) {
      try {
        port = Integer.parseInt(args[0]);
      } catch(Exception e) {}
    }
    new Server(port).start();

    new Server2(port+1).start();
    Thread.sleep(100); // wait for server ready
    selector = Selector.open();

    init(port+1);

    selthread = new SelectorThread();
    selthread.start();

    for (int i = 0 ; i < 500 ; ++i) {
      System.out.println(i);
      doIt(port);
      Thread.sleep(200);
    }
    System.out.println("end");
    System.exit(0);
  }

  static boolean isSCTPSupported() {
    try {
      SctpChannel c = SctpChannel.open();
      c.close();
      return true;
    } catch (IOException ioe) {
      ioe.printStackTrace();
    } catch (UnsupportedOperationException e) {
      System.out.println(e);
    }

    return false;
  }

  static void init(int port) throws Exception
  {
    InetSocketAddress sa = new InetSocketAddress("localhost", port);
    for (int i = 0 ; i < 3 ; ++i) {
      SctpChannel channel = SctpChannel.open(sa, 1, 1);
      channel.configureBlocking(false);
      channel.register(selector, SelectionKey.OP_READ);
    }
  }


  static void doIt(int port) throws Exception
  {
    InetSocketAddress sa = new InetSocketAddress("localhost", port);

    for (int i = 0 ; i < NUM ; ++i) {
      System.out.println("  " + i);
      SctpChannel channel = SctpChannel.open(sa, 1, 1);
      channel.configureBlocking(false);

      SelectionKey key = selthread.regchannel(channel);

      key.cancel();
      selector.wakeup();
      channel.close();

      Thread.sleep(200);
    }
  }

  static class SelectorThread extends Thread
  {
    Object lock = new Object();
    SctpChannel channel;
    SelectionKey key;

    SelectionKey regchannel(SctpChannel ch) throws Exception
    {
      synchronized (lock) {
	channel = ch;
	selector.wakeup();
	lock.wait();
      }
      return key;
    }

    public void run()
    {
      try {
        while (true) {
	  selector.select(10000);
	  synchronized (lock) {
	    if (channel != null) {
	      key = channel.register(selector, SelectionKey.OP_READ);
	      channel = null;
	      lock.notify();
	    }
	  }
        }

      } catch (Exception e) {
	e.printStackTrace();
      }
    }
  }

  static class Server2 extends Thread
  {
    SctpChannel[] x;
    int port;

    Server2(int port) {
      this.port = port;
    }

    public void run()
    {
      x = new SctpChannel[32];
      int i = 0;
      try {
	SctpServerChannel ss = SctpServerChannel.open();
	InetSocketAddress sa = new InetSocketAddress("localhost", port);
	ss.bind(sa);
	while (true) {
	  SctpChannel soc = ss.accept();
          x[i] = soc;
          i++;
	}
      } catch (Exception e) {
	e.printStackTrace();
      }
    }
  }
    
  static class Server extends Thread
  {
    int port;

    Server(int port) { this.port = port; }

    public void run()
    {
      try {
	SctpServerChannel ss = SctpServerChannel.open();
	InetSocketAddress sa = new InetSocketAddress("localhost", port);
	ss.bind(sa);
	while (true) {
	  SctpChannel soc = ss.accept();
	  soc.close();
	}
      } catch (Exception e) {
	e.printStackTrace();
      }
    }
  }
}


---------- END SOURCE ----------

FREQUENCY : rarely
Comments
[jdk8u-fix-request] Approval Request from ktakakuri This fix adds the preClose check appropriately. The test added in this patch do not work as is in 8u, so I have made some modifications. Testing: jdk/com/sun/nio/sctp on Linux x86_64
03-04-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk8u-dev/pull/427 Date: 2024-01-24 12:14:25 +0000
24-01-2024

[jdk11u-fix-request] Approval Request from Tabata Daishi This fix adds the preClose check appropriately. The tests added in this patch do not work as is in 11u, so I have made some modifications. Testing: I tested jdk/com/sun/nio/sctp on Linux, which might be affected by this patch.
08-12-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk11u-dev/pull/2249 Date: 2023-11-01 06:27:41 +0000
01-11-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk17u-dev/pull/1235 Date: 2023-04-05 05:42:51 +0000
05-04-2023

Fix Request(17u) The patch applies cleanly to 17u. There is no risk because this fix adds the preClose check appropriately. Testing: I tested tier1 and attached test on RHEL7.9 manually.
05-04-2023

From the submitter: I verified the fix. Latest JDK 18 works fine.
13-10-2021

Requested the submitter verify the fix by downloading the latest version of JDK 18 from https://jdk.java.net/18/
12-10-2021

Changeset: d91e227a Author: Masanori Yano <myano@openjdk.org> Committer: Daniel Fuchs <dfuchs@openjdk.org> Date: 2021-09-24 11:17:26 +0000 URL: https://git.openjdk.java.net/jdk/commit/d91e227abb94953129adc297fbd456c55bb2ae10
24-09-2021

Moving this issue to java.net, only because this is where SCTP issues have been tracked to date. It would be useful to convert the reproducer to use ServerSocketChannel/SocketChannel to verify that the issue does not exist with these channel implementations. As regards the SCTP channel implementations then they should be overhauled at some point to re-align their implementation with the SSC/SC channel implementations as these have changed significantly in recent releases (esp. in the area of closing and async close where were historically the most problematic and complex areas of the implementation).
31-01-2020

Tested with JDK 14ea on Oracle Linux: [root@localhost Documents]# jdk-14/bin/java -version java version "14-ea" 2020-03-17 Java(TM) SE Runtime Environment (build 14-ea+28-1366) Java HotSpot(TM) 64-Bit Server VM (build 14-ea+28-1366, mixed mode, sharing) [root@localhost ~]# lsof -U -a -p 9236 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 9236 root 4u unix 0xffff9c25c7d68400 0t0 80034 socket java 9236 root 18u unix 0xffff9c25c7d68400 0t0 80034 socket [root@localhost ~]# lsof -U -a -p 9236 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 9236 root 4u unix 0xffff9c25c7d68400 0t0 80034 socket java 9236 root 18u unix 0xffff9c25c7d68400 0t0 80034 socket [root@localhost ~]# lsof -U -a -p 9236 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 9236 root 4u unix 0xffff9c25c7d68400 0t0 80034 socket java 9236 root 18u unix 0xffff9c25c7d68400 0t0 80034 socket [root@localhost ~]# lsof -U -a -p 9236 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 9236 root 4u unix 0xffff9c25c7d68400 0t0 80034 socket java 9236 root 18u unix 0xffff9c25c7d68400 0t0 80034 socket [root@localhost ~]# lsof -U -a -p 9236 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 9236 root 4u unix 0xffff9c25c7d68400 0t0 80034 socket java 9236 root 18u unix 0xffff9c25c7d68400 0t0 80034 socket [root@localhost ~]# lsof -U -a -p 9236 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 9236 root 4u unix 0xffff9c25c7d68400 0t0 80034 socket java 9236 root 18u unix 0xffff9c25c7d68400 0t0 80034 socket java 9236 root 19u unix 0xffff9c25c7d68400 0t0 80034 socket [root@localhost ~]# lsof -U -a -p 9236 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 9236 root 4u unix 0xffff9c25c7d68400 0t0 80034 socket java 9236 root 18u unix 0xffff9c25c7d68400 0t0 80034 socket java 9236 root 19u unix 0xffff9c25c7d68400 0t0 80034 socket [root@localhost ~]# lsof -U -a -p 9236 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 9236 root 4u unix 0xffff9c25c7d68400 0t0 80034 socket java 9236 root 18u unix 0xffff9c25c7d68400 0t0 80034 socket java 9236 root 19u unix 0xffff9c25c7d68400 0t0 80034 socket
31-01-2020