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:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
161
test/jdk/java/net/Socket/AddressTest.java
Normal file
161
test/jdk/java/net/Socket/AddressTest.java
Normal 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();
|
||||
}
|
||||
}
|
||||
151
test/jdk/java/net/Socket/AsyncShutdown.java
Normal file
151
test/jdk/java/net/Socket/AsyncShutdown.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
80
test/jdk/java/net/Socket/B6210227.java
Normal file
80
test/jdk/java/net/Socket/B6210227.java
Normal 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;
|
||||
}
|
||||
}
|
||||
185
test/jdk/java/net/Socket/CloseAvailable.java
Normal file
185
test/jdk/java/net/Socket/CloseAvailable.java
Normal 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");
|
||||
}
|
||||
}
|
||||
176
test/jdk/java/net/Socket/ClosedSocketTest.java
Normal file
176
test/jdk/java/net/Socket/ClosedSocketTest.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
176
test/jdk/java/net/Socket/ConnectFailTest.java
Normal file
176
test/jdk/java/net/Socket/ConnectFailTest.java
Normal 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());
|
||||
}
|
||||
|
||||
}
|
||||
218
test/jdk/java/net/Socket/ConnectSocksProxyTest.java
Normal file
218
test/jdk/java/net/Socket/ConnectSocksProxyTest.java
Normal 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());
|
||||
}
|
||||
|
||||
}
|
||||
217
test/jdk/java/net/Socket/ConnectionReset.java
Normal file
217
test/jdk/java/net/Socket/ConnectionReset.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
220
test/jdk/java/net/Socket/CtorFailTest.java
Normal file
220
test/jdk/java/net/Socket/CtorFailTest.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
243
test/jdk/java/net/Socket/DeadlockTest.java
Normal file
243
test/jdk/java/net/Socket/DeadlockTest.java
Normal 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;
|
||||
}
|
||||
142
test/jdk/java/net/Socket/ExceptionText.java
Normal file
142
test/jdk/java/net/Socket/ExceptionText.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
90
test/jdk/java/net/Socket/GetLocalAddress.java
Normal file
90
test/jdk/java/net/Socket/GetLocalAddress.java
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
341
test/jdk/java/net/Socket/HttpProxy.java
Normal file
341
test/jdk/java/net/Socket/HttpProxy.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
51
test/jdk/java/net/Socket/IDNTest.java
Normal file
51
test/jdk/java/net/Socket/IDNTest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
129
test/jdk/java/net/Socket/InheritHandle.java
Normal file
129
test/jdk/java/net/Socket/InheritHandle.java
Normal 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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
101
test/jdk/java/net/Socket/InheritTimeout.java
Normal file
101
test/jdk/java/net/Socket/InheritTimeout.java
Normal 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();
|
||||
}
|
||||
}
|
||||
174
test/jdk/java/net/Socket/LinkLocal.java
Normal file
174
test/jdk/java/net/Socket/LinkLocal.java
Normal 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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
37
test/jdk/java/net/Socket/NativeThread.java
Normal file
37
test/jdk/java/net/Socket/NativeThread.java
Normal 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();
|
||||
}
|
||||
89
test/jdk/java/net/Socket/NullHost.java
Normal file
89
test/jdk/java/net/Socket/NullHost.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
test/jdk/java/net/Socket/OldSocketImpl.jar
Normal file
BIN
test/jdk/java/net/Socket/OldSocketImpl.jar
Normal file
Binary file not shown.
49
test/jdk/java/net/Socket/OldSocketImplTest.java
Normal file
49
test/jdk/java/net/Socket/OldSocketImplTest.java
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
90
test/jdk/java/net/Socket/ProxyCons.java
Normal file
90
test/jdk/java/net/Socket/ProxyCons.java
Normal 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();
|
||||
}
|
||||
}
|
||||
89
test/jdk/java/net/Socket/RST.java
Normal file
89
test/jdk/java/net/Socket/RST.java
Normal 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();
|
||||
}
|
||||
}
|
||||
140
test/jdk/java/net/Socket/ReadAfterReset.java
Normal file
140
test/jdk/java/net/Socket/ReadAfterReset.java
Normal 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;
|
||||
}
|
||||
}
|
||||
68
test/jdk/java/net/Socket/ReadTimeout.java
Normal file
68
test/jdk/java/net/Socket/ReadTimeout.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
75
test/jdk/java/net/Socket/RejectIPv6.java
Normal file
75
test/jdk/java/net/Socket/RejectIPv6.java
Normal 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;
|
||||
}
|
||||
}
|
||||
59
test/jdk/java/net/Socket/SetReceiveBufferSize.java
Normal file
59
test/jdk/java/net/Socket/SetReceiveBufferSize.java
Normal 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!");
|
||||
}
|
||||
}
|
||||
62
test/jdk/java/net/Socket/SetSoLinger.java
Normal file
62
test/jdk/java/net/Socket/SetSoLinger.java
Normal 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.");
|
||||
}
|
||||
}
|
||||
50
test/jdk/java/net/Socket/ShutdownBoth.java
Normal file
50
test/jdk/java/net/Socket/ShutdownBoth.java
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
96
test/jdk/java/net/Socket/ShutdownInput.java
Normal file
96
test/jdk/java/net/Socket/ShutdownInput.java
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
88
test/jdk/java/net/Socket/SoTimeout.java
Normal file
88
test/jdk/java/net/Socket/SoTimeout.java
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
151
test/jdk/java/net/Socket/SocketAcceptInterruptTest.java
Normal file
151
test/jdk/java/net/Socket/SocketAcceptInterruptTest.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
53
test/jdk/java/net/Socket/SocketGrowth.java
Normal file
53
test/jdk/java/net/Socket/SocketGrowth.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
179
test/jdk/java/net/Socket/SocketReadInterruptTest.java
Normal file
179
test/jdk/java/net/Socket/SocketReadInterruptTest.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
140
test/jdk/java/net/Socket/SocksConnectTimeout.java
Normal file
140
test/jdk/java/net/Socket/SocksConnectTimeout.java
Normal 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++; };
|
||||
|
||||
}
|
||||
120
test/jdk/java/net/Socket/Streams.java
Normal file
120
test/jdk/java/net/Socket/Streams.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
118
test/jdk/java/net/Socket/TestAfterClose.java
Normal file
118
test/jdk/java/net/Socket/TestAfterClose.java
Normal 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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
73
test/jdk/java/net/Socket/TestClose.java
Normal file
73
test/jdk/java/net/Socket/TestClose.java
Normal 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");
|
||||
}
|
||||
}
|
||||
62
test/jdk/java/net/Socket/TestTcpNoDelay.java
Normal file
62
test/jdk/java/net/Socket/TestTcpNoDelay.java
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
53
test/jdk/java/net/Socket/Timeout.java
Normal file
53
test/jdk/java/net/Socket/Timeout.java
Normal 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.");
|
||||
}
|
||||
}
|
||||
705
test/jdk/java/net/Socket/Timeouts.java
Normal file
705
test/jdk/java/net/Socket/Timeouts.java
Normal 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;
|
||||
}
|
||||
}
|
||||
86
test/jdk/java/net/Socket/TrafficClass.java
Normal file
86
test/jdk/java/net/Socket/TrafficClass.java
Normal 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.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
72
test/jdk/java/net/Socket/UdpSocket.java
Normal file
72
test/jdk/java/net/Socket/UdpSocket.java
Normal 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;
|
||||
}
|
||||
}
|
||||
160
test/jdk/java/net/Socket/UrgentDataTest.java
Normal file
160
test/jdk/java/net/Socket/UrgentDataTest.java
Normal 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 ();
|
||||
}
|
||||
}
|
||||
}
|
||||
78
test/jdk/java/net/Socket/asyncClose/AsyncClose.java
Normal file
78
test/jdk/java/net/Socket/asyncClose/AsyncClose.java
Normal 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.");
|
||||
}
|
||||
}
|
||||
66
test/jdk/java/net/Socket/asyncClose/AsyncCloseTest.java
Normal file
66
test/jdk/java/net/Socket/asyncClose/AsyncCloseTest.java
Normal 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;
|
||||
}
|
||||
84
test/jdk/java/net/Socket/asyncClose/BrokenPipe.java
Normal file
84
test/jdk/java/net/Socket/asyncClose/BrokenPipe.java
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
104
test/jdk/java/net/Socket/asyncClose/DatagramSocket_receive.java
Normal file
104
test/jdk/java/net/Socket/asyncClose/DatagramSocket_receive.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
244
test/jdk/java/net/Socket/asyncClose/Leaky.java
Normal file
244
test/jdk/java/net/Socket/asyncClose/Leaky.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
86
test/jdk/java/net/Socket/asyncClose/Race.java
Normal file
86
test/jdk/java/net/Socket/asyncClose/Race.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
98
test/jdk/java/net/Socket/asyncClose/ServerSocket_accept.java
Normal file
98
test/jdk/java/net/Socket/asyncClose/ServerSocket_accept.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
70
test/jdk/java/net/Socket/libNativeThread.c
Normal file
70
test/jdk/java/net/Socket/libNativeThread.c
Normal 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
|
||||
}
|
||||
235
test/jdk/java/net/Socket/setReuseAddress/Basic.java
Normal file
235
test/jdk/java/net/Socket/setReuseAddress/Basic.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
85
test/jdk/java/net/Socket/setReuseAddress/Restart.java
Normal file
85
test/jdk/java/net/Socket/setReuseAddress/Restart.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue