# HG changeset patch # User vtewari # Date 1510562016 -19800 # Node ID fbfe06b70e16bbd2447a4160422e277939c582bb # Parent 259dffd8dabce93953e8f0fe2e64931610af4d92 8145635: Add TCP_QUICKACK socket option Reviewed-by: chegar, rriggs, clanger diff -r 259dffd8dabc -r fbfe06b70e16 make/lib/Lib-jdk.net.gmk --- a/make/lib/Lib-jdk.net.gmk Fri Nov 10 03:27:43 2017 +0000 +++ b/make/lib/Lib-jdk.net.gmk Mon Nov 13 14:03:36 2017 +0530 @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ SRC := $(TOPDIR)/src/jdk.net/solaris/native/libextnet, \ OPTIMIZATION := LOW, \ CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/jdk.net, \ - MAPFILE := $(TOPDIR)/make/mapfiles/libextnet/mapfile-vers, \ + MAPFILE := $(TOPDIR)/make/mapfiles/libextnet/mapfile-solaris, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ LIBS := -lsocket -lc -ljava, \ @@ -48,4 +48,25 @@ endif +ifeq ($(OPENJDK_TARGET_OS), linux) + + $(eval $(call SetupNativeCompilation, BUILD_LIBEXTNET, \ + LIBRARY := extnet, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(TOPDIR)/src/jdk.net/linux/native/libextnet, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/jdk.net, \ + MAPFILE := $(TOPDIR)/make/mapfiles/libextnet/mapfile-linux, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LIBS := -ljvm -ljava -lc, \ + OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libextnet, \ + )) + + $(BUILD_LIBEXTNET): $(call FindLib, java.base, java) + + TARGETS += $(BUILD_LIBEXTNET) +endif + + ################################################################################ diff -r 259dffd8dabc -r fbfe06b70e16 make/mapfiles/libextnet/mapfile-linux --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/mapfiles/libextnet/mapfile-linux Mon Nov 13 14:03:36 2017 +0530 @@ -0,0 +1,33 @@ +# +# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +SUNWprivate_1.1 { + global: + Java_jdk_net_LinuxSocketOptions_setQuickAck0; + Java_jdk_net_LinuxSocketOptions_getQuickAck0; + Java_jdk_net_LinuxSocketOptions_quickAckSupported0; + local: + *; +}; diff -r 259dffd8dabc -r fbfe06b70e16 make/mapfiles/libextnet/mapfile-solaris --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/mapfiles/libextnet/mapfile-solaris Mon Nov 13 14:03:36 2017 +0530 @@ -0,0 +1,34 @@ +# +# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +SUNWprivate_1.1 { + global: + Java_jdk_net_SolarisSocketOptions_init; + Java_jdk_net_SolarisSocketOptions_setFlowOption; + Java_jdk_net_SolarisSocketOptions_getFlowOption; + Java_jdk_net_SolarisSocketOptions_flowSupported; + local: + *; +}; diff -r 259dffd8dabc -r fbfe06b70e16 make/mapfiles/libextnet/mapfile-vers --- a/make/mapfiles/libextnet/mapfile-vers Fri Nov 10 03:27:43 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -# -# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -SUNWprivate_1.1 { - global: - Java_jdk_net_SolarisSocketOptions_init; - Java_jdk_net_SolarisSocketOptions_setFlowOption; - Java_jdk_net_SolarisSocketOptions_getFlowOption; - Java_jdk_net_SolarisSocketOptions_flowSupported; - local: - *; -}; diff -r 259dffd8dabc -r fbfe06b70e16 src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java --- a/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java Fri Nov 10 03:27:43 2017 +0000 +++ b/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java Mon Nov 13 14:03:36 2017 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,10 +85,18 @@ protected Set> supportedOptions() { HashSet> options = new HashSet<>(super.supportedOptions()); - options.addAll(extendedOptions.options()); + addExtSocketOptions(extendedOptions.options(), options); return options; } + private void addExtSocketOptions(Set> extOptions, + Set> options) { + // TCP_QUICKACK is applicable for TCP Sockets only. + extOptions.stream() + .filter((option) -> !option.name().equals("TCP_QUICKACK")) + .forEach((option) -> options.add(option)); + } + protected void socketSetOption(int opt, Object val) throws SocketException { if (opt == SocketOptions.SO_REUSEPORT && !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) { diff -r 259dffd8dabc -r fbfe06b70e16 src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java Mon Nov 13 14:03:36 2017 +0530 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.net; + +import java.net.SocketException; +import java.security.AccessController; +import java.security.PrivilegedAction; +import jdk.net.ExtendedSocketOptions.PlatformSocketOptions; + +class LinuxSocketOptions extends PlatformSocketOptions { + + public LinuxSocketOptions() { + } + + @Override + void setQuickAck(int fd, boolean on) throws SocketException { + setQuickAck0(fd, on); + } + + @Override + boolean getQuickAck(int fd) throws SocketException { + return getQuickAck0(fd); + } + + @Override + public boolean quickAckSupported() { + return quickAckSupported0(); + } + + native static private void setQuickAck0(int fd, boolean on) throws SocketException; + + native static private boolean getQuickAck0(int fd) throws SocketException; + + native static private boolean quickAckSupported0(); + + static { + AccessController.doPrivileged((PrivilegedAction) () -> { + System.loadLibrary("extnet"); + return null; + }); + } +} diff -r 259dffd8dabc -r fbfe06b70e16 src/jdk.net/linux/native/libextnet/LinuxSocketOptions.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.net/linux/native/libextnet/LinuxSocketOptions.c Mon Nov 13 14:03:36 2017 +0530 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +#include +#include +#include +#include + +#include +#include +#include "jni_util.h" + +/* + * Class: jdk_net_LinuxSocketOptions + * Method: setQuickAck + * Signature: (II)V + */ +JNIEXPORT void JNICALL Java_jdk_net_LinuxSocketOptions_setQuickAck0 +(JNIEnv *env, jobject unused, jint fd, jboolean on) { + int optval; + int rv; + optval = (on ? 1 : 0); + rv = setsockopt(fd, SOL_SOCKET, TCP_QUICKACK, &optval, sizeof (optval)); + if (rv < 0) { + if (errno == ENOPROTOOPT) { + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); + } else { + JNU_ThrowByNameWithLastError(env, "java/net/SocketException", + "set option TCP_QUICKACK failed"); + } + } +} + +/* + * Class: jdk_net_LinuxSocketOptions + * Method: getQuickAck + * Signature: (I)Z; + */ +JNIEXPORT jboolean JNICALL Java_jdk_net_LinuxSocketOptions_getQuickAck0 +(JNIEnv *env, jobject unused, jint fd) { + int on; + socklen_t sz = sizeof (on); + int rv = getsockopt(fd, SOL_SOCKET, TCP_QUICKACK, &on, &sz); + if (rv < 0) { + if (errno == ENOPROTOOPT) { + JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", + "unsupported socket option"); + } else { + JNU_ThrowByNameWithLastError(env, "java/net/SocketException", + "get option TCP_QUICKACK failed"); + } + } + return on != 0; +} + +/* + * Class: jdk_net_LinuxSocketOptions + * Method: quickAckSupported + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_jdk_net_LinuxSocketOptions_quickAckSupported0 +(JNIEnv *env, jobject unused) { + int one = 1; + int rv, s; + s = socket(PF_INET, SOCK_STREAM, 0); + if (s < 0) { + return JNI_FALSE; + } + rv = setsockopt(s, SOL_SOCKET, TCP_QUICKACK, (void *) &one, sizeof (one)); + if (rv != 0 && errno == ENOPROTOOPT) { + rv = JNI_FALSE; + } else { + rv = JNI_TRUE; + } + close(s); + return rv; +} diff -r 259dffd8dabc -r fbfe06b70e16 src/jdk.net/share/classes/jdk/net/ExtendedSocketOptions.java --- a/src/jdk.net/share/classes/jdk/net/ExtendedSocketOptions.java Fri Nov 10 03:27:43 2017 +0000 +++ b/src/jdk.net/share/classes/jdk/net/ExtendedSocketOptions.java Mon Nov 13 14:03:36 2017 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,20 +67,53 @@ public static final SocketOption SO_FLOW_SLA = new ExtSocketOption("SO_FLOW_SLA", SocketFlow.class); + /** + * Disable Delayed Acknowledgements. + * + *

+ * This socket option can be used to reduce or disable delayed + * acknowledgments (ACKs). When {@code TCP_QUICKACK} is enabled, ACKs are + * sent immediately, rather than delayed if needed in accordance to normal + * TCP operation. This option is not permanent, it only enables a switch to + * or from {@code TCP_QUICKACK} mode. Subsequent operations of the TCP + * protocol will once again disable/enable {@code TCP_QUICKACK} mode + * depending on internal protocol processing and factors such as delayed ACK + * timeouts occurring and data transfer, therefore this option needs to be + * set with {@code setOption} after each operation of TCP on a given socket. + * + *

+ * The value of this socket option is a {@code Boolean} that represents + * whether the option is enabled or disabled. The socket option is specific + * to stream-oriented sockets using the TCP/IP protocol. The exact semantics + * of this socket option are socket type and system dependent. + * + * @since 10 + */ + public static final SocketOption TCP_QUICKACK = + new ExtSocketOption("TCP_QUICKACK", Boolean.class); private static final PlatformSocketOptions platformSocketOptions = PlatformSocketOptions.get(); private static final boolean flowSupported = platformSocketOptions.flowSupported(); + private static final boolean quickAckSupported = + platformSocketOptions.quickAckSupported(); private static final Set> extendedOptions = options(); static Set> options() { - if (flowSupported) - return Set.of(SO_FLOW_SLA); - else + if (flowSupported) { + if (quickAckSupported) { + return Set.of(SO_FLOW_SLA, TCP_QUICKACK); + } else { + return Set.of(SO_FLOW_SLA); + } + } else if (quickAckSupported) { + return Set.of(TCP_QUICKACK); + } else { return Collections.>emptySet(); + } } static { @@ -105,6 +138,8 @@ assert flowSupported; SocketFlow flow = checkValueType(value, option.type()); setFlowOption(fd, flow); + } else if (option == TCP_QUICKACK) { + setQuickAckOption(fd, (boolean) value); } else { throw new InternalError("Unexpected option " + option); } @@ -127,6 +162,8 @@ SocketFlow flow = SocketFlow.create(); getFlowOption(fd, flow); return flow; + } else if (option == TCP_QUICKACK) { + return getQuickAckOption(fd); } else { throw new InternalError("Unexpected option " + option); } @@ -156,12 +193,21 @@ } private static void getFlowOption(FileDescriptor fd, SocketFlow f) - throws SocketException - { + throws SocketException { int status = platformSocketOptions.getFlowOption(fdAccess.get(fd), f); f.status(status); // augment the given flow with the status } + private static void setQuickAckOption(FileDescriptor fd, boolean enable) + throws SocketException { + platformSocketOptions.setQuickAck(fdAccess.get(fd), enable); + } + + private static Object getQuickAckOption(FileDescriptor fd) + throws SocketException { + return platformSocketOptions.getQuickAck(fdAccess.get(fd)); + } + static class PlatformSocketOptions { protected PlatformSocketOptions() {} @@ -184,9 +230,13 @@ return System.getProperty("os.name"); } }); - if ("SunOS".equals(osname)) + if ("SunOS".equals(osname)) { return newInstance("jdk.net.SolarisSocketOptions"); - return new PlatformSocketOptions(); + } else if ("Linux".equals(osname)) { + return newInstance("jdk.net.LinuxSocketOptions"); + } else { + return new PlatformSocketOptions(); + } } private static final PlatformSocketOptions instance = create(); @@ -208,5 +258,17 @@ boolean flowSupported() { return false; } + + void setQuickAck(int fd, boolean on) throws SocketException { + throw new UnsupportedOperationException("unsupported TCP_QUICKACK option"); + } + + boolean getQuickAck(int fd) throws SocketException { + throw new UnsupportedOperationException("unsupported TCP_QUICKACK option"); + } + + boolean quickAckSupported() { + return false; + } } } diff -r 259dffd8dabc -r fbfe06b70e16 src/jdk.net/share/classes/jdk/net/Sockets.java --- a/src/jdk.net/share/classes/jdk/net/Sockets.java Fri Nov 10 03:27:43 2017 +0000 +++ b/src/jdk.net/share/classes/jdk/net/Sockets.java Mon Nov 13 14:03:36 2017 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -279,6 +279,9 @@ if (flowsupported) { set.add(ExtendedSocketOptions.SO_FLOW_SLA); } + if (QuickAck.available) { + set.add(ExtendedSocketOptions.TCP_QUICKACK); + } set = Collections.unmodifiableSet(set); options.put(Socket.class, set); @@ -290,6 +293,9 @@ if (reuseportsupported) { set.add(StandardSocketOptions.SO_REUSEPORT); } + if (QuickAck.available) { + set.add(ExtendedSocketOptions.TCP_QUICKACK); + } set.add(StandardSocketOptions.IP_TOS); set = Collections.unmodifiableSet(set); options.put(ServerSocket.class, set); @@ -331,4 +337,17 @@ return Collections.unmodifiableMap(options); } + + /** + * Tells whether TCP_QUICKACK is supported. + */ + static class QuickAck { + + static final boolean available; + + static { + Set> s = new Socket().supportedOptions(); + available = s.contains(ExtendedSocketOptions.TCP_QUICKACK); + } + } } diff -r 259dffd8dabc -r fbfe06b70e16 test/jdk/jdk/net/Sockets/QuickAckTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/jdk/net/Sockets/QuickAckTest.java Mon Nov 13 14:03:36 2017 +0530 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + /* + * @test + * @bug 8145635 + * @summary Add TCP_QUICKACK socket option + * @modules jdk.net + * @run main QuickAckTest + */ +import java.io.IOException; +import java.net.DatagramSocket; +import java.net.MulticastSocket; +import java.net.ServerSocket; +import java.net.Socket; +import jdk.net.ExtendedSocketOptions; +import jdk.net.Sockets; + +public class QuickAckTest { + + private static final String LOCAL_HOST = "127.0.0.1"; + + public static void main(String args[]) throws IOException { + + try (ServerSocket ss = new ServerSocket(0); + Socket s = new Socket(LOCAL_HOST, ss.getLocalPort()); + DatagramSocket ds = new DatagramSocket(0); + MulticastSocket mc = new MulticastSocket(0)) { + + if (ss.supportedOptions().contains(ExtendedSocketOptions.TCP_QUICKACK)) { + Sockets.setOption(ss, ExtendedSocketOptions.TCP_QUICKACK, true); + if (!ss.getOption(ExtendedSocketOptions.TCP_QUICKACK)) { + throw new RuntimeException("Test failed, TCP_QUICKACK should" + + " have been set"); + } + } + if (s.supportedOptions().contains(ExtendedSocketOptions.TCP_QUICKACK)) { + Sockets.setOption(s, ExtendedSocketOptions.TCP_QUICKACK, true); + if (!s.getOption(ExtendedSocketOptions.TCP_QUICKACK)) { + throw new RuntimeException("Test failed, TCP_QUICKACK should" + + " have been set"); + } + } + if (ds.supportedOptions().contains(ExtendedSocketOptions.TCP_QUICKACK)) { + throw new RuntimeException("Test failed, TCP_QUICKACK is applicable" + + " for TCP Sockets only."); + } + if (mc.supportedOptions().contains(ExtendedSocketOptions.TCP_QUICKACK)) { + throw new RuntimeException("Test failed, TCP_QUICKACK is applicable" + + " for TCP Sockets only"); + } + } + } +}