8233847: (sctp) Flx link-local IPv6 scope handling and test cleanup

Reviewed-by: alanb
This commit is contained in:
Chris Hegarty 2019-11-21 12:14:29 +00:00
parent 180ffe5e45
commit 76e5a32c52
13 changed files with 84 additions and 71 deletions

View File

@ -240,8 +240,9 @@ module java.base {
jdk.naming.dns;
exports sun.net.util to
java.desktop,
java.net.http,
jdk.jconsole,
java.net.http;
jdk.sctp;
exports sun.net.www to
java.net.http,
jdk.jartool;

View File

@ -29,7 +29,7 @@ package com.sun.nio.sctp;
*
* <P> The {@code HandlerResult} is used to determine the behavior of the
* channel after it handles a notification from the SCTP stack. Essentially its
* value determines if the channel should try to receive another notificaiton or
* value determines if the channel should try to receive another notification or
* a message before returning.
*
* @since 1.7

View File

@ -53,6 +53,7 @@ import com.sun.nio.sctp.MessageInfo;
import com.sun.nio.sctp.NotificationHandler;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.SctpSocketOption;
import sun.net.util.IPAddressUtil;
import sun.nio.ch.DirectBuffer;
import sun.nio.ch.IOStatus;
import sun.nio.ch.IOUtil;
@ -1012,6 +1013,9 @@ public class SctpChannelImpl extends SctpChannel
if (target != null) {
InetSocketAddress isa = Net.checkAddress(target);
addr = isa.getAddress();
if (addr.isLinkLocalAddress()) {
addr = IPAddressUtil.toScopedAddress(addr);
}
port = isa.getPort();
}

View File

@ -53,6 +53,7 @@ import com.sun.nio.sctp.MessageInfo;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.SctpMultiChannel;
import com.sun.nio.sctp.SctpSocketOption;
import sun.net.util.IPAddressUtil;
import sun.nio.ch.DirectBuffer;
import sun.nio.ch.NativeThread;
import sun.nio.ch.IOStatus;
@ -892,6 +893,9 @@ public class SctpMultiChannelImpl extends SctpMultiChannel
if (target != null) {
InetSocketAddress isa = Net.checkAddress(target);
addr = isa.getAddress();
if (addr.isLinkLocalAddress()) {
addr = IPAddressUtil.toScopedAddress(addr);
}
port = isa.getPort();
}
int pos = bb.position();

View File

@ -34,6 +34,7 @@ import java.util.Set;
import java.util.HashSet;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.net.util.IPAddressUtil;
import sun.nio.ch.IOUtil;
import sun.nio.ch.Net;
import com.sun.nio.sctp.SctpSocketOption;
@ -169,9 +170,13 @@ public class SctpNet {
InetSocketAddress netAddr = (InetSocketAddress)addr;
if (name.equals(SCTP_PRIMARY_ADDR)) {
InetAddress inetAddress = netAddr.getAddress();
if (inetAddress.isLinkLocalAddress()) {
inetAddress = IPAddressUtil.toScopedAddress(inetAddress);
}
setPrimAddrOption0(fd,
assocId,
netAddr.getAddress(),
inetAddress,
netAddr.getPort());
} else {
setPeerPrimAddrOption0(fd,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 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
@ -110,9 +110,10 @@ public class Bind {
try {
channel.close(); /* open a new unbound channel for test */
channel = SctpChannel.open();
connectChannel(channel);
channel.bind(null);
fail("AlreadyConnectedException expected");
try (var peer = connectChannel(channel)) {
channel.bind(null);
fail("AlreadyConnectedException expected");
}
} catch (AlreadyConnectedException unused) { pass();
} catch (IOException ioe) { unexpected(ioe); }
@ -264,7 +265,9 @@ public class Bind {
} finally {
try { if (channel != null) channel.close(); }
catch (IOException ioe) { unexpected(ioe); }
}
try { if (peerChannel != null) peerChannel.close(); }
catch (IOException ioe) { unexpected(ioe); }
}
}
boolean boundAddress(SctpChannel channel, InetAddress addr)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 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
@ -191,6 +191,9 @@ public class CommUp {
}
} //for
try { sc.close(); }
catch (IOException ioe) { unexpected(ioe); }
} catch (IOException ioe) {
unexpected(ioe);
} catch (InterruptedException ie) {

View File

@ -61,11 +61,10 @@ public class Connect {
void doTest() {
SctpChannel channel = null;
SctpServerChannel ssc = null;
try {
try (SctpServerChannel ssc = SctpServerChannel.open()) {
/* Create a server channel to connect to */
ssc = SctpServerChannel.open().bind(null);
ssc.bind(null);
Set<SocketAddress> addrs = ssc.getAllLocalAddresses();
if (addrs.isEmpty())
debug("addrs should not be empty");
@ -209,8 +208,6 @@ public class Connect {
} finally {
try { if (channel != null) channel.close(); }
catch (IOException unused) {}
try { if (ssc != null) ssc.close(); }
catch (IOException unused) {}
}
}

View File

@ -72,8 +72,7 @@ public class SocketOptionTests {
return;
}
try {
SctpChannel sc = SctpChannel.open();
try (SctpChannel sc = SctpChannel.open()) {
/* check supported options */
Set<SctpSocketOption<?>> options = sc.supportedOptions();
@ -143,8 +142,6 @@ public class SocketOptionTests {
/* SCTP_PRIMARY_ADDR */
void sctpPrimaryAddr() throws IOException {
SocketAddress addrToSet = null;;
System.out.println("TESTING SCTP_PRIMARY_ADDR");
SctpChannel sc = SctpChannel.open();
SctpServerChannel ssc = SctpServerChannel.open().bind(null);
@ -158,12 +155,11 @@ public class SocketOptionTests {
sc.connect(serverAddr);
SctpChannel peerChannel = ssc.accept();
ssc.close();
Set<SocketAddress> peerAddrs = peerChannel.getAllLocalAddresses();
debug("Peer local Addresses: ");
for (Iterator<SocketAddress> it = peerAddrs.iterator(); it.hasNext(); ) {
Set<SocketAddress> remoteAddresses = sc.getRemoteAddresses();
debug("Remote Addresses: ");
for (Iterator<SocketAddress> it = remoteAddresses.iterator(); it.hasNext(); ) {
InetSocketAddress addr = (InetSocketAddress)it.next();
debug("\t" + addr);
addrToSet = addr; // any of the peer addresses will do!
}
/* retrieval of SCTP_PRIMARY_ADDR is not supported on Solaris */
@ -176,25 +172,21 @@ public class SocketOptionTests {
} else { /* Linux */
SocketAddress primaryAddr = sc.getOption(SCTP_PRIMARY_ADDR);
System.out.println("SCTP_PRIMARY_ADDR returned: " + primaryAddr);
/* Verify that this is one of the peer addresses */
boolean found = false;
addrToSet = primaryAddr; // may not have more than one addr
for (Iterator<SocketAddress> it = peerAddrs.iterator(); it.hasNext(); ) {
InetSocketAddress addr = (InetSocketAddress)it.next();
if (addr.equals(primaryAddr)) {
found = true;
}
addrToSet = addr;
}
check(found, "SCTP_PRIMARY_ADDR returned bogus address!");
/* Verify that this is one of the remote addresses */
check(remoteAddresses.contains(primaryAddr), "SCTP_PRIMARY_ADDR returned bogus address!");
System.out.println("SCTP_PRIMARY_ADDR try set to: " + addrToSet);
sc.setOption(SCTP_PRIMARY_ADDR, addrToSet);
System.out.println("SCTP_PRIMARY_ADDR set to: " + addrToSet);
primaryAddr = sc.getOption(SCTP_PRIMARY_ADDR);
System.out.println("SCTP_PRIMARY_ADDR returned: " + primaryAddr);
check(addrToSet.equals(primaryAddr),"SCTP_PRIMARY_ADDR not set correctly");
for (Iterator<SocketAddress> it = remoteAddresses.iterator(); it.hasNext(); ) {
InetSocketAddress addrToSet = (InetSocketAddress) it.next();
System.out.println("SCTP_PRIMARY_ADDR try set to: " + addrToSet);
sc.setOption(SCTP_PRIMARY_ADDR, addrToSet);
System.out.println("SCTP_PRIMARY_ADDR set to : " + addrToSet);
primaryAddr = sc.getOption(SCTP_PRIMARY_ADDR);
System.out.println("SCTP_PRIMARY_ADDR returned : " + primaryAddr);
check(addrToSet.equals(primaryAddr), "SCTP_PRIMARY_ADDR not set correctly");
}
}
sc.close();
peerChannel.close();
}
//--------------------- Infrastructure ---------------------------
boolean debug = true;

View File

@ -210,7 +210,8 @@ public class Branch {
/* echo the message */
debug("Server: echoing first message");
buffer.flip();
int bytes = serverChannel.send(buffer, info);
MessageInfo sendInfo = MessageInfo.createOutgoing(info.association(), null, 0);
int bytes = serverChannel.send(buffer, sendInfo);
debug("Server: sent " + bytes + "bytes");
clientFinishedLatch.await(10L, TimeUnit.SECONDS);

View File

@ -276,7 +276,8 @@ public class Send {
/* echo the message */
debug("Server: echoing first message");
buffer.flip();
int bytes = serverChannel.send(buffer, info);
MessageInfo sendInfo = MessageInfo.createOutgoing(assoc, null, info.streamNumber());
int bytes = serverChannel.send(buffer, sendInfo);
debug("Server: sent " + bytes + "bytes");
/* receive a large message */
@ -302,7 +303,8 @@ public class Send {
/* echo the message */
debug("Server: echoing second message");
buffer.flip();
bytes = serverChannel.send(buffer, info);
sendInfo = MessageInfo.createOutgoing(assoc, null, info.streamNumber());
bytes = serverChannel.send(buffer, sendInfo);
debug("Server: sent " + bytes + "bytes");
/* TEST 6 */

View File

@ -98,14 +98,19 @@ public class SendFailed {
new SendFailedNotificationHandler();
ByteBuffer recvBuffer = direct ? allocateDirect(recvBufferSize)
: allocate((recvBufferSize));
channel.receive(recvBuffer, null, handler);
MessageInfo info = channel.receive(recvBuffer, null, handler);
debug("receive returned info:" + info);
// verify sent buffer received by send failed notification
ByteBuffer buffer = handler.getSendFailedByteBuffer();
check(buffer.remaining() == sent);
check(buffer.position() == 0);
check(buffer.limit() == sent);
assertSameContent(sendBuffer, handler.getSendFailedByteBuffer());
if (handler.receivedSendFailed) {
// verify sent buffer received by send failed notification
ByteBuffer buffer = handler.getSendFailedByteBuffer();
check(buffer.remaining() == sent);
check(buffer.position() == 0);
check(buffer.limit() == sent);
assertSameContent(sendBuffer, handler.getSendFailedByteBuffer());
} else {
debug("Unexpected event or received data. Check output.");
}
}
}
@ -113,6 +118,7 @@ public class SendFailed {
{
/** Reference to the buffer captured in send failed notification */
private ByteBuffer sentBuffer;
boolean receivedSendFailed;
@Override
public HandlerResult handleNotification(
@ -135,6 +141,7 @@ public class SendFailed {
public HandlerResult handleNotification(
SendFailedNotification notification, Object attachment) {
debug("%nSendFailedNotification: %s. ", notification);
receivedSendFailed = true;
sentBuffer = notification.buffer();
return HandlerResult.RETURN;
}

View File

@ -154,7 +154,6 @@ public class SocketOptionTests {
/* SCTP_PRIMARY_ADDR */
void sctpPrimaryAddr() throws IOException {
SocketAddress addrToSet = null;
ByteBuffer buffer = ByteBuffer.allocate(Util.SMALL_BUFFER);
System.out.println("TESTING SCTP_PRIMARY_ADDR");
@ -189,12 +188,11 @@ public class SocketOptionTests {
SctpChannel peerChannel = ssc.accept();
ssc.close();
Set<SocketAddress> peerAddrs = peerChannel.getAllLocalAddresses();
debug("Peer local Addresses: ");
for (Iterator<SocketAddress> it = peerAddrs.iterator(); it.hasNext(); ) {
Set<SocketAddress> remoteAddresses = smc.getRemoteAddresses(assoc);
debug("Remote Addresses: ");
for (Iterator<SocketAddress> it = remoteAddresses.iterator(); it.hasNext(); ) {
InetSocketAddress addr = (InetSocketAddress)it.next();
debug("\t" + addr);
addrToSet = addr; // any of the peer addresses will do!
}
/* retrieval of SCTP_PRIMARY_ADDR is not supported on Solaris */
@ -207,25 +205,21 @@ public class SocketOptionTests {
} else { /* Linux */
SocketAddress primaryAddr = smc.getOption(SCTP_PRIMARY_ADDR, assoc);
System.out.println("SCTP_PRIMARY_ADDR returned: " + primaryAddr);
/* Verify that this is one of the peer addresses */
boolean found = false;
addrToSet = primaryAddr; // may not have more than one addr
for (Iterator<SocketAddress> it = peerAddrs.iterator(); it.hasNext(); ) {
InetSocketAddress addr = (InetSocketAddress)it.next();
if (addr.equals(primaryAddr)) {
found = true;
}
addrToSet = addr;
}
check(found, "SCTP_PRIMARY_ADDR returned bogus address!");
/* Verify that this is one of the remote addresses */
check(remoteAddresses.contains(primaryAddr), "SCTP_PRIMARY_ADDR returned bogus address!");
System.out.println("Try SCTP_PRIMARY_ADDR set to: " + addrToSet);
smc.setOption(SCTP_PRIMARY_ADDR, addrToSet, assoc);
System.out.println("SCTP_PRIMARY_ADDR set to: " + addrToSet);
primaryAddr = smc.getOption(SCTP_PRIMARY_ADDR, assoc);
System.out.println("SCTP_PRIMARY_ADDR returned: " + primaryAddr);
check(addrToSet.equals(primaryAddr),"SCTP_PRIMARY_ADDR not set correctly");
for (Iterator<SocketAddress> it = remoteAddresses.iterator(); it.hasNext(); ) {
InetSocketAddress addrToSet = (InetSocketAddress) it.next();
System.out.println("SCTP_PRIMARY_ADDR try set to: " + addrToSet);
smc.setOption(SCTP_PRIMARY_ADDR, addrToSet, assoc);
System.out.println("SCTP_PRIMARY_ADDR set to : " + addrToSet);
primaryAddr = smc.getOption(SCTP_PRIMARY_ADDR, assoc);
System.out.println("SCTP_PRIMARY_ADDR returned : " + primaryAddr);
check(addrToSet.equals(primaryAddr), "SCTP_PRIMARY_ADDR not set correctly");
}
}
smc.close();
peerChannel.close();
}
class SOTNotificationHandler extends AbstractNotificationHandler<Object>