undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,161 @@
/*
* Copyright (c) 2001, 2021, 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 4507501
* @library /test/lib
* @summary Test various methods that should throw IAE when passed improper
* SocketAddress
* @run main AddressTest
* @run main/othervm -Djava.net.preferIPv4Stack=true AddressTest
*/
import java.net.*;
import jdk.test.lib.net.IPSupport;
public class AddressTest {
class MySocketAddress extends SocketAddress {
public MySocketAddress() {
}
}
public AddressTest() throws Exception {
SocketAddress addr = new MySocketAddress();
Socket soc = new Socket();
ServerSocket serv = new ServerSocket();
DatagramSocket ds = new DatagramSocket((SocketAddress)null);
DatagramPacket pac = new DatagramPacket(new byte[20], 20);
MulticastSocket mul = new MulticastSocket((SocketAddress) null);
boolean ok = false;
try {
soc.bind(addr);
} catch (IllegalArgumentException e) {
ok = true;
} catch (Exception e2) {
}
if (!ok)
throw new RuntimeException("Socket.bind should throw IllegalArgumentException!");
ok = false;
soc.close();
soc = new Socket();
try {
soc.connect(addr, 100);
} catch (IllegalArgumentException e) {
ok = true;
} catch (Exception e2) {
}
if (!ok)
throw new RuntimeException("Socket.connect should throw IllegalArgumentException!");
ok = false;
try {
serv.bind(addr);
} catch (IllegalArgumentException e) {
ok = true;
} catch (Exception e2) {
}
if (!ok)
throw new RuntimeException("ServerSocket.bind should throw IllegalArgumentException!");
ok = false;
try {
pac.setSocketAddress(addr);
} catch (IllegalArgumentException e) {
ok = true;
} catch (Exception e2) {
}
if (!ok)
throw new RuntimeException("DatagramPacket.setSocketAddress should throw IllegalArgumentException");
ok = false;
try {
ds.bind(addr);
} catch (IllegalArgumentException e) {
ok = true;
} catch (Exception e2) {
}
if (!ok)
throw new RuntimeException("DatagramSocket.bind should throw IllegalArgumentException");
ok = false;
try {
ds.connect(addr);
} catch (IllegalArgumentException e) {
ok = true;
} catch (Exception e2) {
}
if (!ok)
throw new RuntimeException("DatagramSocket.connect should throw IllegalArgumentException");
ok = false;
try {
mul.bind(addr);
} catch (IllegalArgumentException e) {
ok = true;
} catch (Exception e2) {
}
if (!ok)
throw new RuntimeException("MulticastSocket.bind should throw IllegalArgumentException");
ok = false;
mul.close();
mul = new MulticastSocket(new InetSocketAddress(0));
try {
mul.joinGroup(addr, null);
} catch (IllegalArgumentException e) {
ok = true;
} catch (Exception e2) {
}
if (!ok)
throw new RuntimeException("MulticastSocket.joinGroup should throw IllegalArgumentException");
ok = false;
try {
mul.leaveGroup(addr, null);
} catch (IllegalArgumentException e) {
ok = true;
} catch (Exception e2) {
}
if (!ok)
throw new RuntimeException("MulticastSocket.leaveGroup should throw IllegalArgumentException");
}
public static void main(String[] args) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
new AddressTest();
}
}

View file

@ -0,0 +1,151 @@
/*
* Copyright (c) 2019, 2025, 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
* @requires (os.family == "linux" | os.family == "mac")
* @summary Test shutdownInput/shutdownOutput with threads blocked in read/write
* @run junit AsyncShutdown
*/
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.*;
class AsyncShutdown {
@ParameterizedTest
@ValueSource(booleans = { false, true })
void testShutdownInput(boolean timed) throws IOException {
withConnection((s1, s2) -> {
InputStream in = s1.getInputStream();
scheduleShutdownInput(s1, 2000);
if (timed) {
s1.setSoTimeout(30*1000);
}
assertEquals(-1, in.read());
assertEquals(0, in.available());
});
}
@Test
void testShutdownOutput1() throws IOException {
withConnection((s1, s2) -> {
OutputStream out = s1.getOutputStream();
scheduleShutdownOutput(s1, 2000);
byte[] data = new byte[128*1024];
try {
while (true) {
out.write(data);
}
} catch (IOException expected) { }
});
}
@Test
void testShutdownOutput2() throws IOException {
withConnection((s1, s2) -> {
s1.setSoTimeout(100);
try {
s1.getInputStream().read();
fail();
} catch (SocketTimeoutException e) { }
OutputStream out = s1.getOutputStream();
scheduleShutdownOutput(s1, 2000);
byte[] data = new byte[128*1024];
try {
while (true) {
out.write(data);
}
} catch (IOException expected) { }
});
}
static void scheduleShutdownInput(Socket s, long delay) {
schedule(() -> {
try {
s.shutdownInput();
} catch (IOException ioe) { }
}, delay);
}
static void scheduleShutdownOutput(Socket s, long delay) {
schedule(() -> {
try {
s.shutdownOutput();
} catch (IOException ioe) { }
}, delay);
}
static void schedule(Runnable task, long delay) {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
try {
executor.schedule(task, delay, TimeUnit.MILLISECONDS);
} finally {
executor.shutdown();
}
}
interface ThrowingBiConsumer<T, U> {
void accept(T t, U u) throws IOException;
}
static void withConnection(ThrowingBiConsumer<Socket, Socket> consumer)
throws IOException
{
Socket s1 = null;
Socket s2 = null;
try (ServerSocket ss = createBoundServer()) {
s1 = new Socket();
s1.connect(ss.getLocalSocketAddress());
s2 = ss.accept();
consumer.accept(s1, s2);
} finally {
if (s1 != null) s1.close();
if (s2 != null) s2.close();
}
}
static ServerSocket createBoundServer() throws IOException {
ServerSocket ss = new ServerSocket();
InetAddress loopback = InetAddress.getLoopbackAddress();
InetSocketAddress address = new InetSocketAddress(loopback, 0);
ss.bind(address);
return ss;
}
}

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2012, 2019, 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 6210227
* @library /test/lib
* @summary REGRESSION: Socket.getLocalAddress() returns address of 0.0.0.0 on outbound TCP.
* This test requires binding to the wildcard address.
* @run main B6210227
* @run main/othervm -Djava.net.preferIPv4Stack=true B6210227
* @run main/othervm -Djava.net.preferIPv6Addresses=true B6210227
*/
import java.util.*;
import java.net.*;
import java.util.stream.IntStream;
import java.util.stream.Collectors;
import jdk.test.lib.net.IPSupport;
public class B6210227 {
public static void main(String[] args) throws Exception
{
IPSupport.throwSkippedExceptionIfNonOperational();
ServerSocket ss = new ServerSocket(0);
int port = ss.getLocalPort();
try {
InetSocketAddress isa = new InetSocketAddress(InetAddress.getLocalHost(), port);
Socket s = new Socket();
s.connect( isa, 1000 );
InetAddress iaLocal = s.getLocalAddress(); // if this comes back as 0.0.0.0 this would demonstrate issue
String sLocalHostname = iaLocal.getHostName();
byte[] address = iaLocal.getAddress();
if (isWildcard(address)) {
if (iaLocal instanceof Inet6Address) {
String msg = IntStream.range(0, address.length)
.mapToObj(i -> "0").collect(Collectors.joining(":"));
throw new RuntimeException(msg + " returned");
} else {
throw new RuntimeException ("0.0.0.0 returned");
}
}
System.out.println("local hostname is "+sLocalHostname );
} catch(Exception e) {
System.out.println("Exception happened");
throw e;
} finally {
ss.close();
}
}
private static boolean isWildcard(byte[] bytes) {
for (int i = 0; i < bytes.length ; i++) {
if (bytes[i] != 0) return false;
}
return true;
}
}

View file

@ -0,0 +1,185 @@
/*
* Copyright (c) 1998, 2025, 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 4091859 8189366
* @library /test/lib
* @summary Test Socket.getInputStream().available()
* @run main/timeout=480 CloseAvailable
* @run main/othervm/timeout=480 -Djava.net.preferIPv4Stack=true CloseAvailable
*/
import java.net.*;
import java.io.*;
import jdk.test.lib.net.IPSupport;
public class CloseAvailable {
public static void main(String[] args) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
testClose();
testEOF(true);
testEOF(false);
testIOEOnClosed(true);
testIOEOnClosed(false);
}
/*
* Verifies that the Socket.getInputStream().available() throws an IOException
* if invoked after the socket has been closed.
*/
static void testClose() throws IOException {
System.out.println("testClose");
final InetAddress addr = InetAddress.getLoopbackAddress();
final Socket acceptedSocket;
try (final ServerSocket ss = new ServerSocket(0, 0, addr)) {
System.out.println("created server socket: " + ss);
final int port = ss.getLocalPort();
// start a thread which initiates a socket connection to the server
Thread.ofPlatform().name("Close-Available-1")
.start(() -> {
try {
final Socket s = new Socket(addr, port);
System.out.println("created socket: " + s);
s.close();
System.out.println("closed socket: " + s);
} catch (Exception e) {
System.err.println("exception in " + Thread.currentThread().getName()
+ ": " + e);
e.printStackTrace();
}
});
// accept the client connect
acceptedSocket = ss.accept();
System.out.println(ss + " accepted connection " + acceptedSocket);
} // (intentionally) close the ServerSocket
final DataInputStream is = new DataInputStream(acceptedSocket.getInputStream());
is.close(); // close the inputstream and thus the underlying socket
System.out.println("closed inputstream of socket: " + acceptedSocket);
try {
final int av = is.available();
// available() was expected to fail but didn't
throw new AssertionError("Socket.getInputStream().available() was expected to fail on "
+ acceptedSocket + " but returned " + av);
} catch (IOException ex) {
// expected IOException
System.out.println("received the expected IOException: " + ex);
}
}
/*
* Verifies consistency of Socket.getInputStream().available() behaviour when EOF reached, both
* explicitly and implicitly.
*/
static void testEOF(boolean readUntilEOF) throws IOException {
System.out.println("testEOF, readUntilEOF: " + readUntilEOF);
final InetAddress addr = InetAddress.getLoopbackAddress();
try (final ServerSocket ss = new ServerSocket()) {
ss.bind(new InetSocketAddress(addr, 0), 0);
System.out.println("server socket bound: " + ss);
final int port = ss.getLocalPort();
try (final Socket s = new Socket(addr, port)) {
System.out.println("created socket: " + s);
s.getOutputStream().write(0x42);
s.shutdownOutput();
try (final Socket soc = ss.accept()) {
System.out.println("accepted socket: " + soc);
ss.close();
System.out.println("closed server socket: " + ss);
final InputStream is = soc.getInputStream();
int b = is.read();
assert b == 0x42 : "unexpected byte read: " + b;
assert !s.isClosed() : "socket " + s + " is unexpectedly closed";
if (readUntilEOF) {
b = is.read();
assert b == -1 : "unexpected number of bytes read: " + b;
}
int a;
for (int i = 0; i < 100; i++) {
a = is.available();
System.out.print(a + ", ");
if (a != 0) {
throw new RuntimeException("Unexpected non-zero available: " + a);
}
}
assert !s.isClosed() : "socket " + s + " is unexpectedly closed";
final int more = is.read();
assert more == -1 : "unexpected byte read: " + more;
}
}
}
System.out.println("\ncomplete");
}
/*
* Verifies IOException thrown by Socket.getInputStream().available(), on a closed input stream
* that may, or may not, have reached EOF prior to closure.
*/
static void testIOEOnClosed(boolean readUntilEOF) throws IOException {
System.out.println("testIOEOnClosed, readUntilEOF: " + readUntilEOF);
final InetAddress addr = InetAddress.getLoopbackAddress();
try (final ServerSocket ss = new ServerSocket()) {
ss.bind(new InetSocketAddress(addr, 0), 0);
System.out.println("server socket bound: " + ss);
final int port = ss.getLocalPort();
try (final Socket s = new Socket(addr, port)) {
System.out.println("created socket: " + s);
s.getOutputStream().write(0x43);
s.shutdownOutput();
try (final Socket soc = ss.accept()) {
System.out.println("accepted socket: " + soc);
ss.close();
System.out.println("closed server socket: " + ss);
final InputStream is = soc.getInputStream();
int b = is.read();
assert b == 0x43 : "unexpected byte read: " + b;
assert !s.isClosed() : "socket " + s + " is unexpectedly closed";
if (readUntilEOF) {
b = is.read();
assert b == -1 : "unexpected byte read: " + b;
}
is.close();
System.out.println("closed inputstream of socket: " + soc);
try {
b = is.available();
throw new RuntimeException("UNEXPECTED successful read: " + b);
} catch (IOException expected) {
System.out.println("caught expected IOException:" + expected);
}
}
}
}
System.out.println("\ncomplete");
}
}

View file

@ -0,0 +1,176 @@
/*
* Copyright (c) 2024, 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.
*/
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.StandardSocketOptions;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
import static org.junit.jupiter.api.Assertions.assertTrue;
/*
* @test
* @summary verifies that the APIs on java.net.Socket throw expected exceptions
* when invoked on a closed socket
* @run junit ClosedSocketTest
*/
public class ClosedSocketTest {
private static final InetAddress loopback = InetAddress.getLoopbackAddress();
private static final InetSocketAddress loopbackEphemeral = new InetSocketAddress(loopback, 0);
/**
* Verifies that various operations that specify to throw an IOException on a closed socket,
* do indeed throw it.
*/
@Test
public void testIOExceptionThrown() throws Exception {
try (final Socket s = new Socket()) {
// close and then invoke the operation on the socket
s.close();
assertTrue(s.isClosed(), "socket isn't closed");
assertThrows(IOException.class, () -> s.bind(loopbackEphemeral),
"bind() when already closed didn't throw IOException");
// connect() will never get to the stage of attempting
// a connection against this port
final int dummyPort = 12345;
assertThrows(IOException.class,
() -> s.connect(new InetSocketAddress(loopback, dummyPort)),
"connect() when already closed didn't throw IOException");
assertThrows(IOException.class,
() -> s.connect(new InetSocketAddress(loopback, dummyPort), 10),
"connect(SocketAddress, int) when already closed didn't throw IOException");
assertThrows(IOException.class,
() -> s.getOption(StandardSocketOptions.SO_RCVBUF),
"getOption() when already closed didn't throw IOException");
assertThrows(IOException.class,
s::getOutputStream,
"getOutputStream() when already closed didn't throw IOException");
assertThrows(IOException.class,
s::shutdownInput,
"shutdownInput() when already closed didn't throw IOException");
assertThrows(IOException.class,
s::shutdownOutput,
"shutdownOutput() when already closed didn't throw IOException");
}
}
/**
* Verifies that various operations that specify to throw a SocketOperation on a closed socket,
* do indeed throw it.
*/
@Test
public void testSocketExceptionThrown() throws Exception {
try (final Socket s = new Socket()) {
// close and then invoke the operations on the socket
s.close();
assertTrue(s.isClosed(), "socket isn't closed");
assertThrowsExactly(SocketException.class,
s::getKeepAlive,
"getKeepAlive() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
s::getOOBInline,
"getOOBInline() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
s::getReceiveBufferSize,
"getReceiveBufferSize() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
s::getReuseAddress,
"getReuseAddress() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
s::getSendBufferSize,
"getSendBufferSize() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
s::getSoLinger,
"getSoLinger() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
s::getSoTimeout,
"getSoTimeout() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
s::getTcpNoDelay,
"getTcpNoDelay() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
s::getTrafficClass,
"getTrafficClass() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
() -> s.setKeepAlive(false),
"setKeepAlive() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
() -> s.setOOBInline(false),
"setOOBInline() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
() -> s.setOption(StandardSocketOptions.SO_RCVBUF, 1024),
"setOption() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
() -> s.setReceiveBufferSize(1024),
"setReceiveBufferSize() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
() -> s.setReuseAddress(false),
"setReuseAddress() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
() -> s.setSendBufferSize(1024),
"setSendBufferSize() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
() -> s.setSoLinger(false, 0),
"setSoLinger() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
() -> s.setSoTimeout(1000),
"setSoTimeout() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
() -> s.setTcpNoDelay(false),
"setTcpNoDelay() when already closed didn't throw SocketException");
assertThrowsExactly(SocketException.class,
() -> s.setTrafficClass(123),
"setTrafficClass() when already closed didn't throw SocketException");
}
}
/**
* Verifies that various operations that aren't expected to throw an exception on a
* closed socket, complete normally.
*/
@Test
public void testNoExceptionThrown() throws Exception {
try (final Socket s = new Socket()) {
// close and then invoke various operation on the socket and don't expect an exception
s.close();
assertTrue(s.isClosed(), "socket isn't closed");
s.getInetAddress();
s.getLocalAddress();
s.getLocalPort();
s.getLocalSocketAddress();
s.getPort();
s.getRemoteSocketAddress();
s.isBound();
s.isConnected();
s.isInputShutdown();
s.isOutputShutdown();
s.supportedOptions();
}
}
}

View file

@ -0,0 +1,176 @@
/*
* Copyright (c) 2024, 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.
*/
import jdk.test.lib.Utils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.channels.SocketChannel;
import java.util.List;
import static java.net.InetAddress.getLoopbackAddress;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
/*
* @test
* @bug 8343791
* @summary verifies that `connect()` failures throw the expected exception and leave socket in the expected state
* @library /test/lib
* @run junit ConnectFailTest
*/
class ConnectFailTest {
// Implementation Note: Explicitly binding on the loopback address to avoid potential unstabilities.
private static final int DEAD_SERVER_PORT = 0xDEAD;
private static final InetSocketAddress REFUSING_SOCKET_ADDRESS = Utils.refusingEndpoint();
private static final InetSocketAddress UNRESOLVED_ADDRESS =
InetSocketAddress.createUnresolved("no.such.host", DEAD_SERVER_PORT);
@Test
void testUnresolvedAddress() {
assertTrue(UNRESOLVED_ADDRESS.isUnresolved());
}
/**
* Verifies that an unbound socket is closed when {@code connect()} fails.
*/
@ParameterizedTest
@MethodSource("sockets")
void testUnboundSocket(Socket socket) throws IOException {
try (socket) {
assertFalse(socket.isBound());
assertFalse(socket.isConnected());
assertThrows(IOException.class, () -> socket.connect(REFUSING_SOCKET_ADDRESS));
assertTrue(socket.isClosed());
}
}
/**
* Verifies that a bound socket is closed when {@code connect()} fails.
*/
@ParameterizedTest
@MethodSource("sockets")
void testBoundSocket(Socket socket) throws IOException {
try (socket) {
socket.bind(new InetSocketAddress(getLoopbackAddress(), 0));
assertTrue(socket.isBound());
assertFalse(socket.isConnected());
assertThrows(IOException.class, () -> socket.connect(REFUSING_SOCKET_ADDRESS));
assertTrue(socket.isClosed());
}
}
/**
* Verifies that a connected socket is not closed when {@code connect()} fails.
*/
@ParameterizedTest
@MethodSource("sockets")
void testConnectedSocket(Socket socket) throws Throwable {
try (socket; ServerSocket serverSocket = createEphemeralServerSocket()) {
socket.connect(serverSocket.getLocalSocketAddress());
try (Socket _ = serverSocket.accept()) {
assertTrue(socket.isBound());
assertTrue(socket.isConnected());
SocketException exception = assertThrows(
SocketException.class,
() -> socket.connect(REFUSING_SOCKET_ADDRESS));
assertEquals("Already connected", exception.getMessage());
assertFalse(socket.isClosed());
}
}
}
/**
* Verifies that an unbound socket is closed when {@code connect()} is invoked using an unresolved address.
*/
@ParameterizedTest
@MethodSource("sockets")
void testUnboundSocketWithUnresolvedAddress(Socket socket) throws IOException {
try (socket) {
assertFalse(socket.isBound());
assertFalse(socket.isConnected());
assertThrows(UnknownHostException.class, () -> socket.connect(UNRESOLVED_ADDRESS));
assertTrue(socket.isClosed());
}
}
/**
* Verifies that a bound socket is closed when {@code connect()} is invoked using an unresolved address.
*/
@ParameterizedTest
@MethodSource("sockets")
void testBoundSocketWithUnresolvedAddress(Socket socket) throws IOException {
try (socket) {
socket.bind(new InetSocketAddress(getLoopbackAddress(), 0));
assertTrue(socket.isBound());
assertFalse(socket.isConnected());
assertThrows(UnknownHostException.class, () -> socket.connect(UNRESOLVED_ADDRESS));
assertTrue(socket.isClosed());
}
}
/**
* Verifies that a connected socket is not closed when {@code connect()} is invoked using an unresolved address.
*/
@ParameterizedTest
@MethodSource("sockets")
void testConnectedSocketWithUnresolvedAddress(Socket socket) throws Throwable {
try (socket; ServerSocket serverSocket = createEphemeralServerSocket()) {
socket.connect(serverSocket.getLocalSocketAddress());
try (Socket _ = serverSocket.accept()) {
assertTrue(socket.isBound());
assertTrue(socket.isConnected());
assertThrows(IOException.class, () -> socket.connect(UNRESOLVED_ADDRESS));
assertFalse(socket.isClosed());
}
}
}
static List<Socket> sockets() throws Exception {
Socket socket = new Socket();
@SuppressWarnings("resource")
Socket channelSocket = SocketChannel.open().socket();
Socket noProxySocket = new Socket(Proxy.NO_PROXY);
return List.of(socket, channelSocket, noProxySocket);
}
private static ServerSocket createEphemeralServerSocket() throws IOException {
return new ServerSocket(0, 0, InetAddress.getLoopbackAddress());
}
}

View file

@ -0,0 +1,218 @@
/*
* Copyright (c) 2024, 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.
*/
import jdk.test.lib.Utils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.net.Authenticator;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import static java.net.InetAddress.getLoopbackAddress;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
/*
* @test
* @bug 8346017
* @summary Verifies the `connect()` behaviour of a SOCKS proxy socket. In particular, that passing a resolvable
* unresolved address doesn't throw an exception.
* @library /test/lib /java/net/Socks
* @build SocksServer
* @run junit ConnectSocksProxyTest
*/
class ConnectSocksProxyTest {
// Implementation Note: Explicitly binding on the loopback address to avoid potential unstabilities.
private static final int DEAD_SERVER_PORT = 0xDEAD;
private static final InetSocketAddress REFUSING_SOCKET_ADDRESS = Utils.refusingEndpoint();
private static final InetSocketAddress UNRESOLVED_ADDRESS =
InetSocketAddress.createUnresolved("no.such.host", DEAD_SERVER_PORT);
private static final String PROXY_AUTH_USERNAME = "foo";
private static final String PROXY_AUTH_PASSWORD = "bar";
private static SocksServer PROXY_SERVER;
private static Proxy PROXY;
@BeforeAll
static void initAuthenticator() {
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(PROXY_AUTH_USERNAME, PROXY_AUTH_PASSWORD.toCharArray());
}
});
}
@BeforeAll
static void initProxyServer() throws IOException {
PROXY_SERVER = new SocksServer(getLoopbackAddress(), 0, false);
PROXY_SERVER.addUser(PROXY_AUTH_USERNAME, PROXY_AUTH_PASSWORD);
PROXY_SERVER.start();
InetSocketAddress proxyAddress = new InetSocketAddress(getLoopbackAddress(), PROXY_SERVER.getPort());
PROXY = new Proxy(Proxy.Type.SOCKS, proxyAddress);
}
@AfterAll
static void stopProxyServer() {
PROXY_SERVER.close();
}
@Test
void testUnresolvedAddress() {
assertTrue(UNRESOLVED_ADDRESS.isUnresolved());
}
/**
* Verifies that an unbound socket is closed when {@code connect()} fails.
*/
@Test
void testUnboundSocket() throws IOException {
try (Socket socket = createProxiedSocket()) {
assertFalse(socket.isBound());
assertFalse(socket.isConnected());
assertThrows(IOException.class, () -> socket.connect(REFUSING_SOCKET_ADDRESS));
assertTrue(socket.isClosed());
}
}
/**
* Verifies that a bound socket is closed when {@code connect()} fails.
*/
@Test
void testBoundSocket() throws IOException {
try (Socket socket = createProxiedSocket()) {
socket.bind(new InetSocketAddress(getLoopbackAddress(), 0));
assertTrue(socket.isBound());
assertFalse(socket.isConnected());
assertThrows(IOException.class, () -> socket.connect(REFUSING_SOCKET_ADDRESS));
assertTrue(socket.isClosed());
}
}
/**
* Verifies that a connected socket is not closed when {@code connect()} fails.
*/
@Test
void testConnectedSocket() throws Throwable {
try (Socket socket = createProxiedSocket();
ServerSocket serverSocket = createEphemeralServerSocket()) {
socket.connect(serverSocket.getLocalSocketAddress());
try (Socket _ = serverSocket.accept()) {
assertTrue(socket.isBound());
assertTrue(socket.isConnected());
SocketException exception = assertThrows(
SocketException.class,
() -> socket.connect(REFUSING_SOCKET_ADDRESS));
assertEquals("Already connected", exception.getMessage());
assertFalse(socket.isClosed());
}
}
}
/**
* Delegates to {@link #testUnconnectedSocketWithUnresolvedAddress(boolean, Socket)} using an unbound socket.
*/
@Test
void testUnboundSocketWithUnresolvedAddress() throws IOException {
try (Socket socket = createProxiedSocket()) {
assertFalse(socket.isBound());
assertFalse(socket.isConnected());
testUnconnectedSocketWithUnresolvedAddress(false, socket);
}
}
/**
* Delegates to {@link #testUnconnectedSocketWithUnresolvedAddress(boolean, Socket)} using a bound socket.
*/
@Test
void testBoundSocketWithUnresolvedAddress() throws IOException {
try (Socket socket = createProxiedSocket()) {
socket.bind(new InetSocketAddress(getLoopbackAddress(), 0));
testUnconnectedSocketWithUnresolvedAddress(true, socket);
}
}
/**
* Verifies the behaviour of an unconnected socket when {@code connect()} is invoked using an unresolved address.
*/
private static void testUnconnectedSocketWithUnresolvedAddress(boolean bound, Socket socket) throws IOException {
assertEquals(bound, socket.isBound());
assertFalse(socket.isConnected());
try (ServerSocket serverSocket = createEphemeralServerSocket()) {
InetSocketAddress unresolvedAddress = InetSocketAddress.createUnresolved(
getLoopbackAddress().getHostAddress(),
serverSocket.getLocalPort());
socket.connect(unresolvedAddress);
try (Socket _ = serverSocket.accept()) {
assertTrue(socket.isBound());
assertTrue(socket.isConnected());
assertFalse(socket.isClosed());
}
}
}
/**
* Verifies that a connected socket is not closed when {@code connect()} is invoked using an unresolved address.
*/
@Test
void testConnectedSocketWithUnresolvedAddress() throws Throwable {
try (Socket socket = createProxiedSocket();
ServerSocket serverSocket = createEphemeralServerSocket()) {
socket.connect(serverSocket.getLocalSocketAddress());
try (Socket _ = serverSocket.accept()) {
assertTrue(socket.isBound());
assertTrue(socket.isConnected());
SocketException exception = assertThrows(
SocketException.class,
() -> socket.connect(UNRESOLVED_ADDRESS));
assertEquals("Already connected", exception.getMessage());
assertFalse(socket.isClosed());
}
}
}
private static Socket createProxiedSocket() {
return new Socket(PROXY);
}
private static ServerSocket createEphemeralServerSocket() throws IOException {
return new ServerSocket(0, 0, getLoopbackAddress());
}
}

View file

@ -0,0 +1,217 @@
/*
* Copyright (c) 2019, 2021, 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
* @run testng ConnectionReset
* @summary Test behavior of read and available when a connection is reset
*/
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@Test
public class ConnectionReset {
static final int REPEAT_COUNT = 5;
/**
* Tests available before read when there are no bytes to read
*/
public void testAvailableBeforeRead1() throws IOException {
System.out.println("testAvailableBeforeRead1");
withResetConnection(null, s -> {
InputStream in = s.getInputStream();
for (int i=0; i<REPEAT_COUNT; i++) {
int bytesAvailable = in.available();
System.out.format("available => %d%n", bytesAvailable);
assertTrue(bytesAvailable == 0);
try {
int bytesRead = in.read();
if (bytesRead == -1) {
System.out.println("read => EOF");
} else {
System.out.println("read => 1 byte");
}
assertTrue(false);
} catch (IOException ioe) {
System.out.format("read => %s (expected)%n", ioe);
}
}
});
}
/**
* Tests available before read when there are bytes to read
*/
public void testAvailableBeforeRead2() throws IOException {
System.out.println("testAvailableBeforeRead2");
byte[] data = { 1, 2, 3 };
withResetConnection(data, s -> {
InputStream in = s.getInputStream();
int remaining = data.length;
for (int i=0; i<REPEAT_COUNT; i++) {
int bytesAvailable = in.available();
System.out.format("available => %d%n", bytesAvailable);
assertTrue(bytesAvailable <= remaining);
try {
int bytesRead = in.read();
if (bytesRead == -1) {
System.out.println("read => EOF");
assertTrue(false);
} else {
System.out.println("read => 1 byte");
assertTrue(remaining > 0);
remaining--;
}
} catch (IOException ioe) {
System.out.format("read => %s%n", ioe);
remaining = 0;
}
}
});
}
/**
* Tests read before available when there are no bytes to read
*/
public void testReadBeforeAvailable1() throws IOException {
System.out.println("testReadBeforeAvailable1");
withResetConnection(null, s -> {
InputStream in = s.getInputStream();
for (int i=0; i<REPEAT_COUNT; i++) {
try {
int bytesRead = in.read();
if (bytesRead == -1) {
System.out.println("read => EOF");
} else {
System.out.println("read => 1 byte");
}
assertTrue(false);
} catch (IOException ioe) {
System.out.format("read => %s (expected)%n", ioe);
}
int bytesAvailable = in.available();
System.out.format("available => %d%n", bytesAvailable);
assertTrue(bytesAvailable == 0);
}
});
}
/**
* Tests read before available when there are bytes to read
*/
public void testReadBeforeAvailable2() throws IOException {
System.out.println("testReadBeforeAvailable2");
byte[] data = { 1, 2, 3 };
withResetConnection(data, s -> {
InputStream in = s.getInputStream();
int remaining = data.length;
for (int i=0; i<REPEAT_COUNT; i++) {
try {
int bytesRead = in.read();
if (bytesRead == -1) {
System.out.println("read => EOF");
assertTrue(false);
} else {
System.out.println("read => 1 byte");
assertTrue(remaining > 0);
remaining--;
}
} catch (IOException ioe) {
System.out.format("read => %s%n", ioe);
remaining = 0;
}
int bytesAvailable = in.available();
System.out.format("available => %d%n", bytesAvailable);
assertTrue(bytesAvailable <= remaining);
}
});
}
/**
* Tests available and read on a socket closed after connection reset
*/
public void testAfterClose() throws IOException {
System.out.println("testAfterClose");
withResetConnection(null, s -> {
InputStream in = s.getInputStream();
try {
in.read();
assertTrue(false);
} catch (IOException ioe) {
// expected
}
s.close();
try {
int bytesAvailable = in.available();
System.out.format("available => %d%n", bytesAvailable);
assertTrue(false);
} catch (IOException ioe) {
System.out.format("available => %s (expected)%n", ioe);
}
try {
int n = in.read();
System.out.format("read => %d%n", n);
assertTrue(false);
} catch (IOException ioe) {
System.out.format("read => %s (expected)%n", ioe);
}
});
}
interface ThrowingConsumer<T> {
void accept(T t) throws IOException;
}
/**
* Invokes a consumer with a Socket connected to a peer that has closed the
* connection with a "connection reset". The peer sends the given data bytes
* before closing (when data is not null).
*/
static void withResetConnection(byte[] data, ThrowingConsumer<Socket> consumer)
throws IOException
{
var loopback = InetAddress.getLoopbackAddress();
try (var listener = new ServerSocket()) {
listener.bind(new InetSocketAddress(loopback, 0));
try (var socket = new Socket()) {
socket.connect(listener.getLocalSocketAddress());
try (Socket peer = listener.accept()) {
if (data != null) {
peer.getOutputStream().write(data);
}
peer.setSoLinger(true, 0);
}
consumer.accept(socket);
}
}
}
}

View file

@ -0,0 +1,220 @@
/*
* Copyright (c) 2024, 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.
*/
import org.junit.jupiter.api.function.Executable;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketImpl;
import java.net.SocketImplFactory;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
/*
* @test
* @summary verifies that the socket is closed on constructor failures
* @modules java.base/java.net:+open
* @run junit CtorFailTest
*/
class CtorFailTest {
private static final VarHandle SOCKET_IMPL_FACTORY_HANDLE = createSocketImplFactoryHandle();
private static final int DEAD_SERVER_PORT = 0xDEAD;
private static VarHandle createSocketImplFactoryHandle() {
try {
Field field = Socket.class.getDeclaredField("factory");
field.setAccessible(true);
return MethodHandles
.privateLookupIn(Socket.class, MethodHandles.lookup())
.findStaticVarHandle(Socket.class, "factory", SocketImplFactory.class);
} catch (NoSuchFieldException | IllegalAccessException exception) {
throw new RuntimeException(exception);
}
}
private static void withSocketImplFactory(SocketImplFactory newFactory, Executable executable) throws Throwable {
SocketImplFactory oldFactory = (SocketImplFactory) SOCKET_IMPL_FACTORY_HANDLE.getAndSet(newFactory);
try {
executable.execute();
} finally {
SOCKET_IMPL_FACTORY_HANDLE.set(oldFactory);
}
}
@ParameterizedTest
@MethodSource("socketImpls")
@SuppressWarnings("resource")
void test(MockSocketImpl socketImpl) throws Throwable {
withSocketImplFactory(() -> socketImpl, () -> {
// Trigger the failure
Exception caughtException = assertThrows(Exception.class, () -> {
// Address and port are mostly ineffective.
// They just need to be _valid enough_ to reach to the point where both `SocketImpl#bind()` and `SocketImpl#connect()` are invoked.
// Failure will be triggered by the injected `SocketImpl`.
InetAddress serverAddress = InetAddress.getLoopbackAddress();
new Socket(serverAddress, DEAD_SERVER_PORT, null, 0);
});
// Run verifications
Exception expectedException = socketImpl.bindException != null
? socketImpl.bindException
: socketImpl.connectException;
assertSame(expectedException, caughtException);
assertEquals(1, socketImpl.closeInvocationCounter.get());
});
}
static List<MockSocketImpl> socketImpls() {
String exceptionMessage = "intentional test failure";
IOException checkedException = new IOException(exceptionMessage);
IllegalArgumentException uncheckedException = new IllegalArgumentException(exceptionMessage);
return List.of(
new MockSocketImpl(checkedException, null),
new MockSocketImpl(null, checkedException),
new MockSocketImpl(uncheckedException, null),
new MockSocketImpl(null, uncheckedException));
}
private static final class MockSocketImpl extends SocketImpl {
private final AtomicInteger closeInvocationCounter = new AtomicInteger(0);
private final Exception bindException;
private final Exception connectException;
private MockSocketImpl(Exception bindException, Exception connectException) {
this.bindException = bindException;
this.connectException = connectException;
}
@Override
protected void create(boolean stream) {
// Do nothing
}
@Override
protected void bind(InetAddress host, int port) throws IOException {
throwIfPresent(bindException);
}
@Override
protected void connect(SocketAddress address, int timeoutMillis) throws IOException {
throwIfPresent(connectException);
}
private void throwIfPresent(Exception exception) throws IOException {
if (exception != null) {
switch (exception) {
case IOException error -> throw error;
case RuntimeException error -> throw error;
default -> throw new IllegalStateException(
"unknown exception type: " + exception.getClass().getCanonicalName());
}
}
}
@Override
public String toString() {
record MockSocket(Exception bindException, Exception connectException, int closeInvocationCounter) {}
return new MockSocket(bindException, connectException, closeInvocationCounter.get()).toString();
}
// Rest of the `SocketImpl` methods should not be used, hence overriding them to throw `UOE`
@Override
protected void close() {
closeInvocationCounter.incrementAndGet();
}
@Override
protected void connect(String host, int port) {
throw new UnsupportedOperationException();
}
@Override
protected void connect(InetAddress address, int port) {
throw new UnsupportedOperationException();
}
@Override
protected void listen(int backlog) {
throw new UnsupportedOperationException();
}
@Override
protected void accept(SocketImpl impl) {
throw new UnsupportedOperationException();
}
@Override
protected InputStream getInputStream() {
throw new UnsupportedOperationException();
}
@Override
protected OutputStream getOutputStream() {
throw new UnsupportedOperationException();
}
@Override
protected int available() {
throw new UnsupportedOperationException();
}
@Override
protected void sendUrgentData(int data) {
throw new UnsupportedOperationException();
}
@Override
public void setOption(int optID, Object value) {
throw new UnsupportedOperationException();
}
@Override
public Object getOption(int optID) {
throw new UnsupportedOperationException();
}
}
}

View file

@ -0,0 +1,243 @@
/*
* Copyright (c) 1999, 2025, 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 4176738
* @library /test/lib
* @summary Make sure a deadlock situation
* would not occur
* @run main DeadlockTest
* @run main/othervm -Djava.net.preferIPv4Stack=true DeadlockTest
*/
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import jdk.test.lib.net.IPSupport;
public class DeadlockTest {
public static void main(String[] argv) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
ServerSocket ss = new ServerSocket(0, 0, InetAddress.getLoopbackAddress());
Socket clientSocket = new Socket();
try {
// Start the server thread
Thread s1 = new Thread(new ServerThread(ss));
s1.start();
// Start the client thread
ClientThread ct = new ClientThread(clientSocket, ss.getLocalPort());
Thread c1 = new Thread(ct);
c1.start();
// Wait for the client thread to finish.
// If it doesn't finish then it's a sign of a deadlock
c1.join();
} finally {
ss.close();
clientSocket.close();
}
}
}
class ServerThread implements Runnable {
private static boolean dbg = false;
ObjectInputStream in;
ObjectOutputStream out;
ServerSocket server;
Socket sock;
public ServerThread(ServerSocket serverSocket) throws Exception {
this.server = serverSocket;
}
public void ping(int cnt) {
Message.write(out, new PingMessage(cnt));
}
private int cnt = 1;
public void run() {
try {
if (Thread.currentThread().getName().startsWith("child") == false) {
sock = server.accept();
new Thread(this, "child").start();
out = new ObjectOutputStream(sock.getOutputStream());
out.flush();
if (dbg) System.out.println("*** ping0 ***");
ping(0);
if (dbg) System.out.println("*** ping1 ***");
ping(1);
if (dbg) System.out.println("*** ping2 ***");
ping(2);
if (dbg) System.out.println("*** ping3 ***");
ping(3);
if (dbg) System.out.println("*** ping4 ***");
ping(4);
if (dbg) System.out.println("*** end ***");
}
} catch (Throwable e) {
System.out.println(e);
// If anything goes wrong, just quit.
}
if (Thread.currentThread().getName().startsWith("child")) {
try {
in = new ObjectInputStream(sock.getInputStream());
while (true) {
if (dbg) System.out.println("read " + cnt);
Message msg = (Message) in.readObject();
if (dbg) System.out.println("read done " + cnt++);
switch (msg.code) {
case Message.PING: {
if (true) System.out.println("ping recv'ed");
} break;
}
}
} catch (Throwable e) {
// If anything goes wrong, just quit. }
}
}
}
}
class ClientThread implements Runnable {
ObjectInputStream in;
ObjectOutputStream out;
Socket sock;
public ClientThread(Socket sock, int serverPort) throws Exception {
try {
System.out.println("About to connect the client socket");
this.sock = sock;
this.sock.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), serverPort));
System.out.println("connected");
out = new ObjectOutputStream(sock.getOutputStream());
out.flush();
} catch (Throwable e) {
System.out.println("client failed with: " + e);
e.printStackTrace();
throw new Exception("Unexpected exception");
}
}
private int cnt = 1;
public void run() {
try {
in = new ObjectInputStream(sock.getInputStream());
int count = 0;
while (true) {
System.out.println("read " + cnt);
Message msg = (Message) in.readObject();
System.out.println("read done " + cnt++);
switch (msg.code) {
case Message.PING: {
System.out.println("ping recv'ed");
count++;
} break;
}
if (count == 5) {
sock.close();
break;
}
}
} catch (IOException ioe) {
} catch (Throwable e) {
// If anything went wrong, just quit
}
}
}
class Message implements java.io.Serializable {
static final int UNKNOWN = 0;
static final int PING = 1;
protected int code;
public Message() { this.code = UNKNOWN; }
public Message(int code) { this.code = code; }
private static int cnt = 1;
public static void write(ObjectOutput out, Message msg) {
try {
System.out.println("write message " + cnt);
out.writeObject(msg);
System.out.println("flush message");
out.flush();
System.out.println("write message done " + cnt++);
} catch (IOException ioe) {
// Ignore the exception
System.out.println(ioe);
}
}
}
class PingMessage extends Message implements java.io.Serializable {
public PingMessage() {
code = Message.PING;
}
public PingMessage(int cnt)
{
code = Message.PING;
this.cnt = cnt;
data = new int[50000];
}
int cnt;
int[] data;
}

View file

@ -0,0 +1,142 @@
/*
* Copyright (c) 2018, 2023, 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
* @library /test/lib
* @build jdk.test.lib.Utils
* @bug 8204233
* @summary Add configurable option for enhanced socket IOException messages
* @run main/othervm
* ExceptionText
* WITHOUT_Enhanced_Text
* @run main/othervm
* -Djdk.includeInExceptions=
* ExceptionText
* WITHOUT_Enhanced_Text
* @run main/othervm
* -Djdk.includeInExceptions=somethingElse
* ExceptionText
* WITHOUT_Enhanced_Text
* @run main/othervm
* -Djdk.includeInExceptions=blah,blah,blah,
* ExceptionText
* WITHOUT_Enhanced_Text
* @run main/othervm
* -Djdk.includeInExceptions=hostInfo
* ExceptionText
* expectEnhancedText
* @run main/othervm
* -Djdk.includeInExceptions=foo,hostinfo,bar
* ExceptionText
* expectEnhancedText
* @run main/othervm
* -Djdk.includeInExceptions=",HOSTINFO,"
* ExceptionText
* expectEnhancedText
*/
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ExecutionException;
import jdk.test.lib.Utils;
public class ExceptionText {
enum TestTarget {SOCKET, CHANNEL, ASYNC_CHANNEL};
public static void main(String args[]) throws Exception {
String passOrFail = args[0];
boolean expectEnhancedText;
if (passOrFail.equals("expectEnhancedText")) {
expectEnhancedText = true;
} else {
expectEnhancedText = false;
}
test(expectEnhancedText);
}
static final InetSocketAddress dest = Utils.refusingEndpoint();
static final String PORT = ":" + Integer.toString(dest.getPort());
static final String HOST = dest.getHostString();
static final InetAddress ADDRESS = dest.getAddress();
static void test(boolean withProperty) {
// Socket
IOException e = getException(TestTarget.SOCKET);
checkResult(e, withProperty);
// SocketChannel
e = getException(TestTarget.CHANNEL);
checkResult(e, withProperty);
// AsyncSocketChannel
e = getException(TestTarget.ASYNC_CHANNEL);
checkResult(e, withProperty);
}
static void checkResult(IOException e, boolean withProperty) {
String msg = e.getMessage();
if (!withProperty) {
if (msg.contains(HOST) || msg.contains(PORT)) {
System.err.println("msg = " + msg);
throw new RuntimeException("Test failed: exception contains address info");
}
} else {
if (!msg.contains(HOST) || !msg.contains(PORT) ||
!msg.contains(ADDRESS.getHostAddress())) {
if (e instanceof ClosedChannelException)
return; // has no detail msg
throw new RuntimeException("Test failed: message '" + msg + "' is missing address info " + dest);
}
}
}
static IOException getException(TestTarget target) {
try {
if (target == TestTarget.SOCKET) {
try (Socket s = new Socket()) {
s.connect(dest);
}
} else if (target == TestTarget.CHANNEL) {
SocketChannel.open(dest);
} else if (target == TestTarget.ASYNC_CHANNEL) {
AsynchronousSocketChannel c = AsynchronousSocketChannel.open();
try {
c.connect(dest).get();
} catch (InterruptedException | ExecutionException ee) {
if (ee.getCause() instanceof IOException)
throw (IOException)ee.getCause();
throw new RuntimeException(ee.getCause());
}
}
return null;
} catch (IOException e) {
e.printStackTrace();
return e;
}
}
}

View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 1998, 2019, 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 4106601 8026245 8071424
* @library /test/lib
* @run main/othervm GetLocalAddress
* @run main/othervm -Djava.net.preferIPv4Stack=true GetLocalAddress
* @run main/othervm -Djava.net.preferIPv6Addresses=true GetLocalAddress
* @summary Test the java.net.socket.GetLocalAddress method
*
*/
import java.net.*;
import jdk.test.lib.net.IPSupport;
public class GetLocalAddress implements Runnable {
static ServerSocket ss;
static InetAddress addr;
static int port;
public static void main(String args[]) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
testBindNull();
boolean error = true;
int linger = 65546;
int value = 0;
addr = InetAddress.getLocalHost();
ss = new ServerSocket();
ss.bind(new InetSocketAddress(addr, 0));
port = ss.getLocalPort();
Thread t = new Thread(new GetLocalAddress());
t.start();
Socket soc = ss.accept();
if(addr.equals(soc.getLocalAddress())) {
error = false;
}
if (error)
throw new RuntimeException("Socket.GetLocalAddress failed.");
soc.close();
}
public void run() {
try {
Socket s = new Socket(addr, port);
} catch (Exception e) {
e.printStackTrace();
}
}
static void testBindNull() throws Exception {
try (Socket soc = new Socket()) {
soc.bind(null);
if (!soc.isBound())
throw new RuntimeException(
"should be bound after bind(null)");
if (soc.getLocalPort() <= 0)
throw new RuntimeException(
"bind(null) failed, local port: " + soc.getLocalPort());
if (soc.getLocalAddress() == null)
throw new RuntimeException(
"bind(null) failed, local address is null");
}
}
}

View file

@ -0,0 +1,341 @@
/*
* Copyright (c) 2010, 2022, 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 6370908 8220663
* @library /test/lib
* @summary Add support for HTTP_CONNECT proxy in Socket class.
* This test uses the wildcard address and is susceptible to fail intermittently.
* @key intermittent
* @run main HttpProxy
* @run main/othervm -Djava.net.preferIPv4Stack=true HttpProxy
* @run main/othervm -Djava.net.preferIPv6Addresses=true HttpProxy
*/
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
import static java.lang.System.out;
import jdk.test.lib.net.HttpHeaderParser;
import jdk.test.lib.net.IPSupport;
public class HttpProxy {
final String proxyHost;
final int proxyPort;
static final int SO_TIMEOUT = 15000;
public static void main(String[] args) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
String host;
int port;
ConnectProxyTunnelServer proxy = null;
if (args.length == 0) {
// Start internal proxy
proxy = new ConnectProxyTunnelServer();
proxy.start();
host = InetAddress.getLoopbackAddress().getHostAddress();
port = proxy.getLocalPort();
out.println("Running with internal proxy: " + host + ":" + port);
} else if (args.length == 2) {
host = args[0];
port = Integer.valueOf(args[1]);
out.println("Running against specified proxy server: " + host + ":" + port);
} else {
System.err.println("Usage: java HttpProxy [<proxy host> <proxy port>]");
return;
}
try {
HttpProxy p = new HttpProxy(host, port);
p.test();
} finally {
if (proxy != null)
proxy.close();
}
}
public HttpProxy(String proxyHost, int proxyPort) {
this.proxyHost = proxyHost;
this.proxyPort = proxyPort;
}
static boolean canUseIPv6() {
return IPSupport.hasIPv6() && !IPSupport.preferIPv4Stack();
}
void test() throws Exception {
InetSocketAddress proxyAddress = new InetSocketAddress(proxyHost, proxyPort);
Proxy httpProxy = new Proxy(Proxy.Type.HTTP, proxyAddress);
// Wildcard address is needed here
try (ServerSocket ss = new ServerSocket(0)) {
List<InetSocketAddress> externalAddresses = new ArrayList<>();
externalAddresses.add(
new InetSocketAddress(InetAddress.getLocalHost(), ss.getLocalPort()));
if (canUseIPv6()) {
byte[] bytes = new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
var address = InetAddress.getByAddress(bytes);
externalAddresses.add(
new InetSocketAddress(address, ss.getLocalPort()));
}
for (SocketAddress externalAddress : externalAddresses) {
try (Socket sock = new Socket(httpProxy)) {
sock.setSoTimeout(SO_TIMEOUT);
sock.setTcpNoDelay(false);
out.println("Trying to connect to server socket on " + externalAddress);
sock.connect(externalAddress);
try (Socket externalSock = ss.accept()) {
// perform some simple checks
check(sock.isBound(), "Socket is not bound");
check(sock.isConnected(), "Socket is not connected");
check(!sock.isClosed(), "Socket should not be closed");
check(sock.getSoTimeout() == SO_TIMEOUT,
"Socket should have a previously set timeout");
check(sock.getTcpNoDelay() == false, "NODELAY should be false");
simpleDataExchange(sock, externalSock);
}
}
}
}
}
static void check(boolean condition, String message) {
if (!condition) out.println(message);
}
static Exception unexpected(Exception e) {
out.println("Unexpected Exception: " + e);
e.printStackTrace();
return e;
}
// performs a simple exchange of data between the two sockets
// and throws an exception if there is any problem.
void simpleDataExchange(Socket s1, Socket s2) throws Exception {
try (final InputStream i1 = s1.getInputStream();
final InputStream i2 = s2.getInputStream();
final OutputStream o1 = s1.getOutputStream();
final OutputStream o2 = s2.getOutputStream()) {
startSimpleWriter("simpleWriter1", o1, 100);
startSimpleWriter("simpleWriter2", o2, 200);
simpleRead(i2, 100);
simpleRead(i1, 200);
}
}
void startSimpleWriter(String threadName, final OutputStream os, final int start) {
(new Thread(new Runnable() {
public void run() {
try { simpleWrite(os, start); }
catch (Exception e) {unexpected(e); }
finally { out.println(threadName + ": done"); }
}}, threadName)).start();
}
void simpleWrite(OutputStream os, int start) throws Exception {
byte b[] = new byte[2];
for (int i=start; i<start+100; i++) {
b[0] = (byte) (i / 256);
b[1] = (byte) (i % 256);
os.write(b);
}
out.println("Wrote " + start + " -> " + (start + 100));
}
void simpleRead(InputStream is, int start) throws Exception {
byte b[] = new byte [2];
for (int i=start; i<start+100; i++) {
int x = is.read(b);
if (x == 1)
x += is.read(b,1,1);
if (x!=2)
throw new Exception("read error");
int r = bytes(b[0], b[1]);
if (r != i)
throw new Exception("read " + r + " expected " +i);
}
out.println("Read " + start + " -> " + (start + 100));
}
int bytes(byte b1, byte b2) {
int i1 = (int)b1 & 0xFF;
int i2 = (int)b2 & 0xFF;
return i1 * 256 + i2;
}
static class ConnectProxyTunnelServer extends Thread implements AutoCloseable {
private final ServerSocket ss;
private volatile boolean closed;
public ConnectProxyTunnelServer() throws IOException {
ss = new ServerSocket(0, 0, InetAddress.getLoopbackAddress());
}
@Override
public void run() {
try {
while (!closed) {
try (Socket clientSocket = ss.accept()) {
processRequest(clientSocket);
}
}
} catch (Exception e) {
if (!closed) {
out.println("Proxy Failed: " + e);
e.printStackTrace();
}
} finally {
if (!closed)
try { ss.close(); } catch (IOException x) { unexpected(x); }
}
}
/**
* Returns the port on which the proxy is accepting connections.
*/
public int getLocalPort() {
return ss.getLocalPort();
}
@Override
public void close() throws Exception {
closed = true;
ss.close();
}
/*
* Processes the CONNECT request
*/
private void processRequest(Socket clientSocket) throws Exception {
HttpHeaderParser mheader = new HttpHeaderParser(clientSocket.getInputStream());
String statusLine = mheader.getRequestDetails();
if (!statusLine.startsWith("CONNECT")) {
out.println("proxy server: processes only "
+ "CONNECT method requests, received: "
+ statusLine);
return;
}
// retrieve the host and port info from the status-line
InetSocketAddress serverAddr = getConnectInfo(statusLine);
out.println("Proxy serving CONNECT request to " + serverAddr);
//open socket to the server
try (Socket serverSocket = new Socket(serverAddr.getAddress(),
serverAddr.getPort())) {
Forwarder clientFW = new Forwarder(clientSocket.getInputStream(),
serverSocket.getOutputStream());
Thread clientForwarderThread = new Thread(clientFW, "ClientForwarder");
clientForwarderThread.start();
send200(clientSocket);
Forwarder serverFW = new Forwarder(serverSocket.getInputStream(),
clientSocket.getOutputStream());
serverFW.run();
clientForwarderThread.join();
}
}
private void send200(Socket clientSocket) throws IOException {
OutputStream out = clientSocket.getOutputStream();
PrintWriter pout = new PrintWriter(out);
pout.println("HTTP/1.1 200 OK");
pout.println();
pout.flush();
}
/*
* This method retrieves the hostname and port of the tunnel destination
* from the request line.
* @param connectStr
* of the form: <i>CONNECT server-name:server-port HTTP/1.x</i>
*/
static InetSocketAddress getConnectInfo(String connectStr)
throws Exception
{
try {
int starti = connectStr.indexOf(' ');
int endi = connectStr.lastIndexOf(' ');
String connectInfo = connectStr.substring(starti+1, endi).trim();
// retrieve server name and port
endi = connectInfo.lastIndexOf(':');
String name = connectInfo.substring(0, endi);
if (name.contains(":")) {
if (!(name.startsWith("[") && name.endsWith("]"))) {
throw new IOException("Invalid host:" + name);
}
name = name.substring(1, name.length() - 1);
}
int port = Integer.parseInt(connectInfo.substring(endi+1));
return new InetSocketAddress(name, port);
} catch (Exception e) {
out.println("Proxy received a request: " + connectStr);
throw unexpected(e);
}
}
}
/* Reads from the given InputStream and writes to the given OutputStream */
static class Forwarder implements Runnable
{
private final InputStream in;
private final OutputStream os;
Forwarder(InputStream in, OutputStream os) {
this.in = in;
this.os = os;
}
@Override
public void run() {
try {
byte[] ba = new byte[1024];
int count;
while ((count = in.read(ba)) != -1) {
os.write(ba, 0, count);
}
} catch (IOException e) {
unexpected(e);
}
}
}
}

View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 2003, 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 4957669 5017871
* @summary REGRESSION:create a socket with a Japanese hostname throws IllegalArgumentExcept; REGRESSION: host can't contain special chars such as space
*/
import java.net.Socket;
import java.net.UnknownHostException;
// internalized domain name test
public class IDNTest {
public static void main(String[] args) {
try {
Socket s = new Socket("\u67f4\u7530\u82b3\u6a39", 8000);
} catch (UnknownHostException e) {
// Expected
} catch (Exception e) {
throw new RuntimeException(e);
}
try {
Socket s = new Socket("ho st", 8000);
} catch (UnknownHostException e) {
// Expected
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View file

@ -0,0 +1,129 @@
/*
* Copyright (c) 2007, 2018, 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 6598160
* @library /test/lib
* @summary Windows IPv6 Socket implementation doesn't set the handle to not inherit
* @author Chris Hegarty
* @run main InheritHandle
* @run main/othervm -Djava.net.preferIPv4Stack=true InheritHandle
*/
import java.net.BindException;
import java.net.ServerSocket;
import java.io.File;
import java.io.IOException;
import jdk.test.lib.net.IPSupport;
/**
* This test is only really applicable to Windows machines that are running IPv6, but
* it should still pass on other platforms so we can just run it.
*/
public class InheritHandle
{
static String java = System.getProperty("java.home") + File.separator +
"bin" + File.separator + "java";
public static void main(String[] args) {
IPSupport.throwSkippedExceptionIfNonOperational();
if (args.length == 1) {
doWait();
} else {
startTest();
}
}
static void startTest() {
ServerSocket ss;
int port;
Process process;
// create a ServerSocket listening on any port
try {
ss = new ServerSocket(0);
port = ss.getLocalPort();
System.out.println("First ServerSocket listening on port " + port);
} catch (IOException e) {
System.out.println("Cannot create ServerSocket");
e.printStackTrace();
return;
}
// create another java process that simply waits. If the bug is present this
// process will inherit the native IPv6 handle for ss and cause the second
// ServerSocket constructor to throw a BindException
try {
process = Runtime.getRuntime().exec(java + " InheritHandle -doWait");
} catch (IOException ioe) {
System.out.println("Cannot create process");
ioe.printStackTrace();
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
return;
}
// Allow some time for the process to get started
try {
System.out.println("waiting...");
Thread.sleep(2 * 1000);
System.out.println("Now close the socket and try to create another" +
" one listening on the same port");
ss.close();
int retries = 0;
while (retries < 5) {
try (ServerSocket s = new ServerSocket(port);) {
System.out.println("Second ServerSocket created successfully");
break;
} catch (BindException e) {
System.out.println("BindException \"" + e.getMessage() + "\", retrying...");
Thread.sleep(100L);
retries ++;
continue;
}
}
} catch (InterruptedException ie) {
} catch (IOException ioe) {
throw new RuntimeException("Failed: " + ioe);
} finally {
process.destroy();
}
System.out.println("OK");
}
static void doWait() {
try {
Thread.sleep(200 * 1000);
} catch (InterruptedException ie) {
}
}
}

View file

@ -0,0 +1,101 @@
/*
* Copyright (c) 2001, 2019, 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 4508149
* @library /test/lib
* @summary Setting ServerSocket.setSoTimeout shouldn't cause
* the timeout to be inherited by accepted connections
* @run main InheritTimeout
* @run main/othervm -Djava.net.preferIPv4Stack=true InheritTimeout
*/
import java.net.*;
import java.io.InputStream;
import jdk.test.lib.net.IPSupport;
public class InheritTimeout {
class Reaper extends Thread {
Socket s;
int timeout;
Reaper(Socket s, int timeout) {
this.s = s;
this.timeout = timeout;
}
public void run() {
try {
Thread.currentThread().sleep(timeout);
s.close();
} catch (Exception e) {
}
}
}
InheritTimeout() throws Exception {
InetAddress ia = InetAddress.getLocalHost();
ServerSocket ss = new ServerSocket();
ss.bind(new InetSocketAddress(ia, 0));
ss.setSoTimeout(1000);
InetSocketAddress isa =
new InetSocketAddress(ia, ss.getLocalPort());
// client establishes the connection
Socket s1 = new Socket();
s1.connect(isa);
// receive the connection
Socket s2 = ss.accept();
// schedule reaper to close the socket in 5 seconds
Reaper r = new Reaper(s2, 5000);
r.start();
boolean readTimedOut = false;
try {
s2.getInputStream().read();
} catch (SocketTimeoutException te) {
readTimedOut = true;
} catch (SocketException e) {
if (!s2.isClosed()) {
throw e;
}
}
s1.close();
ss.close();
if (readTimedOut) {
throw new Exception("Unexpected SocketTimeoutException throw!");
}
}
public static void main(String args[]) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
new InheritTimeout();
}
}

View file

@ -0,0 +1,174 @@
/*
* Copyright (c) 2001, 2019, 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 4469866
* @library /test/lib
* @summary Connecting to a link-local IPv6 address should not
* causes a SocketException to be thrown.
* @library /test/lib
* @build jdk.test.lib.NetworkConfiguration
* jdk.test.lib.Platform
* @run main LinkLocal
* @run main/othervm -Djava.net.preferIPv4Stack=true LinkLocal
*/
import java.net.*;
import java.util.List;
import java.util.stream.Collectors;
import jdk.test.lib.NetworkConfiguration;
import jdk.test.lib.net.IPSupport;
public class LinkLocal {
static int testCount = 0;
static int failed = 0;
static void TcpTest(InetAddress ia) throws Exception {
System.out.println("**************************************");
testCount++;
System.out.println("Test " + testCount + ": TCP connect to " + ia);
/*
* Create ServerSocket on wildcard address and then
* try to connect Socket to link-local address.
*/
ServerSocket ss = new ServerSocket();
ss.bind(new InetSocketAddress(ia, 0));
Socket s = new Socket();
try {
s.connect(new InetSocketAddress(ia, ss.getLocalPort()));
System.out.println("Test passed - connection established.");
// connection was established so accept it
Socket s2 = ss.accept();
s2.close();
} catch (SocketException e) {
failed++;
System.out.println("Test failed: " + e);
} finally {
s.close();
ss.close();
}
}
static void UdpTest(InetAddress ia, boolean connected) throws Exception {
System.out.println("**************************************");
testCount++;
if (connected) {
System.out.println("Test " + testCount + ": UDP connect to " + ia);
} else {
System.out.println("Test " + testCount + ": UDP send to " + ia);
}
DatagramSocket ds1 = new DatagramSocket();
DatagramSocket ds2 = new DatagramSocket(0, ia);
try {
byte b[] = "Hello".getBytes();
DatagramPacket p = new DatagramPacket(b, b.length);
if (connected) {
ds1.connect( new InetSocketAddress(ia, ds2.getLocalPort()) );
System.out.println("DatagramSocket connected.");
} else {
p.setAddress(ia);
p.setPort(ds2.getLocalPort());
}
ds1.send(p);
System.out.println("Packet has been sent.");
ds2.setSoTimeout(5000);
ds2.receive(p);
System.out.println("Test passed - packet received.");
} catch (SocketException e) {
failed++;
System.out.println("Test failed: " + e);
} finally {
ds1.close();
ds2.close();
}
}
static void TestAddress(InetAddress ia) throws Exception {
TcpTest(ia);
UdpTest(ia, true); /* unconnected */
UdpTest(ia, false); /* connected */
}
public static void main(String args[]) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
/*
* If an argument is provided ensure that it's
* a link-local IPv6 address.
*/
if (args.length > 0) {
InetAddress ia = InetAddress.getByName(args[0]);
if ( !(ia instanceof Inet6Address) ||
!ia.isLinkLocalAddress()) {
throw new Exception(ia +
" is not a link-local IPv6 address");
}
TestAddress(ia);
}
/*
* If no argument is provided then enumerate the
* local addresses and run the test on each link-local
* IPv6 address.
*/
if (args.length == 0) {
List<Inet6Address> addrs = NetworkConfiguration.probe()
.ip6Addresses()
.filter(Inet6Address::isLinkLocalAddress)
.collect(Collectors.toList());
for (Inet6Address addr : addrs) {
TestAddress(addr);
}
}
/*
* Print results
*/
if (testCount == 0) {
System.out.println("No link-local IPv6 addresses - test skipped!");
} else {
System.out.println("**************************************");
System.out.println(testCount + " test(s) executed, " +
failed + " failed.");
if (failed > 0) {
throw new Exception( failed + " test(s) failed.");
}
}
}
}

View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2020, 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.
*/
public class NativeThread {
public static final int SIGPIPE;
static {
SIGPIPE = getSIGPIPE();
}
public static native long getID();
public static native int signal(long threadId, int sig);
private static native int getSIGPIPE();
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2002, 2019, 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 4712609
* @summary Socket(String host, int port) throws NullPointerException if host is null
*/
import java.net.*;
import java.io.IOException;
public class NullHost {
class Server extends Thread {
private ServerSocket svr;
public Server() throws IOException {
svr = new ServerSocket();
// The client side calls Socket((String) null, ...) which
// resolves to InetAddress.getByName((String)null) which in
// turns will resolve to the loopback address
svr.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
}
public int getPort() {
return svr.getLocalPort();
}
volatile boolean done;
public void shutdown() {
try {
done = true;
svr.close();
} catch (IOException e) {
}
}
public void run() {
Socket s;
try {
while (!done) {
s = svr.accept();
s.close();
}
} catch (IOException e) {
if (!done) e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
NullHost n = new NullHost();
}
public NullHost () throws IOException {
Server s = new Server();
int port = s.getPort();
s.start();
try {
try (var sock = new Socket((String)null, port)) {}
try (var sock = new Socket((String)null, port, true)) {}
try (var sock = new Socket((String)null, port, null, 0)) {}
} catch (NullPointerException e) {
throw new RuntimeException("Got a NPE");
} finally {
s.shutdown();
}
}
}

Binary file not shown.

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2019, 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 8216978
* @summary Drop support for pre JDK 1.4 SocketImpl implementations
* @library OldSocketImpl.jar
* @run main/othervm OldSocketImplTest
*/
import java.net.*;
public class OldSocketImplTest {
public static void main(String[] args) throws Exception {
Socket.setSocketImplFactory(new SocketImplFactory() {
public SocketImpl createSocketImpl() {
return new OldSocketImpl();
}
});
try {
Socket socket = new Socket("localhost", 23);
throw new RuntimeException("error test failed");
} catch (AbstractMethodError error) {
error.printStackTrace();
System.out.println("Old impl no longer accepted: OK");
}
}
}

View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 2003, 2019, 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 4097826
* @library /test/lib
* @summary SOCKS support inadequate
* @run main/timeout=40/othervm -DsocksProxyHost=nonexistant ProxyCons
* @run main/timeout=40/othervm -DsocksProxyHost=nonexistant -Djava.net.preferIPv4Stack=true ProxyCons
*/
import java.net.*;
import jdk.test.lib.net.IPSupport;
public class ProxyCons {
class Server extends Thread {
ServerSocket server;
Server (ServerSocket server) {
super ();
this.server = server;
}
public void run () {
try {
Socket s = server.accept ();
s.close();
while (!finished ()) {
Thread.sleep (500);
}
} catch (Exception e) {
}
}
boolean isFinished = false;
synchronized boolean finished () {
return (isFinished);
}
synchronized void done () {
isFinished = true;
}
}
public ProxyCons() {
}
void test() throws Exception {
InetAddress localHost = InetAddress.getLocalHost();
ServerSocket ss = new ServerSocket();
ss.bind(new InetSocketAddress(localHost, 0));
try {
Server s = new Server(ss);
s.start();
Socket sock = new Socket(Proxy.NO_PROXY);
sock.connect(new InetSocketAddress(localHost, ss.getLocalPort()));
s.done();
sock.close();
} catch (java.io.IOException e) {
throw new RuntimeException(e);
} finally {
ss.close();
}
}
public static void main(String[] args) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
ProxyCons c = new ProxyCons();
c.test();
}
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2001, 2019, 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 4468997
* @library /test/lib
* @summary SO_LINGER is ignored on Windows with Winsock 2
* @run main RST
* @run main/othervm -Djava.net.preferIPv4Stack=true RST
*/
import java.net.*;
import java.io.*;
import jdk.test.lib.net.IPSupport;
public class RST implements Runnable {
Socket client;
public void run() {
try {
client.setSoLinger(true, 0); // hard reset
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
RST() throws Exception {
InetAddress loopback = InetAddress.getLoopbackAddress();
ServerSocket ss = new ServerSocket();
ss.bind(new InetSocketAddress(loopback, 0));
client = new Socket(loopback, ss.getLocalPort());
Socket server = ss.accept();
Thread thr = new Thread(this);
thr.start();
SocketException exc = null;
try {
InputStream in = server.getInputStream();
/*
* This read should throw a SocketException indicating a
* connection reset.
*/
int n = in.read();
} catch (SocketException se) {
exc = se;
}
server.close();
ss.close();
if (exc == null) {
throw new Exception("Expected SocketException not thrown");
}
if (exc.getMessage().toLowerCase().indexOf("reset") == -1) {
throw new Exception("SocketException thrown but not expected \"connection reset\"");
}
}
public static void main(String args[]) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
new RST();
}
}

View file

@ -0,0 +1,140 @@
/*
* Copyright (c) 2018, 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
* @requires (os.family == "linux" | os.family == "mac")
* @bug 8203937
* @summary Test reading bytes from a socket after the connection has been
* reset by the peer
*/
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
* This test exercises platform specific and unspecified behavior. It exists
* only to ensure that the behavior doesn't change between JDK releases.
*/
public class ReadAfterReset {
private static final PrintStream out = System.out;
// number of bytes to write before the connection reset
private static final int NUM_BYTES_TO_WRITE = 1000;
public static void main(String[] args) throws IOException {
try (ServerSocket ss = new ServerSocket()) {
ss.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
/**
* Connect to the server which will write some bytes and reset the
* connection. The client then attempts to read the bytes sent by
* the server before it closed the connection.
*/
out.println("Test connection ...");
try (Socket s = new Socket()) {
s.connect(ss.getLocalSocketAddress());
int nwrote = acceptAndResetConnection(ss);
int nread = readUntilIOException(s);
if (nread != nwrote) {
throw new RuntimeException("Client read " + nread + ", expected " + nwrote);
}
}
/**
* Connect to the server which will write some bytes and reset the
* connection. The client then writes to its end of the connection,
* failing as the connection is reset. It then attempts to read the
* bytes sent by the server before it closed the connection.
*/
out.println();
out.println("Test connection ...");
try (Socket s = new Socket()) {
s.connect(ss.getLocalSocketAddress());
int nwrote = acceptAndResetConnection(ss);
writeUntilIOException(s);
int nread = readUntilIOException(s);
if (nread != nwrote) {
throw new RuntimeException("Client read " + nread + ", expected " + nwrote);
}
}
}
}
/**
* Accept a connection, write bytes, and then reset the connection
*/
static int acceptAndResetConnection(ServerSocket ss) throws IOException {
int count = NUM_BYTES_TO_WRITE;
try (Socket peer = ss.accept()) {
peer.getOutputStream().write(new byte[count]);
peer.setSoLinger(true, 0);
out.format("Server wrote %d bytes and reset connection%n", count);
}
return count;
}
/**
* Write bytes to a socket until I/O exception is thrown
*/
static void writeUntilIOException(Socket s) {
try {
byte[] bytes = new byte[100];
while (true) {
s.getOutputStream().write(bytes);
out.format("Client wrote %d bytes%n", bytes.length);
}
} catch (IOException ioe) {
out.format("Client write failed: %s (expected)%n", ioe);
}
}
/**
* Read bytes from a socket until I/O exception is thrown.
*
* @return the number of bytes read before the I/O exception was thrown
*/
static int readUntilIOException(Socket s) {
int nread = 0;
try {
byte[] bytes = new byte[100];
while (true) {
int n = s.getInputStream().read(bytes);
if (n < 0) {
out.println("Client read EOF");
break;
} else {
out.format("Client read %s bytes%n", n);
nread += n;
}
}
} catch (IOException ioe) {
out.format("Client read failed: %s (expected)%n", ioe);
}
return nread;
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 1998, 2019, 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 4169831
* @library /test/lib
* @summary test timeout on a socket read
* @run main/timeout=15 ReadTimeout
* @run main/othervm/timeout=15 -Djava.net.preferIPv4Stack=true ReadTimeout
*/
import java.net.*;
import java.io.*;
import jdk.test.lib.net.IPSupport;
public class ReadTimeout {
public static void main(String args[]) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
InetAddress sin = null;
Socket soc = null,soc1 = null;
InputStream is = null;
OutputStream os = null;
ServerSocket srv = null;
int port = 0;
int tout = 1000;
sin = InetAddress.getLocalHost();
srv = new ServerSocket();
srv.bind(new InetSocketAddress(sin, 0));
port = srv.getLocalPort();
soc = new Socket(sin, port);
soc1 = srv.accept();
soc.setSoTimeout(tout);
try {
is = soc.getInputStream();
os = soc1.getOutputStream();
is.read();
} catch(InterruptedIOException e) {
} finally {
soc.close();
soc1.close();
srv.close();
}
}
}

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2018, 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 8201510
* @library /test/lib
* @summary Make sure IPv6 addresses are rejected when the System option
* java.net.preferIPv4Stack is set to true
* @run main/othervm -Djava.net.preferIPv4Stack=true RejectIPv6
*/
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import jdk.test.lib.net.IPSupport;
public class RejectIPv6 {
public static void main(String [] argv) throws Throwable {
IPSupport.throwSkippedExceptionIfNonOperational();
ServerSocket serverSocket = new ServerSocket(0);
serverSocket.setSoTimeout(1000);
int serverPort = serverSocket.getLocalPort();
Socket clientSocket = new Socket();
test("bind", () -> clientSocket.bind(
new InetSocketAddress("::1", 0)));
test("connect", () -> clientSocket.connect(
new InetSocketAddress("::1", serverPort), 1000));
}
static void test(String msg, CodeToTest codeToTest) throws Throwable {
Thread client = new Thread(() ->
{
try {
codeToTest.run();
throw new RuntimeException(msg +
" failed to reject IPv6 address");
} catch (SocketException ok) {
} catch (Exception exc) {
throw new RuntimeException("unexpected", exc);
}
});
client.start();
client.join();
}
interface CodeToTest {
void run() throws Exception;
}
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2000, 2019, 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 4326250
* @summary Test Socket.setReceiveBufferSize() throwin IllegalArgumentException
*
*/
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.ServerSocket;
public class SetReceiveBufferSize {
public static void main(String[] args) throws Exception {
SetReceiveBufferSize s = new SetReceiveBufferSize();
}
public SetReceiveBufferSize() throws Exception {
ServerSocket ss = new ServerSocket();
InetAddress loopback = InetAddress.getLoopbackAddress();
ss.bind(new InetSocketAddress(loopback, 0));
Socket s = new Socket(loopback, ss.getLocalPort());
Socket accepted = ss.accept();
try {
s.setReceiveBufferSize(0);
} catch (IllegalArgumentException e) {
return;
} catch (Exception ex) {
} finally {
ss.close();
s.close();
accepted.close();
}
throw new RuntimeException("IllegalArgumentException not thrown!");
}
}

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 1998, 2019, 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 4151834
* @library /test/lib
* @summary Test Socket.setSoLinger
* @run main SetSoLinger
* @run main/othervm -Djava.net.preferIPv4Stack=true SetSoLinger
* @run main/othervm -Djava.net.preferIPv6Addresses=true SetSoLinger
*/
import java.net.*;
import jdk.test.lib.net.IPSupport;
public class SetSoLinger {
static final int LINGER = 65546;
public static void main(String args[]) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
int value;
InetAddress addr = InetAddress.getLocalHost();
ServerSocket ss = new ServerSocket();
InetSocketAddress socketAddress = new InetSocketAddress(addr, 0);
ss.bind(socketAddress);
int port = ss.getLocalPort();
Socket s = new Socket(addr, port);
Socket soc = ss.accept();
soc.setSoLinger(true, LINGER);
value = soc.getSoLinger();
soc.close();
s.close();
ss.close();
if(value != 65535)
throw new RuntimeException("Failed. Value not properly reduced.");
}
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2001, 2019, 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 4425485
* @summary Check that shutdownInput followed by shutdownOutput
* doesn't throw an exception.
*/
import java.net.*;
public class ShutdownBoth {
public static void main(String args[]) throws Exception {
InetAddress loopback = InetAddress.getLoopbackAddress();
ServerSocket ss = new ServerSocket(0, 50, loopback);
Socket s1 = new Socket(ss.getInetAddress(), ss.getLocalPort());
Socket s2 = ss.accept();
try {
s1.shutdownInput();
s1.shutdownOutput(); // failed b55
} finally {
s1.close();
s2.close();
ss.close();
}
}
}

View file

@ -0,0 +1,96 @@
/*
* Copyright (c) 2011, 2019, 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 7014860
* @library /test/lib
* @summary Socket.getInputStream().available() not clear for
* case that connection is shutdown for reading
* @run main ShutdownInput
* @run main/othervm -Djava.net.preferIPv4Stack=true ShutdownInput
*/
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import jdk.test.lib.net.IPSupport;
public class ShutdownInput {
static boolean failed = false;
public static void main(String args[]) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
InetAddress iaddr = InetAddress.getLoopbackAddress();
try (ServerSocket ss = new ServerSocket(0, 0, iaddr);
Socket s1 = new Socket(iaddr, ss.getLocalPort());
Socket s2 = ss.accept() ) {
test(s1, s2, "Testing NET");
}
// check the NIO socket adapter
InetSocketAddress socketAddress = new InetSocketAddress(iaddr, 0);
try (ServerSocketChannel sc = ServerSocketChannel.open().bind(socketAddress);
SocketChannel s1 = SocketChannel.open(
new InetSocketAddress(iaddr, sc.socket().getLocalPort()));
SocketChannel s2 = sc.accept() ) {
test(s1.socket(), s2.socket(), "Testing NIO");
}
if (failed) {
throw new RuntimeException("Failed: check output");
}
}
public static void test(Socket s1, Socket s2, String mesg) throws Exception {
OutputStream os = s1.getOutputStream();
os.write("This is a message".getBytes("US-ASCII"));
InputStream in = s2.getInputStream();
s2.shutdownInput();
if (in.available() != 0) {
failed = true;
System.out.println(mesg + ":" + s2 + " in.available() should be 0, " +
"but returns "+ in.available());
}
byte[] ba = new byte[2];
if (in.read() != -1 ||
in.read(ba) != -1 ||
in.read(ba, 0, ba.length) != -1) {
failed = true;
System.out.append(mesg + ":" + s2 + " in.read() should be -1");
}
}
}

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 1998, 2022, 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 4156625
@summary Socket.setSoTimeout(T) can cause incorrect delay of T
under green threads
@author Tom Rodriguez
*/
/*
* This program depends a bit on the particular behaviour of the green
* threads scheduler to produce the problem, but given that the underlying
* bug a green threads bug, I think that's OK.
*/
import java.net.*;
public class SoTimeout implements Runnable {
static ServerSocket serverSocket;
static long timeWritten;
static InetAddress addr;
static int port;
public static void main(String[] args) throws Exception {
addr = InetAddress.getLocalHost();
serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress(addr, 0));
port = serverSocket.getLocalPort();
byte[] b = new byte[12];
Thread t = new Thread(new SoTimeout());
t.start();
Socket s = serverSocket.accept();
serverSocket.close();
// set a 5 second timeout on the socket
s.setSoTimeout(5000);
s.getInputStream().read(b, 0, b.length);
s.close();
long waited = System.currentTimeMillis() - timeWritten;
// this sequence should complete fairly quickly and if it
// takes something resembling the SoTimeout value then
// we are probably incorrectly blocking and not waking up
if (waited > 2000) {
throw new Exception("shouldn't take " + waited + " to complete");
}
}
public void run() {
try {
byte[] b = new byte[12];
Socket s = new Socket(addr, port);
Thread.yield();
timeWritten = System.currentTimeMillis();
s.getOutputStream().write(b, 0, 12);
s.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,151 @@
/*
* Copyright (c) 2020, 2021, 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 8237858
* @summary SocketImpl.socketAccept() handles EINTR incorrectly
* @requires (os.family != "windows")
* @compile NativeThread.java
* @run main/othervm/native SocketAcceptInterruptTest 0
* @run main/othervm/native SocketAcceptInterruptTest 5000
*/
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class SocketAcceptInterruptTest {
public static void main(String[] args) throws Exception {
System.loadLibrary("NativeThread");
InetAddress loopback = InetAddress.getLoopbackAddress();
ExecutorService executor = Executors.newFixedThreadPool(1);
try ( ServerSocket ss = new ServerSocket(0, 50, loopback);) {
Server server = new Server(ss, Integer.parseInt(args[0]));
Future<Result> future = executor.submit(server);
long threadId = server.getID();
sendSignal(threadId, ss);
sleep(100);
// In failing case server socket will be closed, so we do need to check first
if (!ss.isClosed()) {
// After sending SIGPIPE, create client socket and connect to server
try ( Socket s = new Socket(loopback, ss.getLocalPort()); InputStream in = s.getInputStream();) {
in.read(); // reading one byte is enought for test.
}
}
Result result = future.get();
if (result.status == Result.FAIL) {
throw result.exception;
}
} finally {
executor.shutdown();
}
System.out.println("OK!");
}
private static void sendSignal(long threadId, ServerSocket ss) {
System.out.println("Sending SIGPIPE to ServerSocket thread.");
int count = 0;
while (!ss.isClosed() && count++ < 20) {
sleep(10);
if (NativeThread.signal(threadId, NativeThread.SIGPIPE) != 0) {
throw new RuntimeException("Failed to interrupt the server thread.");
}
}
}
private static void sleep(long time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
// ignore the exception.
}
}
static class Server implements Callable<Result> {
private volatile long threadId;
private final ServerSocket serverSocket;
private final int timeout;
public Server(ServerSocket ss, int timeout) {
serverSocket = ss;
this.timeout = timeout;
}
@Override
public Result call() {
try {
threadId = NativeThread.getID();
serverSocket.setSoTimeout(timeout);
try ( Socket socket = serverSocket.accept();
OutputStream outputStream = socket.getOutputStream();) {
outputStream.write("Hello!".getBytes());
return new Result(Result.SUCCESS, null);
}
} catch (IOException e) {
close();
return new Result(Result.FAIL, e);
}
}
long getID() {
while (threadId == 0) {
sleep(5);
}
return threadId;
}
private void close() {
if (!serverSocket.isClosed()) {
try {
serverSocket.close();
} catch (IOException ex) {
// ignore the exception
}
}
}
}
static class Result {
static final int SUCCESS = 0;
static final int FAIL = 1;
final int status;
final Exception exception;
public Result(int status, Exception ex) {
this.status = status;
exception = ex;
}
}
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2012, 2019, 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 7181793
* @summary getOutputStream create streams that cannot be GC'ed until Socket is closed
* @run main/othervm -Xmx32m SocketGrowth
*/
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketGrowth {
public static void main(String[] args) throws IOException {
InetAddress loopbackAddress = InetAddress.getLoopbackAddress();
try (ServerSocket ss = new ServerSocket(0, 0, loopbackAddress)) {
try (Socket s = new Socket(loopbackAddress, ss.getLocalPort());
Socket peer = ss.accept()) {
for (int i=0; i<1000000; i++) {
// buggy JDK will run out of memory in this loop
s.getOutputStream();
// test InputStream also while we're here
s.getInputStream();
if (i % 100000 == 0) System.out.println(i);
}
}
}
}
}

View file

@ -0,0 +1,179 @@
/*
* Copyright (c) 2020, 2021, 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 8237858
* @summary SocketImpl.socketAccept() handles EINTR incorrectly
* @requires (os.family != "windows")
* @compile NativeThread.java
* @run main/othervm/native SocketReadInterruptTest 2000 3000
* @run main/othervm/native SocketReadInterruptTest 2000 0
*/
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class SocketReadInterruptTest {
public static void main(String[] args) throws Exception {
System.loadLibrary("NativeThread");
ExecutorService executor = Executors.newFixedThreadPool(2);
InetAddress loopback = InetAddress.getLoopbackAddress();
try ( ServerSocket ss = new ServerSocket(0, 50, loopback);
Socket s1 = new Socket(loopback, ss.getLocalPort());) {
Server server = new Server(ss, Integer.parseInt(args[0]));
Future<Result> f1 = executor.submit(server);
Client client = new Client(s1, Integer.parseInt(args[1]));
Future<Result> f2 = executor.submit(client);
long threadId = client.getID();
sleep(200);
System.out.println("Sending SIGPIPE to client thread.");
if (NativeThread.signal(threadId, NativeThread.SIGPIPE) != 0) {
throw new RuntimeException("Failed to interrupt the thread.");
}
Result r1 = f1.get();
if (r1.status == Result.FAIL) {
throw r1.exception;
}
Result r2 = f2.get();
if (r2.status == Result.FAIL) {
throw r2.exception;
}
System.out.println("OK!");
} finally {
executor.shutdown();
}
}
private static void sleep(long time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
static class Client implements Callable<Result> {
private volatile long threadId;
private final Socket client;
private final int timeout;
public Client(Socket s, int timeout) {
client = s;
this.timeout = timeout;
}
@Override
public Result call() {
threadId = NativeThread.getID();
byte[] arr = new byte[64];
try ( InputStream in = client.getInputStream();) {
client.setSoTimeout(timeout);
in.read(arr);
return new Result(Result.SUCCESS, null);
} catch (IOException ex) {
close();
return new Result(Result.FAIL, ex);
}
}
long getID() {
while (threadId == 0) {
sleep(5);
}
return threadId;
}
void close() {
if (!client.isClosed()) {
try {
client.close();
} catch (IOException ex) {
// ignore the exception.
}
}
}
}
static class Server implements Callable<Result> {
private final ServerSocket serverSocket;
private final int timeout;
public Server(ServerSocket ss, int timeout) {
serverSocket = ss;
this.timeout = timeout;
}
@Override
public Result call() {
try {
try ( Socket client = serverSocket.accept(); OutputStream outputStream = client.getOutputStream();) {
sleep(timeout);
outputStream.write("This is just a test string.".getBytes());
return new Result(Result.SUCCESS, null);
}
} catch (IOException e) {
close();
return new Result(Result.FAIL, e);
}
}
public void close() {
if (!serverSocket.isClosed()) {
try {
serverSocket.close();
} catch (IOException ex) {
}
}
}
}
static class Result {
static final int SUCCESS = 0;
static final int FAIL = 1;
final int status;
final Exception exception;
public Result(int status, Exception ex) {
this.status = status;
exception = ex;
}
}
}

View file

@ -0,0 +1,140 @@
/*
* Copyright (c) 2010, 2019, 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 6223635
* @library /test/lib
* @summary Code hangs at connect call even when Timeout is specified
* @run main SocksConnectTimeout
* @run main/othervm -Djava.net.preferIPv4Stack=true SocksConnectTimeout
*/
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.net.ServerSocket;
import java.net.SocketTimeoutException;
import java.io.IOException;
import java.io.Closeable;
import java.util.concurrent.Phaser;
import java.util.concurrent.TimeUnit;
import jdk.test.lib.net.IPSupport;
public class SocksConnectTimeout {
static ServerSocket serverSocket;
static final boolean debug = true;
static final Phaser startPhaser = new Phaser(2);
static final Phaser finishPhaser = new Phaser(2);
static int failed, passed;
public static void main(String[] args) {
IPSupport.throwSkippedExceptionIfNonOperational();
try {
serverSocket = new ServerSocket();
InetAddress localHost = InetAddress.getLocalHost();
serverSocket.bind(new InetSocketAddress(localHost, 0));
(new Thread() {
@Override
public void run() { serve(); }
}).start();
Proxy socksProxy = new Proxy(Proxy.Type.SOCKS,
new InetSocketAddress(localHost, serverSocket.getLocalPort()));
test(socksProxy);
} catch (IOException e) {
unexpected(e);
} finally {
close(serverSocket);
if (failed > 0)
throw new RuntimeException("Test Failed: passed:" + passed + ", failed:" + failed);
}
}
static void test(Proxy proxy) {
startPhaser.arriveAndAwaitAdvance();
Socket socket = null;
try {
socket = new Socket(proxy);
connectWithTimeout(socket);
failed("connected successfully!");
} catch (SocketTimeoutException socketTimeout) {
debug("Passed: Received: " + socketTimeout);
passed();
} catch (Exception exception) {
failed("Connect timeout test failed", exception);
} finally {
finishPhaser.arriveAndAwaitAdvance();
close(socket);
}
}
static void connectWithTimeout(Socket socket) throws IOException {
socket.connect(new InetSocketAddress(InetAddress.getLocalHost(), 1234), 500);
}
static void serve() {
Socket client = null;
try {
startPhaser.arriveAndAwaitAdvance();
client = serverSocket.accept();
finishPhaser.awaitAdvanceInterruptibly(finishPhaser.arrive(), 5, TimeUnit.SECONDS);
} catch (Exception e) {
unexpected(e);
} finally {
close(client);
}
}
static void debug(String message) {
if (debug)
System.out.println(message);
}
static void unexpected(Exception e ) {
System.out.println("Unexcepted Exception: " + e);
}
static void close(Closeable closeable) {
if (closeable != null) try { closeable.close(); } catch (IOException e) {unexpected(e);}
}
static void failed(String message) {
System.out.println(message);
failed++;
}
static void failed(String message, Exception e) {
System.out.println(message);
System.out.println(e);
failed++;
}
static void passed() { passed++; };
}

View file

@ -0,0 +1,120 @@
/*
* Copyright (c) 2012, 2019, 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 8003833
* @summary Spurious NPE from Socket.getIn/OutputStream
*/
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Phaser;
// Racey test, will not always fail, but if it does then there is a problem.
public class Streams {
static final int NUM_THREADS = 100;
static volatile boolean failed;
static final Phaser startingGate = new Phaser(NUM_THREADS + 1);
public static void main(String[] args) throws Exception {
try (ServerSocket ss = new ServerSocket()) {
InetAddress loopback = InetAddress.getLoopbackAddress();
ss.bind(new InetSocketAddress(loopback, 0));
runTest(OutputStreamGetter.class, ss);
runTest(InputStreamGetter.class, ss);
}
if (failed)
throw new RuntimeException("Failed, check output");
}
static void runTest(Class<? extends StreamGetter> klass, ServerSocket ss)
throws Exception
{
final int port = ss.getLocalPort();
final InetAddress address = ss.getInetAddress();
Socket[] sockets = new Socket[NUM_THREADS];
for (int i=0; i<NUM_THREADS; i++) {
sockets[i] = address.isAnyLocalAddress()
? new Socket("localhost", port)
: new Socket(address, port);
try (Socket socket = ss.accept()) {}
}
Constructor<? extends StreamGetter> ctr = klass.getConstructor(Socket.class);
Thread[] threads = new Thread[NUM_THREADS];
for (int i=0; i<NUM_THREADS; i++)
threads[i] = ctr.newInstance(sockets[i]);
for (int i=0; i<NUM_THREADS; i++)
threads[i].start();
startingGate.arriveAndAwaitAdvance();
for (int i=0; i<NUM_THREADS; i++)
sockets[i].close();
for (int i=0; i<NUM_THREADS; i++)
threads[i].join();
}
static abstract class StreamGetter extends Thread {
final Socket socket;
StreamGetter(Socket s) { socket = s; }
@Override
public void run() {
try {
startingGate.arriveAndAwaitAdvance();
getStream();
} catch (IOException x) {
// OK, socket may be closed
} catch (NullPointerException x) {
x.printStackTrace();
failed = true;
}
}
abstract void getStream() throws IOException;
}
static class InputStreamGetter extends StreamGetter {
public InputStreamGetter(Socket s) { super(s); }
void getStream() throws IOException {
socket.getInputStream();
}
}
static class OutputStreamGetter extends StreamGetter {
public OutputStreamGetter(Socket s) { super(s); }
void getStream() throws IOException {
socket.getOutputStream();
}
}
}

View file

@ -0,0 +1,118 @@
/*
* Copyright (c) 2007, 2019, 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 6505016
* @library /test/lib
* @summary Socket spec should clarify what getInetAddress/getPort/etc return
* after the Socket is closed
* @run main TestAfterClose
* @run main/othervm -Djava.net.preferIPv4Stack=true TestAfterClose
*/
import java.net.*;
import java.io.*;
import jdk.test.lib.net.IPSupport;
public class TestAfterClose
{
static int failCount;
public static void main(String[] args) {
IPSupport.throwSkippedExceptionIfNonOperational();
try {
InetAddress loopback = InetAddress.getLoopbackAddress();
ServerSocket ss = new ServerSocket(0, 0, loopback);
Socket socket = new Socket(loopback, ss.getLocalPort());
ss.accept();
ss.close();
test(socket);
} catch (IOException ioe) {
ioe.printStackTrace();
}
if (failCount > 0)
throw new RuntimeException("Failed: failcount = " + failCount);
}
static void test(Socket socket) throws IOException {
//Before Close
int socketPort = socket.getPort();
InetAddress socketInetAddress = socket.getInetAddress();
SocketAddress socketRemoteSocketAddress = socket.getRemoteSocketAddress();
int socketLocalPort = socket.getLocalPort();
//After Close
socket.close();
if (socketPort != socket.getPort()) {
System.out.println("Socket.getPort failed");
failCount++;
}
if (!socket.getInetAddress().equals(socketInetAddress)) {
System.out.println("Socket.getInetAddress failed");
failCount++;
}
if (!socket.getRemoteSocketAddress().equals(socketRemoteSocketAddress)) {
System.out.println("Socket.getRemoteSocketAddresss failed");
failCount++;
}
if (socketLocalPort != socket.getLocalPort()) {
System.out.println("Socket.getLocalPort failed");
failCount++;
}
InetAddress anyAddr = null;
try {
anyAddr = InetAddress.getByAddress("",new byte[] {0,0,0,0});
} catch (UnknownHostException uhe) {
}
if (anyAddr != null && !socket.getLocalAddress().equals(anyAddr)) {
System.out.println("Socket.getLocalAddress failed");
failCount++;
}
InetSocketAddress addr = new InetSocketAddress(socket.getLocalPort());
if (!socket.getLocalSocketAddress().equals(addr)) {
System.out.println("Socket.getLocalSocketAddress failed");
failCount++;
}
if (!socket.isConnected()) {
System.out.println("Socket.isConnected failed");
failCount++;
}
if (!socket.isBound()) {
System.out.println("Socket.isBound failed");
failCount++;
}
}
}

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2001, 2019, 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 4408755
* @library /test/lib
* @summary This tests whether it's possible to get some informations
* out of a closed socket. This is for backward compatibility
* purposes.
* @run main TestClose
* @run main/othervm -Djava.net.preferIPv4Stack=true TestClose
*/
import java.net.*;
import jdk.test.lib.net.IPSupport;
public class TestClose {
public static void main(String[] args) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
ServerSocket ss;
Socket s;
InetAddress ad1, ad2;
int port1, port2, serverport;
InetAddress loopback = InetAddress.getLoopbackAddress();
ss = new ServerSocket();
ss.bind(new InetSocketAddress(loopback, 0));
serverport = ss.getLocalPort();
s = new Socket(loopback, serverport);
s.close();
ss.close();
ad1 = ss.getInetAddress();
if (ad1 == null)
throw new RuntimeException("ServerSocket.getInetAddress() returned null");
port1 = ss.getLocalPort();
if (port1 != serverport)
throw new RuntimeException("ServerSocket.getLocalPort() returned the wrong value");
ad2 = s.getInetAddress();
if (ad2 == null)
throw new RuntimeException("Socket.getInetAddress() returned null");
port2 = s.getPort();
if (port2 != serverport)
throw new RuntimeException("Socket.getPort() returned wrong value");
ad2 = s.getLocalAddress();
if (ad2 == null)
throw new RuntimeException("Socket.getLocalAddress() returned null");
port2 = s.getLocalPort();
if (port2 == -1)
throw new RuntimeException("Socket.getLocalPort returned -1");
}
}

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2006, 2018, 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 6404388
* @library /test/lib
* @summary VISTA: Socket setTcpNoDelay & setKeepAlive working incorrectly
* @run main TestTcpNoDelay
* @run main/othervm -Djava.net.preferIPv4Stack=true TestTcpNoDelay
*/
import java.net.*;
import java.io.IOException;
import jdk.test.lib.net.IPSupport;
public class TestTcpNoDelay
{
public static void main(String[] args) {
IPSupport.throwSkippedExceptionIfNonOperational();
try {
Socket socket = new Socket();
boolean on = socket.getTcpNoDelay();
System.out.println("Get TCP_NODELAY = " + on);
boolean opposite = on ? false: true;
System.out.println("Set TCP_NODELAY to " + opposite);
socket.setTcpNoDelay(opposite);
boolean noDelay = socket.getTcpNoDelay();
System.out.println("Get TCP_NODELAY = " + noDelay);
if (noDelay != opposite)
throw new RuntimeException("setTcpNoDelay no working as expected");
} catch (IOException e){
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 1998, 2018, 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 4163126
* @library /test/lib
* @summary test to see if timeout hangs
* @run main/timeout=15 Timeout
* @run main/othervm/timeout=15 -Djava.net.preferIPv4Stack=true Timeout
*/
import java.net.*;
import java.io.*;
import jdk.test.lib.net.IPSupport;
public class Timeout {
public static void main(String[] args) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
boolean success = false;
ServerSocket sock = new ServerSocket(0);
try {
sock.setSoTimeout(2);
sock.accept();
} catch (InterruptedIOException e) {
success = true;
} finally {
sock.close();
}
if (!success)
throw new RuntimeException("Socket timeout failure.");
}
}

View file

@ -0,0 +1,705 @@
/*
* Copyright (c) 2019, 2025, 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 8221481 8358496
* @library /test/lib
* @build jdk.test.lib.Utils
* @run junit/othervm/timeout=180 Timeouts
* @summary Test Socket timeouts
*/
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.*;
import jdk.test.lib.Utils;
class Timeouts {
/**
* Test timed connect where connection is established.
*/
@Test
void testTimedConnect1() throws IOException {
try (ServerSocket ss = boundServerSocket()) {
try (Socket s = new Socket()) {
s.connect(ss.getLocalSocketAddress(), 2000);
}
}
}
/**
* Test timed connect where connection is refused.
*/
@Test
void testTimedConnect2() throws IOException {
try (Socket s = new Socket()) {
SocketAddress remote = Utils.refusingEndpoint();
assertThrows(ConnectException.class, () -> s.connect(remote, 10000));
}
}
/**
* Test connect with a timeout of Integer.MAX_VALUE.
*/
@Test
void testTimedConnect3() throws IOException {
try (ServerSocket ss = boundServerSocket()) {
try (Socket s = new Socket()) {
s.connect(ss.getLocalSocketAddress(), Integer.MAX_VALUE);
}
}
}
/**
* Test connect with a negative timeout.
*/
@Test
void testTimedConnect4() throws IOException {
try (ServerSocket ss = boundServerSocket()) {
try (Socket s = new Socket()) {
assertThrows(IllegalArgumentException.class,
() -> s.connect(ss.getLocalSocketAddress(), -1));
}
}
}
/**
* Test timed read where the read succeeds immediately.
*/
@Test
void testTimedRead1() throws IOException {
withConnection((s1, s2) -> {
s1.getOutputStream().write(99);
s2.setSoTimeout(30*1000);
int b = s2.getInputStream().read();
assertEquals(99, b);
});
}
/**
* Test timed read where the read succeeds after a delay.
*/
@Test
void testTimedRead2() throws IOException {
withConnection((s1, s2) -> {
scheduleWrite(s1.getOutputStream(), 99, 2000);
s2.setSoTimeout(30*1000);
int b = s2.getInputStream().read();
assertEquals(99, b);
});
}
/**
* Test timed read where the read times out.
*/
@Test
void testTimedRead3() throws IOException {
withConnection((s1, s2) -> {
s2.setSoTimeout(2000);
long startMillis = millisTime();
assertThrows(SocketTimeoutException.class, () -> s2.getInputStream().read());
int timeout = s2.getSoTimeout();
checkDuration(startMillis, timeout-100, timeout+20_000);
});
}
/**
* Test timed read that succeeds after a previous read has timed out.
*/
@Test
void testTimedRead4() throws IOException {
withConnection((s1, s2) -> {
s2.setSoTimeout(2000);
assertThrows(SocketTimeoutException.class, () -> s2.getInputStream().read());
s1.getOutputStream().write(99);
int b = s2.getInputStream().read();
assertEquals(99, b);
});
}
/**
* Test timed read that succeeds after a previous read has timed out and
* after a short delay.
*/
@Test
void testTimedRead5() throws IOException {
withConnection((s1, s2) -> {
s2.setSoTimeout(2000);
assertThrows(SocketTimeoutException.class, () -> s2.getInputStream().read());
s2.setSoTimeout(30*3000);
scheduleWrite(s1.getOutputStream(), 99, 2000);
int b = s2.getInputStream().read();
assertEquals(99, b);
});
}
/**
* Test untimed read that succeeds after a previous read has timed out.
*/
@Test
void testTimedRead6() throws IOException {
withConnection((s1, s2) -> {
s2.setSoTimeout(2000);
assertThrows(SocketTimeoutException.class, () -> s2.getInputStream().read());
s1.getOutputStream().write(99);
s2.setSoTimeout(0);
int b = s2.getInputStream().read();
assertEquals(99, b);
});
}
/**
* Test untimed read that succeeds after a previous read has timed out and
* after a short delay.
*/
@Test
void testTimedRead7() throws IOException {
withConnection((s1, s2) -> {
s2.setSoTimeout(2000);
assertThrows(SocketTimeoutException.class, () -> s2.getInputStream().read());
scheduleWrite(s1.getOutputStream(), 99, 2000);
s2.setSoTimeout(0);
int b = s2.getInputStream().read();
assertEquals(99, b);
});
}
/**
* Test async close of timed read.
*/
@Test
void testTimedRead8() throws IOException {
withConnection((s1, s2) -> {
s2.setSoTimeout(30*1000);
scheduleClose(s2, 2000);
assertThrows(SocketException.class, () -> s2.getInputStream().read());
});
}
/**
* Test read with a timeout of Integer.MAX_VALUE.
*/
@Test
void testTimedRead9() throws IOException {
withConnection((s1, s2) -> {
scheduleWrite(s1.getOutputStream(), 99, 2000);
s2.setSoTimeout(Integer.MAX_VALUE);
int b = s2.getInputStream().read();
assertEquals(99, b);
});
}
/**
* Test 100 threads concurrently reading the same Socket with a timeout of 2s.
* Each read should throw SocketTimeoutException after 2s, not 2s for the first,
* 4s for the second, 6s for the third, up to 200s for the last thread.
*/
@Test
void testTimedRead10() throws Exception {
var futures = new ArrayList<Future<?>>();
withConnection((_, s) -> {
s.setSoTimeout(2000);
Callable<?> timedReadTask = () -> {
long startMillis = millisTime();
assertThrows(SocketTimeoutException.class,
() -> s.getInputStream().read());
int timeout = s.getSoTimeout();
checkDuration(startMillis, timeout-100, timeout+20_000);
return null;
};
// start 100 virtual threads to read from the socket
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 100; i++) {
Future<?> future = executor.submit(timedReadTask);
futures.add(future);
}
}
});
for (Future<?> future : futures) {
future.get();
}
}
/**
* Test writing after a timed read.
*/
@Test
void testTimedWrite1() throws IOException {
withConnection((s1, s2) -> {
s1.getOutputStream().write(99);
s2.setSoTimeout(3000);
int b = s2.getInputStream().read();
assertEquals(99, b);
// schedule thread to read s1 to EOF
scheduleReadToEOF(s1.getInputStream(), 3000);
// write a lot so that write blocks
byte[] data = new byte[128*1024];
for (int i = 0; i < 100; i++) {
s2.getOutputStream().write(data);
}
});
}
/**
* Test async close of writer (after a timed read).
*/
@Test
void testTimedWrite2() throws IOException {
withConnection((s1, s2) -> {
s1.getOutputStream().write(99);
s2.setSoTimeout(3000);
int b = s2.getInputStream().read();
assertEquals(99, b);
// schedule s2 to be closed
scheduleClose(s2, 3000);
// write a lot so that write blocks
byte[] data = new byte[128*1024];
try {
while (true) {
s2.getOutputStream().write(data);
}
} catch (SocketException expected) { }
});
}
/**
* Test timed accept where a connection is established immediately.
*/
@Test
void testTimedAccept1() throws IOException {
Socket s1 = null;
Socket s2 = null;
try (ServerSocket ss = boundServerSocket()) {
s1 = new Socket();
s1.connect(ss.getLocalSocketAddress());
ss.setSoTimeout(30*1000);
s2 = ss.accept();
} finally {
if (s1 != null) s1.close();
if (s2 != null) s2.close();
}
}
/**
* Test timed accept where a connection is established after a short delay.
*/
@Test
void testTimedAccept2() throws IOException {
try (ServerSocket ss = boundServerSocket()) {
ss.setSoTimeout(30*1000);
scheduleConnect(ss.getLocalSocketAddress(), 2000);
Socket s = ss.accept();
s.close();
}
}
/**
* Test timed accept where the accept times out
*/
@Test
void testTimedAccept3() throws IOException {
try (ServerSocket ss = boundServerSocket()) {
ss.setSoTimeout(2000);
long startMillis = millisTime();
try {
Socket s = ss.accept();
s.close();
fail();
} catch (SocketTimeoutException expected) {
int timeout = ss.getSoTimeout();
checkDuration(startMillis, timeout-100, timeout+20_000);
}
}
}
/**
* Test timed accept where a connection is established immediately after a
* previous accept timed out.
*/
@Test
void testTimedAccept4() throws IOException {
try (ServerSocket ss = boundServerSocket()) {
ss.setSoTimeout(2000);
try {
Socket s = ss.accept();
s.close();
fail();
} catch (SocketTimeoutException expected) { }
try (Socket s1 = new Socket()) {
s1.connect(ss.getLocalSocketAddress());
Socket s2 = ss.accept();
s2.close();
}
}
}
/**
* Test untimed accept where a connection is established after a previous
* accept timed out.
*/
@Test
void testTimedAccept5() throws IOException {
try (ServerSocket ss = boundServerSocket()) {
ss.setSoTimeout(2000);
try {
Socket s = ss.accept();
s.close();
fail();
} catch (SocketTimeoutException expected) { }
ss.setSoTimeout(0);
try (Socket s1 = new Socket()) {
s1.connect(ss.getLocalSocketAddress());
Socket s2 = ss.accept();
s2.close();
}
}
}
/**
* Test untimed accept where a connection is established after a previous
* accept timed out and after a short delay.
*/
@Test
void testTimedAccept6() throws IOException {
try (ServerSocket ss = boundServerSocket()) {
ss.setSoTimeout(2000);
try {
Socket s = ss.accept();
s.close();
fail();
} catch (SocketTimeoutException expected) { }
ss.setSoTimeout(0);
scheduleConnect(ss.getLocalSocketAddress(), 2000);
Socket s = ss.accept();
s.close();
}
}
/**
* Test async close of a timed accept.
*/
@Test
void testTimedAccept7() throws IOException {
try (ServerSocket ss = boundServerSocket()) {
ss.setSoTimeout(30*1000);
long delay = 2000;
scheduleClose(ss, delay);
long startMillis = millisTime();
try {
ss.accept().close();
fail();
} catch (SocketException expected) {
checkDuration(startMillis, delay-100, delay+20_000);
}
}
}
/**
* Test timed accept with the thread interrupted status set.
*/
@Test
void testTimedAccept8() throws IOException {
assumeFalse(Thread.currentThread().isVirtual(), "Main test is a virtual thread");
try (ServerSocket ss = boundServerSocket()) {
ss.setSoTimeout(2000);
Thread.currentThread().interrupt();
long startMillis = millisTime();
try {
Socket s = ss.accept();
s.close();
fail();
} catch (SocketTimeoutException expected) {
// accept should have blocked for 2 seconds
int timeout = ss.getSoTimeout();
checkDuration(startMillis, timeout-100, timeout+20_000);
assertTrue(Thread.currentThread().isInterrupted());
} finally {
Thread.interrupted(); // clear interrupted status
}
}
}
/**
* Test interrupt of thread blocked in timed accept.
*/
@Test
void testTimedAccept9() throws IOException {
assumeFalse(Thread.currentThread().isVirtual(), "Main test is a virtual thread");
try (ServerSocket ss = boundServerSocket()) {
ss.setSoTimeout(4000);
// interrupt thread after 1 second
Future<?> interrupter = scheduleInterrupt(Thread.currentThread(), 1000);
long startMillis = millisTime();
try {
Socket s = ss.accept(); // should block for 4 seconds
s.close();
fail();
} catch (SocketTimeoutException expected) {
// accept should have blocked for 4 seconds
int timeout = ss.getSoTimeout();
checkDuration(startMillis, timeout-100, timeout+20_000);
assertTrue(Thread.currentThread().isInterrupted());
} finally {
interrupter.cancel(true);
Thread.interrupted(); // clear interrupted status
}
}
}
/**
* Test two threads blocked in timed accept where no connection is established.
*/
@Test
void testTimedAccept10() throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(2);
try (ServerSocket ss = boundServerSocket()) {
ss.setSoTimeout(4000);
long startMillis = millisTime();
Future<Socket> result1 = pool.submit(ss::accept);
Future<Socket> result2 = pool.submit(ss::accept);
// both tasks should complete with SocketTimeoutException
Throwable e = assertThrows(ExecutionException.class, result1::get);
assertTrue(e.getCause() instanceof SocketTimeoutException);
e = assertThrows(ExecutionException.class, result2::get);
assertTrue(e.getCause() instanceof SocketTimeoutException);
// should get here in 4 seconds, not 8 seconds
int timeout = ss.getSoTimeout();
checkDuration(startMillis, timeout-100, timeout+20_000);
} finally {
pool.shutdown();
}
}
/**
* Test two threads blocked in timed accept where one connection is established.
*/
@Test
void testTimedAccept11() throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(2);
try (ServerSocket ss = boundServerSocket()) {
ss.setSoTimeout(4000);
long startMillis = millisTime();
Future<Socket> result1 = pool.submit(ss::accept);
Future<Socket> result2 = pool.submit(ss::accept);
// establish connection after 2 seconds
scheduleConnect(ss.getLocalSocketAddress(), 2000);
// one task should have accepted the connection, the other should
// have completed with SocketTimeoutException
Socket s1 = null;
try {
s1 = result1.get();
s1.close();
} catch (ExecutionException e) {
assertTrue(e.getCause() instanceof SocketTimeoutException);
}
Socket s2 = null;
try {
s2 = result2.get();
s2.close();
} catch (ExecutionException e) {
assertTrue(e.getCause() instanceof SocketTimeoutException);
}
assertTrue((s1 != null) ^ (s2 != null));
// should get here in 4 seconds, not 8 seconds
int timeout = ss.getSoTimeout();
checkDuration(startMillis, timeout-100, timeout+20_000);
} finally {
pool.shutdown();
}
}
/**
* Test Socket setSoTimeout with a negative timeout.
*/
@Test
void testBadTimeout1() throws IOException {
try (Socket s = new Socket()) {
assertThrows(IllegalArgumentException.class, () -> s.setSoTimeout(-1));
}
}
/**
* Test ServerSocket setSoTimeout with a negative timeout.
*/
@Test
void testBadTimeout2() throws IOException {
try (ServerSocket ss = new ServerSocket()) {
assertThrows(IllegalArgumentException.class, () -> ss.setSoTimeout(-1));
}
}
/**
* Returns a ServerSocket bound to a port on the loopback address.
*/
static ServerSocket boundServerSocket() throws IOException {
var loopback = InetAddress.getLoopbackAddress();
ServerSocket ss = new ServerSocket();
ss.bind(new InetSocketAddress(loopback, 0));
return ss;
}
/**
* An operation that accepts two arguments and may throw IOException.
*/
interface ThrowingBiConsumer<T, U> {
void accept(T t, U u) throws IOException;
}
/**
* Invokes the consumer with a connected pair of sockets.
*/
static void withConnection(ThrowingBiConsumer<Socket, Socket> consumer)
throws IOException
{
Socket s1 = null;
Socket s2 = null;
try (ServerSocket ss = boundServerSocket()) {
s1 = new Socket();
s1.connect(ss.getLocalSocketAddress());
s2 = ss.accept();
consumer.accept(s1, s2);
} finally {
if (s1 != null) s1.close();
if (s2 != null) s2.close();
}
}
/**
* Schedule c to be closed after a delay.
*/
static void scheduleClose(Closeable c, long delay) {
schedule(() -> {
try {
c.close();
} catch (IOException ioe) { }
}, delay);
}
/**
* Schedule thread to be interrupted after a delay.
*/
static Future<?> scheduleInterrupt(Thread thread, long delay) {
return schedule(() -> thread.interrupt(), delay);
}
/**
* Schedule a thread to connect to the given end point after a delay.
*/
static void scheduleConnect(SocketAddress remote, long delay) {
schedule(() -> {
try (Socket s = new Socket()) {
s.connect(remote);
} catch (IOException ioe) { }
}, delay);
}
/**
* Schedule a thread to read to EOF after a delay.
*/
static void scheduleReadToEOF(InputStream in, long delay) {
schedule(() -> {
byte[] bytes = new byte[8192];
try {
while (in.read(bytes) != -1) { }
} catch (IOException ioe) { }
}, delay);
}
/**
* Schedule a thread to write after a delay.
*/
static void scheduleWrite(OutputStream out, byte[] data, long delay) {
schedule(() -> {
try {
out.write(data);
} catch (IOException ioe) { }
}, delay);
}
static void scheduleWrite(OutputStream out, int b, long delay) {
scheduleWrite(out, new byte[] { (byte)b }, delay);
}
static Future<?> schedule(Runnable task, long delay) {
return ForkJoinPool.commonPool().schedule(task, delay, TimeUnit.MILLISECONDS);
}
/**
* Returns the current time in milliseconds.
*/
private static long millisTime() {
long now = System.nanoTime();
return TimeUnit.MILLISECONDS.convert(now, TimeUnit.NANOSECONDS);
}
/**
* Check the duration of a task.
* @param start start time, in milliseconds
* @param min minimum expected duration, in milliseconds
* @param max maximum expected duration, in milliseconds
* @return the duration (now - start), in milliseconds
*/
private static long checkDuration(long start, long min, long max) {
long duration = millisTime() - start;
assertTrue(duration >= min,
"Duration " + duration + "ms, expected >= " + min + "ms");
assertTrue(duration <= max,
"Duration " + duration + "ms, expected <= " + max + "ms");
return duration;
}
}

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2001, 2018, 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 4511783
* @library /test/lib
* @summary Test that setTrafficClass/getTraffiClass don't
* throw an exception
* @run main TrafficClass
* @run main/othervm -Djava.net.preferIPv4Stack=true TrafficClass
*/
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import jdk.test.lib.net.IPSupport;
public class TrafficClass {
static final int IPTOS_RELIABILITY = 0x4;
static int failures = 0;
static void testDatagramSocket(DatagramSocket s) {
try {
s.setTrafficClass( IPTOS_RELIABILITY );
int tc = s.getTrafficClass();
} catch (Exception e) {
failures++;
System.err.println("testDatagramSocket failed: " + e);
}
}
static void testSocket(Socket s) {
try {
s.setTrafficClass(IPTOS_RELIABILITY);
int tc = s.getTrafficClass();
} catch (Exception e) {
failures++;
System.err.println("testSocket failed: " + e);
}
}
public static void main(String args[]) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
DatagramSocket ds = new DatagramSocket();
testDatagramSocket(ds);
DatagramChannel dc = DatagramChannel.open();
testDatagramSocket(dc.socket());
Socket s = new Socket();
testSocket(s);
SocketChannel sc = SocketChannel.open();
testSocket(sc.socket());
if (failures > 0) {
throw new Exception(failures + " sub-test(s) failed - " +
"see log for details.");
}
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2019, 2025, 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.
*/
import java.net.InetAddress;
import java.net.Socket;
import org.testng.annotations.Test;
import static org.testng.Assert.fail;
/*
* @test
* @summary Basic test for the UDP sockets through the java.net.Socket constructors
* @run testng UdpSocket
*/
public class UdpSocket {
/**
* Verifies that the {@code Socket} constructors that take the {@code stream}
* parameter don't allow construction of UDP sockets.
*/
@Test
public void testUDPConstructors() throws Exception {
try {
new Socket("doesnotmatter", 12345, false);
fail("Socket constructor was expected to throw IllegalArgumentException" +
" for stream=false, but didn't");
} catch (IllegalArgumentException iae) {
// verify it's thrown for the right reason
assertExceptionMessage(iae);
}
try {
new Socket(InetAddress.getLoopbackAddress(), 12345, false);
fail("Socket constructor was expected to throw IllegalArgumentException" +
" for stream=false, but didn't");
} catch (IllegalArgumentException iae) {
// verify it's thrown for the right reason
assertExceptionMessage(iae);
}
}
private static void assertExceptionMessage(final IllegalArgumentException iae) {
final String msg = iae.getMessage();
if (msg != null && msg.contains(
"Socket constructor does not support creation of datagram socket")) {
// contains the expected message
return;
}
// unexpected exception message, propagate the original exception
throw iae;
}
}

View file

@ -0,0 +1,160 @@
/*
* Copyright (c) 2001, 2019, 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 4092038
* @library /test/lib
* @summary TCP Urgent data support
* @run main UrgentDataTest
* @run main/othervm -Djava.net.preferIPv4Stack=true UrgentDataTest
*/
import java.net.*;
import java.io.*;
import jdk.test.lib.net.IPSupport;
public class UrgentDataTest {
Object opref;
boolean isClient, isServer;
String clHost;
ServerSocket listener;
Socket client, server;
int clPort;
InputStream clis, sis;
OutputStream clos, sos;
static void usage () {
System.out.println (" usage: java UrgentDataTest <runs client and server together>");
System.out.println (" usage: java UrgentDataTest -server <runs server alone>");
System.out.println (" usage: java UrgentDataTest -client host port <runs client and connects to"+
" specified server>");
}
public static void main (String args[]) {
IPSupport.throwSkippedExceptionIfNonOperational();
try {
UrgentDataTest test = new UrgentDataTest ();
if (args.length == 0) {
InetAddress loopback = InetAddress.getLoopbackAddress();
test.listener = new ServerSocket ();
test.listener.bind(new InetSocketAddress(loopback, 0));
test.isClient = true;
test.isServer = true;
test.clHost = loopback.getHostAddress();
test.clPort = test.listener.getLocalPort();
test.run();
} else if (args[0].equals ("-server")) {
test.listener = new ServerSocket (0);
System.out.println ("Server listening on port " + test.listener.getLocalPort());
test.isClient = false;
test.isServer = true;
test.run();
System.out.println ("Server: Completed OK");
} else if (args[0].equals ("-client")) {
test.isClient = true;
test.isServer = false;
test.clHost = args [1];
test.clPort = Integer.parseInt (args[2]);
test.run();
System.out.println ("Client: Completed OK");
} else {
usage ();
}
}
catch (ArrayIndexOutOfBoundsException e) {
usage();
}
catch (NumberFormatException e) {
usage();
}
catch (Exception e) {
e.printStackTrace ();
throw new RuntimeException ("Exception caught");
}
}
public void run () throws Exception {
try {
if (isClient) {
client = new Socket (clHost, clPort);
clis = client.getInputStream();
clos = client.getOutputStream();
client.setOOBInline (true);
if (client.getOOBInline() != true) {
throw new RuntimeException ("Setting OOBINLINE failed");
}
}
if (isServer) {
server = listener.accept ();
sis = server.getInputStream();
sos = server.getOutputStream();
}
if (isClient) {
clos.write ("Hello".getBytes ());
client.sendUrgentData (100);
clos.write ("world".getBytes ());
}
// read Hello world from server (during which oob byte must have been dropped)
String s = "Helloworld";
if (isServer) {
for (int y=0; y<s.length(); y++) {
int c = sis.read ();
if (c != (int)s.charAt (y)) {
throw new RuntimeException ("Unexpected character read");
}
}
// Do the same from server to client
sos.write ("Hello".getBytes ());
server.sendUrgentData (101);
sos.write ("World".getBytes ());
}
if (isClient) {
// read Hello world from client (during which oob byte must have been read)
s="Hello";
for (int y=0; y<s.length(); y++) {
int c = clis.read ();
if (c != (int)s.charAt (y)) {
throw new RuntimeException ("Unexpected character read");
}
}
if (clis.read() != 101) {
throw new RuntimeException ("OOB byte not received");
}
s="World";
for (int y=0; y<s.length(); y++) {
int c = clis.read ();
if (c != (int)s.charAt (y)) {
throw new RuntimeException ("Unexpected character read");
}
}
}
} finally {
if (listener != null) listener.close();
if (client != null) client.close ();
if (server != null) server.close ();
}
}
}

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2001, 2021, 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.
*/
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import jdk.test.lib.net.IPSupport;
import static java.util.concurrent.CompletableFuture.*;
/*
* @test
* @bug 4344135
* @library /test/lib
* @summary Check that {Socket,ServerSocket,DatagramSocket}.close will
* cause any thread blocked on the socket to throw a SocketException.
* @run main AsyncClose
* @run main/othervm -Djava.net.preferIPv4Stack=true AsyncClose
*/
public class AsyncClose {
public static void main(String args[]) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
AsyncCloseTest tests[] = {
new Socket_getInputStream_read(),
new Socket_getInputStream_read(20000),
new Socket_getOutputStream_write(),
new DatagramSocket_receive(),
new DatagramSocket_receive(20000),
new ServerSocket_accept(),
new ServerSocket_accept(20000),
};
int failures = 0;
List<CompletableFuture<AsyncCloseTest>> cfs = new ArrayList<>();
for (AsyncCloseTest test : tests)
cfs.add( supplyAsync(() -> test.go()));
for (CompletableFuture<AsyncCloseTest> cf : cfs) {
AsyncCloseTest test = cf.get();
System.out.println("******************************");
System.out.println("Test: " + test.description());
if (test.hasPassed()) {
System.out.println("Passed.");
} else {
System.out.println("Failed: " + test.failureReason());
failures++;
}
System.out.println("");
}
if (failures > 0)
throw new Exception(failures + " sub-tests failed - see log.");
}
}

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2001, 2018, 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.
*/
/*
* Abstract class representing an asynchronous close test - subclasses
* should override description() and go() methods.
*/
public abstract class AsyncCloseTest {
public abstract String description();
public abstract AsyncCloseTest go();
public synchronized boolean hasPassed() {
return passed;
}
protected synchronized AsyncCloseTest passed() {
if (failureReason() == null) {
passed = true;
}
return this;
}
protected synchronized AsyncCloseTest failed(String r) {
passed = false;
reason.append(String.format("%n - %s", r));
return this;
}
public synchronized String failureReason() {
return reason.length() > 0 ? reason.toString() : null;
}
protected synchronized void closed() {
closed = true;
}
protected synchronized boolean isClosed() {
return closed;
}
private boolean passed;
private final StringBuilder reason = new StringBuilder();
private boolean closed;
}

View file

@ -0,0 +1,84 @@
/*
* Copyright (c) 2001, 2019, 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 4511404
* @library /test/lib
* @summary Check that a broken pipe error doesn't throw an exception
* indicating the socket is closed.
* @run main BrokenPipe
* @run main/othervm -Djava.net.preferIPv4Stack=true BrokenPipe
*/
import java.io.*;
import java.net.*;
import jdk.test.lib.net.IPSupport;
public class BrokenPipe {
private static class Closer implements Runnable {
private final Socket s;
Closer(Socket s) {
this.s = s;
}
public void run() {
try {
/* gives time for 'write' to block */
Thread.sleep(5000);
s.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
ServerSocket ss = new ServerSocket(0, 0, InetAddress.getLocalHost());
Socket client = new Socket(InetAddress.getLocalHost(),
ss.getLocalPort());
Socket server = ss.accept();
ss.close();
new Thread(new Closer(server)).start();
try {
client.getOutputStream().write(new byte[1000000]);
} catch (IOException ioe) {
/*
* Check that the exception text doesn't indicate the
* socket is closed. In tiger we should be able to
* replace this by catching a more specific exception.
*/
String text = ioe.getMessage();
if (text.toLowerCase().indexOf("closed") >= 0) {
throw ioe;
}
} finally {
server.close();
}
}
}

View file

@ -0,0 +1,104 @@
/*
* Copyright (c) 2001, 2019, 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.
*/
/*
* Tests that a thread blocked in DatagramSocket.receive
* throws a SocketException if the socket is asynchronously closed.
*/
import java.net.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
public class DatagramSocket_receive extends AsyncCloseTest implements Runnable {
private final DatagramSocket s;
private final int timeout;
private final CountDownLatch latch;
private final AtomicBoolean readyToClose = new AtomicBoolean(false);
public DatagramSocket_receive() throws SocketException {
this(0);
}
public DatagramSocket_receive(int timeout) throws SocketException {
this.timeout = timeout;
latch = new CountDownLatch(1);
s = new DatagramSocket(0, InetAddress.getLoopbackAddress());
}
public String description() {
String s = "DatagramSocket.receive(DatagramPacket)";
if (timeout > 0) {
s += " (timeout specified)";
}
return s;
}
public void run() {
try {
byte b[] = new byte[1024];
DatagramPacket p = new DatagramPacket(b, b.length);
if (timeout > 0) {
s.setSoTimeout(timeout);
}
latch.countDown();
do {
// if readyToClose is still false it means some other
// process on the system attempted to send datagram packet:
// just ignore it, and go back to accept again.
s.receive(p);
} while (!readyToClose.get());
failed("DatagramSocket.receive(DatagramPacket) returned unexpectedly!!" + " - " + p.getAddress());
} catch (SocketException se) {
if (latch.getCount() != 1) {
closed();
}
} catch (Exception e) {
failed(e.getMessage());
} finally {
if (latch.getCount() == 1) {
latch.countDown();
}
}
}
public AsyncCloseTest go() {
try {
Thread thr = new Thread(this);
thr.start();
latch.await();
Thread.sleep(5000); //sleep, so receive(DatagramPacket) can block
readyToClose.set(true);
s.close();
thr.join();
if (isClosed()) {
return passed();
} else {
return failed("DatagramSocket.receive(DatagramPacket) wasn't preempted");
}
} catch (Exception x) {
failed(x.getMessage());
throw new RuntimeException(x);
}
}
}

View file

@ -0,0 +1,244 @@
/*
* Copyright (c) 2023, 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 8278326
* @modules java.base/java.net:+open
* @run junit Leaky
* @summary Test async close when binding, connecting, or reading a socket option
*/
import java.io.FileDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketImpl;
import java.net.SocketOption;
import java.net.StandardSocketOptions;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import org.junit.*;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;
public class Leaky {
private static ScheduledExecutorService executor;
private static ServerSocket listener;
@BeforeAll
public static void setup() throws Exception {
listener = new ServerSocket();
listener.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
executor = Executors.newScheduledThreadPool(2);
}
@AfterAll
public static void finish() throws Exception {
executor.close();
listener.close();
}
/**
* Race Socket bind and close.
*/
@RepeatedTest(100)
public void raceBindAndClose() throws Exception {
Socket socket = new Socket();
race(socket::close, () -> {
try {
socket.bind(new InetSocketAddress(0));
} catch (IOException ioe) {
if (!socket.isClosed()) {
throw ioe;
}
}
});
// check that there isn't an open socket
SocketImpl psi = getPlatformSocketImpl(socket);
assertFalse(isSocketOpen(psi));
}
/**
* Race Socket connect and close.
*/
@RepeatedTest(100)
public void raceConnectAndClose() throws Exception {
Socket socket = new Socket();
race(socket::close, () -> {
try {
socket.connect(listener.getLocalSocketAddress());
// if connected, need to close other end
listener.accept().close();
} catch (IOException ioe) {
if (!socket.isClosed()) {
throw ioe;
}
}
});
// check that there isn't an open socket
SocketImpl psi = getPlatformSocketImpl(socket);
assertFalse(isSocketOpen(psi));
}
/**
* Race Socket getOption and close.
*/
@RepeatedTest(100)
public void raceGetOptionAndClose() throws Exception {
Socket socket = new Socket();
race(socket::close, () -> {
try {
socket.getOption(StandardSocketOptions.SO_REUSEADDR);
} catch (IOException ioe) {
if (!socket.isClosed()) {
throw ioe;
}
}
});
// check that there isn't an open socket
SocketImpl psi = getPlatformSocketImpl(socket);
assertFalse(isSocketOpen(psi));
}
/**
* A task that may throw an exception.
*/
private interface ThrowingRunnable {
void run() throws Exception;
}
/**
* Staggers two tasks to execute after random delays.
*/
private void race(ThrowingRunnable task1, ThrowingRunnable task2) throws Exception {
int delay1 = ThreadLocalRandom.current().nextInt(10);
int delay2 = ThreadLocalRandom.current().nextInt(10);
Future<Void> future1 = executor.schedule(() -> {
task1.run();
return null;
}, delay1, TimeUnit.MILLISECONDS);
Future<Void> future2 = executor.schedule(() -> {
task2.run();
return null;
}, delay2, TimeUnit.MILLISECONDS);
ExecutionException e = null;
try {
future1.get();
} catch (ExecutionException e1) {
e = e1;
}
try {
future2.get();
} catch (ExecutionException e2) {
if (e == null) {
e = e2;
} else {
e.addSuppressed(e2);
}
}
if (e != null) {
throw e;
}
}
/**
* Return the underlying PlatformSocketImpl for the given socket.
*/
private static SocketImpl getPlatformSocketImpl(Socket s) {
SocketImpl si = getSocketImpl(s);
return getDelegate(si);
}
/**
* Returns the socket's SocketImpl.
*/
private static SocketImpl getSocketImpl(Socket s) {
try {
Field f = Socket.class.getDeclaredField("impl");
f.setAccessible(true);
return (SocketImpl) f.get(s);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Returns the SocketImpl that the given SocketImpl delegates to.
*/
private static SocketImpl getDelegate(SocketImpl si) {
try {
Class<?> clazz = Class.forName("java.net.DelegatingSocketImpl");
Field f = clazz.getDeclaredField("delegate");
f.setAccessible(true);
return (SocketImpl) f.get(si);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Returns true if the SocketImpl has an open socket.
*/
private static boolean isSocketOpen(SocketImpl si) throws Exception {
// check if SocketImpl.fd is set
Field f = SocketImpl.class.getDeclaredField("fd");
f.setAccessible(true);
FileDescriptor fd = (FileDescriptor) f.get(si);
if (fd == null) {
return false; // not created
}
// call getOption to get the value of the SO_REUSEADDR socket option
Method m = SocketImpl.class.getDeclaredMethod("getOption", SocketOption.class);
m.setAccessible(true);
try {
m.invoke(si, StandardSocketOptions.SO_REUSEADDR);
return true; // socket is open
} catch (InvocationTargetException e) {
if (e.getCause() instanceof IOException) {
return false; // assume socket is closed
}
throw e;
}
}
}

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2013, 2019, 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 8006395 8012244
* @summary Tests racing code that reads and closes a Socket
*/
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.ConnectException;
import java.net.SocketException;
import java.util.concurrent.Phaser;
// Racey test, will not always fail, but if it does then we have a problem.
public class Race {
final static int THREADS = 100;
public static void main(String[] args) throws Exception {
try (ServerSocket ss = new ServerSocket()) {
InetAddress loopback = InetAddress.getLoopbackAddress();
ss.bind(new InetSocketAddress(loopback, 0));
final int port = ss.getLocalPort();
final Phaser phaser = new Phaser(THREADS + 1);
for (int i=0; i<100; i++) {
try {
final Socket s = new Socket(loopback, port);
s.setSoLinger(false, 0);
try (Socket sa = ss.accept()) {
sa.setSoLinger(false, 0);
final InputStream is = s.getInputStream();
Thread[] threads = new Thread[THREADS];
for (int j=0; j<THREADS; j++) {
threads[j] = new Thread() {
public void run() {
try {
phaser.arriveAndAwaitAdvance();
while (is.read() != -1)
Thread.sleep(50);
} catch (Exception x) {
if (!(x instanceof SocketException
&& x.getMessage().equalsIgnoreCase("socket closed")))
x.printStackTrace();
// ok, expect Socket closed
}
}};
}
for (int j=0; j<100; j++)
threads[j].start();
phaser.arriveAndAwaitAdvance();
s.close();
for (int j=0; j<100; j++)
threads[j].join();
}
} catch (ConnectException e) {
System.err.println("Exception " + e + " Port: " + port);
}
}
}
}
}

View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2001, 2019, 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.
*/
/*
* Tests that a thread blocked in ServerSocket.accept
* throws a SocketException if the socket is asynchronously closed.
*/
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
public class ServerSocket_accept extends AsyncCloseTest implements Runnable {
private final ServerSocket ss;
private final int timeout;
private final CountDownLatch latch;
private final AtomicBoolean readyToClose = new AtomicBoolean(false);
public ServerSocket_accept() throws IOException {
this(0);
}
public ServerSocket_accept(int timeout) throws IOException {
this.timeout = timeout;
latch = new CountDownLatch(1);
ss = new ServerSocket(0, 0, InetAddress.getLoopbackAddress());
}
public String description() {
String s = "ServerSocket.accept()";
if (timeout > 0) {
s += " (with timeout)";
}
return s;
}
public void run() {
try {
latch.countDown();
Socket s;
// if readyToClose is still false it means some other
// process on the system attempted to connect: just
// ignore it, and go back to accept again.
do {
s = ss.accept();
} while (!readyToClose.get());
failed("ServerSocket.accept() returned unexpectedly!!" + " - " + s);
} catch (SocketException se) {
closed();
} catch (Exception e) {
failed(e.getMessage());
}
}
public AsyncCloseTest go(){
try {
Thread thr = new Thread(this);
thr.start();
latch.await();
Thread.sleep(5000); //sleep, so ServerSocket.accept() can block
readyToClose.set(true);
ss.close();
thr.join();
if (isClosed()) {
return passed();
} else {
return failed("ServerSocket.accept() wasn't preempted");
}
} catch (Exception x) {
failed(x.getMessage());
throw new RuntimeException(x);
}
}
}

View file

@ -0,0 +1,102 @@
/*
* Copyright (c) 2001, 2024, 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.
*/
/*
* Tests that a thread blocked in Socket.getInputStream().read()
* throws a SocketException if the socket is asynchronously closed.
*/
import java.net.*;
import java.io.*;
import java.util.concurrent.CountDownLatch;
public class Socket_getInputStream_read extends AsyncCloseTest implements Runnable {
private final Socket s;
private final int timeout;
private final CountDownLatch latch;
public Socket_getInputStream_read() {
this(0);
}
public Socket_getInputStream_read(int timeout) {
this.timeout = timeout;
latch = new CountDownLatch(1);
s = new Socket();
}
public String description() {
String s = "Socket.getInputStream().read()";
if (timeout > 0) {
s += " (with timeout)";
}
return s;
}
public void run() {
try {
InputStream in = s.getInputStream();
if (timeout > 0) {
s.setSoTimeout(timeout);
}
latch.countDown();
int n = in.read();
failed("Socket.getInputStream().read() returned unexpectedly, n=" + n);
} catch (SocketException se) {
if (latch.getCount() != 1) {
closed();
}
} catch (Exception e) {
failed(e.getMessage());
} finally {
if (latch.getCount() == 1) {
latch.countDown();
}
}
}
public AsyncCloseTest go() {
try {
InetAddress lh = InetAddress.getLocalHost();
try (ServerSocket ss = new ServerSocket(0, 0, lh)) {
s.connect(new InetSocketAddress(lh, ss.getLocalPort()));
try (Socket s2 = ss.accept()) {
Thread thr = new Thread(this);
thr.start();
latch.await();
Thread.sleep(5000); //sleep, so Socket.getInputStream().read() can block
s.close();
thr.join();
}
if (isClosed()) {
return passed();
} else {
return failed("Socket.getInputStream().read() wasn't preempted");
}
}
} catch (Exception x) {
failed(x.getMessage());
throw new RuntimeException(x);
}
}
}

View file

@ -0,0 +1,91 @@
/*
* Copyright (c) 2001, 2024, 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.
*/
/*
* Tests that a thread blocked in Socket.getOutputStream().write()
* throws a SocketException if the socket is asynchronously closed.
*/
import java.net.*;
import java.io.*;
import java.util.concurrent.CountDownLatch;
public class Socket_getOutputStream_write extends AsyncCloseTest implements Runnable {
private final Socket s;
private final CountDownLatch latch;
public Socket_getOutputStream_write() {
latch = new CountDownLatch(1);
s = new Socket();
}
public String description() {
return "Socket.getOutputStream().write()";
}
public void run() {
try {
OutputStream out = s.getOutputStream();
byte b[] = new byte[8192];
latch.countDown();
for (;;) {
out.write(b);
}
} catch (SocketException se) {
if (latch.getCount() != 1) {
closed();
}
} catch (Exception e) {
failed(e.getMessage());
} finally {
if (latch.getCount() == 1) {
latch.countDown();
}
}
}
public AsyncCloseTest go() {
try {
InetAddress lh = InetAddress.getLocalHost();
try (ServerSocket ss = new ServerSocket(0, 0, lh)) {
s.connect(new InetSocketAddress(lh, ss.getLocalPort()));
try (Socket s2 = ss.accept()) {
Thread thr = new Thread(this);
thr.start();
latch.await();
Thread.sleep(1000);
s.close();
thr.join();
}
if (isClosed()) {
return passed();
} else {
return failed("Socket.getOutputStream().write() wasn't preempted");
}
}
} catch (Exception x) {
failed(x.getMessage());
throw new RuntimeException(x);
}
}
}

View file

@ -0,0 +1,70 @@
/*
* Copyright (c) 2020, 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.
*/
#include<jni.h>
#include<signal.h>
#include<stdlib.h>
#if defined(__linux__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
#include <pthread.h>
#endif
/*
* Class: NativeThread
* Method: getID
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_NativeThread_getID(JNIEnv *env, jclass class)
{
#if defined(__linux__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
return (jlong)pthread_self();
#else
return 0;
#endif
}
/*
* Class: NativeThread
* Method: signal
* Signature: (JI)I
*/
JNIEXPORT jint JNICALL Java_NativeThread_signal(JNIEnv *env, jclass class, jlong thread, jint sig)
{
#if defined(__linux__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
return pthread_kill((pthread_t)thread, sig);
#else
return 0;
#endif
}
/*
* Class: NativeThread
* Method: getSIGPIPE
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_NativeThread_getSIGPIPE(JNIEnv *env, jclass class)
{
#if defined(__linux__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
return SIGPIPE;
#else
return 0;
#endif
}

View file

@ -0,0 +1,235 @@
/*
* Copyright (c) 2001, 2018, 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 4476378
* @library /test/lib
* @summary Check the specific behaviour of the setReuseAddress(boolean)
* method.
* @run main Basic
* @run main/othervm -Dsun.net.useExclusiveBind Basic
* @run main/othervm -Dsun.net.useExclusiveBind=true Basic
* @run main/othervm -Djava.net.preferIPv4Stack=true Basic
* @run main/othervm -Dsun.net.useExclusiveBind
* -Djava.net.preferIPv4Stack=true Basic
* @run main/othervm -Dsun.net.useExclusiveBind=true
* -Djava.net.preferIPv4Stack=true Basic
*/
import java.net.*;
import jdk.test.lib.net.IPSupport;
public class Basic {
static int testCount = 0;
static int failures = 0;
void test(String msg) {
testCount++;
System.out.println("***************************************");
System.out.println("Test " + testCount + ": " + msg);
}
void passed() {
System.out.println("Test passed.");
}
void failed() {
failures++;
System.out.println("Test failed.");
}
void check(boolean pass) {
if (pass) {
passed();
} else {
failed();
}
}
void SocketTests() throws Exception {
Socket s1 = new Socket();
test("Socket should be created with SO_REUSEADDR disabled");
check(!s1.getReuseAddress());
test("Socket.setReuseAddress(true)");
s1.setReuseAddress(true);
check(s1.getReuseAddress());
test("Socket.setReuseAddress(false)");
s1.setReuseAddress(false);
check(!s1.getReuseAddress() );
/* bind to any port */
s1.bind( new InetSocketAddress(0) );
test("Binding Socket to port already in use should throw " +
"a BindException");
Socket s2 = new Socket();
try {
s2.bind( new InetSocketAddress(s1.getLocalPort()) );
failed();
} catch (BindException e) {
passed();
}
s2.close();
s1.close();
}
void ServerSocketTests() throws Exception {
ServerSocket s1 = new ServerSocket();
test("ServerSocket.setReuseAddress(true)");
s1.setReuseAddress(true);
check(s1.getReuseAddress());
test("Socket.setReuseAddress(false)");
s1.setReuseAddress(false);
check(!s1.getReuseAddress() );
/* bind to any port */
s1.bind( new InetSocketAddress(0) );
test("Binding ServerSocket to port already in use should throw " +
"a BindException");
ServerSocket s2 = new ServerSocket();
try {
s2.bind( new InetSocketAddress(s1.getLocalPort()) );
failed();
} catch (BindException e) {
passed();
}
s2.close();
s1.close();
}
void DatagramSocketTests() throws Exception {
DatagramSocket s1 = new DatagramSocket(null);
test("DatagramSocket should be created with SO_REUSEADDR disabled");
check(!s1.getReuseAddress());
test("DatagramSocket.setReuseAddress(true)");
s1.setReuseAddress(true);
check(s1.getReuseAddress());
test("DatagramSocket.setReuseAddress(false)");
s1.setReuseAddress(false);
check(!s1.getReuseAddress() );
/* bind to any port */
s1.bind( new InetSocketAddress(0) );
test("Binding datagram socket to port already in use should throw " +
"a BindException");
DatagramSocket s2 = new DatagramSocket(null);
try {
s2.bind( new InetSocketAddress(s1.getLocalPort()) );
failed();
} catch (BindException e) {
passed();
}
s2.close();
s1.close();
// bind with SO_REUSEADDR enabled
s1 = new DatagramSocket(null);
s1.setReuseAddress(true);
s1.bind( new InetSocketAddress(0) );
test("Bind 2 datagram sockets to the same port - second " +
"bind doesn't have SO_REUSEADDR enabled");
s2 = new DatagramSocket(null);
try {
s2.bind( new InetSocketAddress(s1.getLocalPort()) );
failed();
} catch (BindException e) {
passed();
}
s2.close();
test("Bind 2 datagram sockets to the same port - both have " +
"SO_REUSEADDR enabled");
s2 = new DatagramSocket(null);
s2.setReuseAddress(true);
try {
s2.bind( new InetSocketAddress(s1.getLocalPort()) );
passed();
} catch (BindException e) {
if (System.getProperty("sun.net.useExclusiveBind") != null) {
// exclusive bind enabled - expected result
passed();
} else {
failed();
}
}
s2.close();
s1.close();
}
void MulticastSocketTests() throws Exception {
test("Check SO_REUSEADDR is enabled in MulticastSocket()");
MulticastSocket s1 = new MulticastSocket();
check(s1.getReuseAddress());
s1.close();
test("Check that SO_REUSEADDR is not disabled by " +
"MulticastSocket.bind()");
s1 = new MulticastSocket(null);
// bind to specific address
InetSocketAddress isa = new InetSocketAddress(
InetAddress.getLocalHost(), 0);
s1.bind(isa);
check(s1.getReuseAddress());
s1.close();
}
Basic() throws Exception {
SocketTests();
ServerSocketTests();
DatagramSocketTests();
MulticastSocketTests();
System.out.println("***************************************");
System.out.println(testCount + " test(s) executed, " +
failures + " failure(s).");
if (failures > 0) {
throw new Exception(failures + " test(s) failed");
}
}
public static void main(String args[]) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
new Basic();
}
}

View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 2001, 2019, 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 4476378
* @library /test/lib
* @summary Check that SO_REUSEADDR allows a server to restart
* after a crash.
* @run main Restart
* @run main/othervm -Dsun.net.useExclusiveBind Restart
* @run main/othervm -Dsun.net.useExclusiveBind=true Restart
* @run main/othervm -Djava.net.preferIPv4Stack=true Restart
* @run main/othervm -Dsun.net.useExclusiveBind
* -Djava.net.preferIPv4Stack=true Restart
* @run main/othervm -Dsun.net.useExclusiveBind=true
* -Djava.net.preferIPv4Stack=true Restart
*/
import java.net.*;
import jdk.test.lib.net.IPSupport;
public class Restart {
/*
* Test that a server can bind to the same port after
* a crash -- ie: while previous connection still in
* TIME_WAIT state we should be able to re-bind if
* SO_REUSEADDR is enabled.
*/
public static void main(String args[]) throws Exception {
IPSupport.throwSkippedExceptionIfNonOperational();
InetAddress localHost = InetAddress.getLocalHost();
ServerSocket ss = new ServerSocket(0, 0, localHost);
Socket s1 = null, s2 = null;
try {
int port = ss.getLocalPort();
s1 = new Socket(localHost, port);
s2 = ss.accept();
// close server socket and the accepted connection
ss.close();
s2.close();
ss = new ServerSocket();
ss.bind( new InetSocketAddress(localHost, port) );
ss.close();
// close the client socket
s1.close();
} catch (BindException be) {
if (System.getProperty("sun.net.useExclusiveBind") != null) {
// exclusive bind, expected exception
} else {
throw be;
}
} finally {
if (ss != null) ss.close();
if (s1 != null) s1.close();
if (s2 != null) s2.close();
}
}
}