8187443: Forest Consolidation: Move files to unified layout

Reviewed-by: darcy, ihse
This commit is contained in:
Erik Joelsson 2017-09-12 19:03:39 +02:00
parent 270fe13182
commit 3789983e89
56923 changed files with 3 additions and 15727 deletions

View file

@ -0,0 +1,121 @@
/*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.ch.sctp;
import com.sun.nio.sctp.Association;
import com.sun.nio.sctp.AssociationChangeNotification;
import java.lang.annotation.Native;
/**
* An implementation of AssociationChangeNotification
*/
public class AssociationChange extends AssociationChangeNotification
implements SctpNotification
{
/* static final ints so that they can be referenced from native */
@Native private final static int SCTP_COMM_UP = 1;
@Native private final static int SCTP_COMM_LOST = 2;
@Native private final static int SCTP_RESTART = 3;
@Native private final static int SCTP_SHUTDOWN = 4;
@Native private final static int SCTP_CANT_START = 5;
private Association association;
/* assocId is used to lookup the association before the notification is
* returned to user code */
private int assocId;
private AssocChangeEvent event;
private int maxOutStreams;
private int maxInStreams;
/* Invoked from native */
private AssociationChange(int assocId,
int intEvent,
int maxOutStreams,
int maxInStreams) {
switch (intEvent) {
case SCTP_COMM_UP :
this.event = AssocChangeEvent.COMM_UP;
break;
case SCTP_COMM_LOST :
this.event = AssocChangeEvent.COMM_LOST;
break;
case SCTP_RESTART :
this.event = AssocChangeEvent.RESTART;
break;
case SCTP_SHUTDOWN :
this.event = AssocChangeEvent.SHUTDOWN;
break;
case SCTP_CANT_START :
this.event = AssocChangeEvent.CANT_START;
break;
default :
throw new AssertionError(
"Unknown Association Change Event type: " + intEvent);
}
this.assocId = assocId;
this.maxOutStreams = maxOutStreams;
this.maxInStreams = maxInStreams;
}
@Override
public int assocId() {
return assocId;
}
@Override
public void setAssociation(Association association) {
this.association = association;
}
@Override
public Association association() {
assert association != null;
return association;
}
@Override
public AssocChangeEvent event() {
return event;
}
int maxOutStreams() {
return maxOutStreams;
}
int maxInStreams() {
return maxInStreams;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(super.toString()).append(" [");
sb.append("Association:").append(association);
sb.append(", Event: ").append(event).append("]");
return sb.toString();
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.ch.sctp;
import com.sun.nio.sctp.Association;
/**
* An implementation of Association
*/
public class AssociationImpl extends Association {
public AssociationImpl(int associationID,
int maxInStreams,
int maxOutStreams) {
super(associationID, maxInStreams, maxOutStreams);
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer(super.toString());
return sb.append("[associationID:")
.append(associationID())
.append(", maxIn:")
.append(maxInboundStreams())
.append(", maxOut:")
.append(maxOutboundStreams())
.append("]")
.toString();
}
}

View file

@ -0,0 +1,120 @@
/*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.ch.sctp;
import java.net.SocketAddress;
import com.sun.nio.sctp.Association;
import com.sun.nio.sctp.PeerAddressChangeNotification;
import java.lang.annotation.Native;
/**
* An implementation of PeerAddressChangeNotification
*/
public class PeerAddrChange extends PeerAddressChangeNotification
implements SctpNotification
{
/* static final ints so that they can be referenced from native */
@Native private final static int SCTP_ADDR_AVAILABLE = 1;
@Native private final static int SCTP_ADDR_UNREACHABLE = 2;
@Native private final static int SCTP_ADDR_REMOVED = 3;
@Native private final static int SCTP_ADDR_ADDED = 4;
@Native private final static int SCTP_ADDR_MADE_PRIM = 5;
@Native private final static int SCTP_ADDR_CONFIRMED =6;
private Association association;
/* assocId is used to lookup the association before the notification is
* returned to user code */
private int assocId;
private SocketAddress address;
private AddressChangeEvent event;
/* Invoked from native */
private PeerAddrChange(int assocId, SocketAddress address, int intEvent) {
switch (intEvent) {
case SCTP_ADDR_AVAILABLE :
this.event = AddressChangeEvent.ADDR_AVAILABLE;
break;
case SCTP_ADDR_UNREACHABLE :
this.event = AddressChangeEvent.ADDR_UNREACHABLE;
break;
case SCTP_ADDR_REMOVED :
this.event = AddressChangeEvent.ADDR_REMOVED;
break;
case SCTP_ADDR_ADDED :
this.event = AddressChangeEvent.ADDR_ADDED;
break;
case SCTP_ADDR_MADE_PRIM :
this.event = AddressChangeEvent.ADDR_MADE_PRIMARY;
break;
case SCTP_ADDR_CONFIRMED :
this.event = AddressChangeEvent.ADDR_CONFIRMED;
break;
default:
throw new AssertionError("Unknown event type");
}
this.assocId = assocId;
this.address = address;
}
@Override
public int assocId() {
return assocId;
}
@Override
public void setAssociation(Association association) {
this.association = association;
}
@Override
public SocketAddress address() {
assert address != null;
return address;
}
@Override
public Association association() {
assert association != null;
return association;
}
@Override
public AddressChangeEvent event() {
assert event != null;
return event;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(super.toString()).append(" [");
sb.append("Address: ").append(address);
sb.append(", Association:").append(association);
sb.append(", Event: ").append(event).append("]");
return sb.toString();
}
}

View file

@ -0,0 +1,130 @@
/*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.ch.sctp;
import java.lang.annotation.Native;
/**
* Wraps the actual message or notification so that it can be
* set and returned from the native receive implementation.
*/
public class ResultContainer {
/* static final ints so that they can be referenced from native */
@Native static final int NOTHING = 0;
@Native static final int MESSAGE = 1;
@Native static final int SEND_FAILED = 2;
@Native static final int ASSOCIATION_CHANGED = 3;
@Native static final int PEER_ADDRESS_CHANGED = 4;
@Native static final int SHUTDOWN = 5;
private Object value;
private int type;
int type() {
return type;
}
boolean hasSomething() {
return type() != NOTHING;
}
boolean isNotification() {
return type() != MESSAGE && type() != NOTHING ? true : false;
}
void clear() {
type = NOTHING;
value = null;
}
SctpNotification notification() {
assert type() != MESSAGE && type() != NOTHING;
return (SctpNotification) value;
}
MessageInfoImpl getMessageInfo() {
assert type() == MESSAGE;
if (value instanceof MessageInfoImpl)
return (MessageInfoImpl) value;
return null;
}
SendFailed getSendFailed() {
assert type() == SEND_FAILED;
if (value instanceof SendFailed)
return (SendFailed) value;
return null;
}
AssociationChange getAssociationChanged() {
assert type() == ASSOCIATION_CHANGED;
if (value instanceof AssociationChange)
return (AssociationChange) value;
return null;
}
PeerAddrChange getPeerAddressChanged() {
assert type() == PEER_ADDRESS_CHANGED;
if (value instanceof PeerAddrChange)
return (PeerAddrChange) value;
return null;
}
Shutdown getShutdown() {
assert type() == SHUTDOWN;
if (value instanceof Shutdown)
return (Shutdown) value;
return null;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Type: ");
switch (type) {
case NOTHING: sb.append("NOTHING"); break;
case MESSAGE: sb.append("MESSAGE"); break;
case SEND_FAILED: sb.append("SEND FAILED"); break;
case ASSOCIATION_CHANGED: sb.append("ASSOCIATION CHANGE"); break;
case PEER_ADDRESS_CHANGED: sb.append("PEER ADDRESS CHANGE"); break;
case SHUTDOWN: sb.append("SHUTDOWN"); break;
default : sb.append("Unknown result type");
}
sb.append(", Value: ");
sb.append((value == null) ? "null" : value.toString());
return sb.toString();
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,341 @@
/*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.ch.sctp;
import java.io.FileDescriptor;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.channels.AlreadyBoundException;
import java.util.Set;
import java.util.HashSet;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.nio.ch.IOUtil;
import sun.nio.ch.Net;
import com.sun.nio.sctp.SctpSocketOption;
import static com.sun.nio.sctp.SctpStandardSocketOptions.*;
public class SctpNet {
private static final String osName = AccessController.doPrivileged(
(PrivilegedAction<String>) () -> System.getProperty("os.name"));
/* -- Miscellaneous SCTP utilities -- */
private static boolean IPv4MappedAddresses() {
if ("SunOS".equals(osName)) {
/* Solaris supports IPv4Mapped Addresses with bindx */
return true;
} /* else { //other OS/implementations */
/* lksctp/linux requires Ipv4 addresses */
return false;
}
static boolean throwAlreadyBoundException() throws IOException {
throw new AlreadyBoundException();
}
static void listen(int fd, int backlog) throws IOException {
listen0(fd, backlog);
}
static int connect(int fd, InetAddress remote, int remotePort)
throws IOException {
return connect0(fd, remote, remotePort);
}
static void close(int fd) throws IOException {
close0(fd);
}
static void preClose(int fd) throws IOException {
preClose0(fd);
}
/**
* @param oneToOne
* if {@code true} returns a one-to-one sctp socket, otherwise
* returns a one-to-many sctp socket
*/
static FileDescriptor socket(boolean oneToOne) throws IOException {
int nativefd = socket0(oneToOne);
return IOUtil.newFD(nativefd);
}
static void bindx(int fd, InetAddress[] addrs, int port, boolean add)
throws IOException {
bindx(fd, addrs, port, addrs.length, add,
IPv4MappedAddresses());
}
static Set<SocketAddress> getLocalAddresses(int fd)
throws IOException {
Set<SocketAddress> set = null;
SocketAddress[] saa = getLocalAddresses0(fd);
if (saa != null) {
set = getRevealedLocalAddressSet(saa);
}
return set;
}
private static Set<SocketAddress> getRevealedLocalAddressSet(
SocketAddress[] saa)
{
SecurityManager sm = System.getSecurityManager();
Set<SocketAddress> set = new HashSet<>(saa.length);
for (SocketAddress sa : saa) {
set.add(getRevealedLocalAddress(sa, sm));
}
return set;
}
private static SocketAddress getRevealedLocalAddress(SocketAddress sa,
SecurityManager sm)
{
if (sm == null || sa == null)
return sa;
InetSocketAddress ia = (InetSocketAddress)sa;
try{
sm.checkConnect(ia.getAddress().getHostAddress(), -1);
// Security check passed
} catch (SecurityException e) {
// Return loopback address
return new InetSocketAddress(InetAddress.getLoopbackAddress(),
ia.getPort());
}
return sa;
}
static Set<SocketAddress> getRemoteAddresses(int fd, int assocId)
throws IOException {
HashSet<SocketAddress> set = null;
SocketAddress[] saa = getRemoteAddresses0(fd, assocId);
if (saa != null) {
set = new HashSet<SocketAddress>(saa.length);
for (SocketAddress sa : saa)
set.add(sa);
}
return set;
}
static <T> void setSocketOption(int fd,
SctpSocketOption<T> name,
T value,
int assocId)
throws IOException {
if (value == null)
throw new IllegalArgumentException("Invalid option value");
if (name.equals(SCTP_INIT_MAXSTREAMS)) {
InitMaxStreams maxStreamValue = (InitMaxStreams)value;
SctpNet.setInitMsgOption0(fd,
maxStreamValue.maxInStreams(), maxStreamValue.maxOutStreams());
} else if (name.equals(SCTP_PRIMARY_ADDR) ||
name.equals(SCTP_SET_PEER_PRIMARY_ADDR)) {
SocketAddress addr = (SocketAddress) value;
if (addr == null)
throw new IllegalArgumentException("Invalid option value");
Net.checkAddress(addr);
InetSocketAddress netAddr = (InetSocketAddress)addr;
if (name.equals(SCTP_PRIMARY_ADDR)) {
setPrimAddrOption0(fd,
assocId,
netAddr.getAddress(),
netAddr.getPort());
} else {
setPeerPrimAddrOption0(fd,
assocId,
netAddr.getAddress(),
netAddr.getPort(),
IPv4MappedAddresses());
}
} else if (name.equals(SCTP_DISABLE_FRAGMENTS) ||
name.equals(SCTP_EXPLICIT_COMPLETE) ||
name.equals(SCTP_FRAGMENT_INTERLEAVE) ||
name.equals(SCTP_NODELAY) ||
name.equals(SO_SNDBUF) ||
name.equals(SO_RCVBUF) ||
name.equals(SO_LINGER)) {
setIntOption(fd, name, value);
} else {
throw new AssertionError("Unknown socket option");
}
}
static Object getSocketOption(int fd, SctpSocketOption<?> name, int assocId)
throws IOException {
if (name.equals(SCTP_SET_PEER_PRIMARY_ADDR)) {
throw new IllegalArgumentException(
"SCTP_SET_PEER_PRIMARY_ADDR cannot be retrieved");
} else if (name.equals(SCTP_INIT_MAXSTREAMS)) {
/* container for holding maxIn/Out streams */
int[] values = new int[2];
SctpNet.getInitMsgOption0(fd, values);
return InitMaxStreams.create(values[0], values[1]);
} else if (name.equals(SCTP_PRIMARY_ADDR)) {
return getPrimAddrOption0(fd, assocId);
} else if (name.equals(SCTP_DISABLE_FRAGMENTS) ||
name.equals(SCTP_EXPLICIT_COMPLETE) ||
name.equals(SCTP_FRAGMENT_INTERLEAVE) ||
name.equals(SCTP_NODELAY) ||
name.equals(SO_SNDBUF) ||
name.equals(SO_RCVBUF) ||
name.equals(SO_LINGER)) {
return getIntOption(fd, name);
} else {
throw new AssertionError("Unknown socket option");
}
}
static void setIntOption(int fd, SctpSocketOption<?> name, Object value)
throws IOException {
if (value == null)
throw new IllegalArgumentException("Invalid option value");
Class<?> type = name.type();
if (type != Integer.class && type != Boolean.class)
throw new AssertionError("Should not reach here");
if (name == SO_RCVBUF ||
name == SO_SNDBUF)
{
int i = ((Integer)value).intValue();
if (i < 0)
throw new IllegalArgumentException(
"Invalid send/receive buffer size");
} else if (name == SO_LINGER) {
int i = ((Integer)value).intValue();
if (i < 0)
value = Integer.valueOf(-1);
if (i > 65535)
value = Integer.valueOf(65535);
} else if (name.equals(SCTP_FRAGMENT_INTERLEAVE)) {
int i = ((Integer)value).intValue();
if (i < 0 || i > 2)
throw new IllegalArgumentException(
"Invalid value for SCTP_FRAGMENT_INTERLEAVE");
}
int arg;
if (type == Integer.class) {
arg = ((Integer)value).intValue();
} else {
boolean b = ((Boolean)value).booleanValue();
arg = (b) ? 1 : 0;
}
setIntOption0(fd, ((SctpStdSocketOption)name).constValue(), arg);
}
static Object getIntOption(int fd, SctpSocketOption<?> name)
throws IOException {
Class<?> type = name.type();
if (type != Integer.class && type != Boolean.class)
throw new AssertionError("Should not reach here");
if (!(name instanceof SctpStdSocketOption))
throw new AssertionError("Should not reach here");
int value = getIntOption0(fd,
((SctpStdSocketOption)name).constValue());
if (type == Integer.class) {
return Integer.valueOf(value);
} else {
return (value == 0) ? Boolean.FALSE : Boolean.TRUE;
}
}
static void shutdown(int fd, int assocId)
throws IOException {
shutdown0(fd, assocId);
}
static FileDescriptor branch(int fd, int assocId) throws IOException {
int nativefd = branch0(fd, assocId);
return IOUtil.newFD(nativefd);
}
/* Native Methods */
static native int socket0(boolean oneToOne) throws IOException;
static native void listen0(int fd, int backlog) throws IOException;
static native int connect0(int fd, InetAddress remote, int remotePort)
throws IOException;
static native void close0(int fd) throws IOException;
static native void preClose0(int fd) throws IOException;
static native void bindx(int fd, InetAddress[] addrs, int port, int length,
boolean add, boolean preferIPv6) throws IOException;
static native int getIntOption0(int fd, int opt) throws IOException;
static native void setIntOption0(int fd, int opt, int arg)
throws IOException;
static native SocketAddress[] getLocalAddresses0(int fd) throws IOException;
static native SocketAddress[] getRemoteAddresses0(int fd, int assocId)
throws IOException;
static native int branch0(int fd, int assocId) throws IOException;
static native void setPrimAddrOption0(int fd, int assocId, InetAddress ia,
int port) throws IOException;
static native void setPeerPrimAddrOption0(int fd, int assocId,
InetAddress ia, int port, boolean preferIPv6) throws IOException;
static native SocketAddress getPrimAddrOption0(int fd, int assocId)
throws IOException;
/* retVals [0] maxInStreams, [1] maxOutStreams */
static native void getInitMsgOption0(int fd, int[] retVals) throws IOException;
static native void setInitMsgOption0(int fd, int arg1, int arg2)
throws IOException;
static native void shutdown0(int fd, int assocId);
static native void init();
static {
init();
}
}

View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.ch.sctp;
import com.sun.nio.sctp.Association;
import com.sun.nio.sctp.Notification;
/**
* All Notification implemenations MUST implement this interface to provide
* access to the native association identidier.
*/
interface SctpNotification extends Notification {
int assocId();
void setAssociation(Association association);
}

View file

@ -0,0 +1,438 @@
/*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.ch.sctp;
import java.net.SocketAddress;
import java.net.InetSocketAddress;
import java.net.InetAddress;
import java.io.FileDescriptor;
import java.io.IOException;
import java.util.Collections;
import java.util.Set;
import java.util.HashSet;
import java.nio.channels.SelectionKey;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.NotYetBoundException;
import java.nio.channels.spi.SelectorProvider;
import com.sun.nio.sctp.IllegalUnbindException;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.SctpServerChannel;
import com.sun.nio.sctp.SctpSocketOption;
import com.sun.nio.sctp.SctpStandardSocketOptions;
import sun.nio.ch.DirectBuffer;
import sun.nio.ch.NativeThread;
import sun.nio.ch.IOStatus;
import sun.nio.ch.IOUtil;
import sun.nio.ch.Net;
import sun.nio.ch.PollArrayWrapper;
import sun.nio.ch.SelChImpl;
import sun.nio.ch.SelectionKeyImpl;
import sun.nio.ch.Util;
/**
* An implementation of SctpServerChannel
*/
public class SctpServerChannelImpl extends SctpServerChannel
implements SelChImpl
{
private final FileDescriptor fd;
private final int fdVal;
/* IDs of native thread doing accept, for signalling */
private volatile long thread = 0;
/* Lock held by thread currently blocked in this channel */
private final Object lock = new Object();
/* Lock held by any thread that modifies the state fields declared below
* DO NOT invoke a blocking I/O operation while holding this lock! */
private final Object stateLock = new Object();
private enum ChannelState {
UNINITIALIZED,
INUSE,
KILLPENDING,
KILLED,
}
/* -- The following fields are protected by stateLock -- */
private ChannelState state = ChannelState.UNINITIALIZED;
/* Binding: Once bound the port will remain constant. */
int port = -1;
private HashSet<InetSocketAddress> localAddresses = new HashSet<InetSocketAddress>();
/* Has the channel been bound to the wildcard address */
private boolean wildcard; /* false */
/* -- End of fields protected by stateLock -- */
/**
* Initializes a new instance of this class.
*/
public SctpServerChannelImpl(SelectorProvider provider)
throws IOException {
//TODO: update provider remove public modifier
super(provider);
this.fd = SctpNet.socket(true);
this.fdVal = IOUtil.fdVal(fd);
this.state = ChannelState.INUSE;
}
@Override
public SctpServerChannel bind(SocketAddress local, int backlog)
throws IOException {
synchronized (lock) {
synchronized (stateLock) {
if (!isOpen())
throw new ClosedChannelException();
if (isBound())
SctpNet.throwAlreadyBoundException();
InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local);
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkListen(isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort());
InetSocketAddress boundIsa = Net.localAddress(fd);
port = boundIsa.getPort();
localAddresses.add(isa);
if (isa.getAddress().isAnyLocalAddress())
wildcard = true;
SctpNet.listen(fdVal, backlog < 1 ? 50 : backlog);
}
}
return this;
}
@Override
public SctpServerChannel bindAddress(InetAddress address)
throws IOException {
return bindUnbindAddress(address, true);
}
@Override
public SctpServerChannel unbindAddress(InetAddress address)
throws IOException {
return bindUnbindAddress(address, false);
}
private SctpServerChannel bindUnbindAddress(InetAddress address, boolean add)
throws IOException {
if (address == null)
throw new IllegalArgumentException();
synchronized (lock) {
synchronized (stateLock) {
if (!isOpen())
throw new ClosedChannelException();
if (!isBound())
throw new NotYetBoundException();
if (wildcard)
throw new IllegalStateException(
"Cannot add or remove addresses from a channel that is bound to the wildcard address");
if (address.isAnyLocalAddress())
throw new IllegalArgumentException(
"Cannot add or remove the wildcard address");
if (add) {
for (InetSocketAddress addr : localAddresses) {
if (addr.getAddress().equals(address)) {
SctpNet.throwAlreadyBoundException();
}
}
} else { /*removing */
/* Verify that there is more than one address
* and that address is already bound */
if (localAddresses.size() <= 1)
throw new IllegalUnbindException("Cannot remove address from a channel with only one address bound");
boolean foundAddress = false;
for (InetSocketAddress addr : localAddresses) {
if (addr.getAddress().equals(address)) {
foundAddress = true;
break;
}
}
if (!foundAddress )
throw new IllegalUnbindException("Cannot remove address from a channel that is not bound to that address");
}
SctpNet.bindx(fdVal, new InetAddress[]{address}, port, add);
/* Update our internal Set to reflect the addition/removal */
if (add)
localAddresses.add(new InetSocketAddress(address, port));
else {
for (InetSocketAddress addr : localAddresses) {
if (addr.getAddress().equals(address)) {
localAddresses.remove(addr);
break;
}
}
}
}
}
return this;
}
private boolean isBound() {
synchronized (stateLock) {
return port == -1 ? false : true;
}
}
private void acceptCleanup() throws IOException {
synchronized (stateLock) {
thread = 0;
if (state == ChannelState.KILLPENDING)
kill();
}
}
@Override
public SctpChannel accept() throws IOException {
synchronized (lock) {
if (!isOpen())
throw new ClosedChannelException();
if (!isBound())
throw new NotYetBoundException();
SctpChannel sc = null;
int n = 0;
FileDescriptor newfd = new FileDescriptor();
InetSocketAddress[] isaa = new InetSocketAddress[1];
try {
begin();
if (!isOpen())
return null;
thread = NativeThread.current();
for (;;) {
n = accept0(fd, newfd, isaa);
if ((n == IOStatus.INTERRUPTED) && isOpen())
continue;
break;
}
} finally {
acceptCleanup();
end(n > 0);
assert IOStatus.check(n);
}
if (n < 1)
return null;
IOUtil.configureBlocking(newfd, true);
InetSocketAddress isa = isaa[0];
sc = new SctpChannelImpl(provider(), newfd);
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkAccept(isa.getAddress().getHostAddress(),
isa.getPort());
return sc;
}
}
@Override
protected void implConfigureBlocking(boolean block) throws IOException {
IOUtil.configureBlocking(fd, block);
}
@Override
public void implCloseSelectableChannel() throws IOException {
synchronized (stateLock) {
SctpNet.preClose(fdVal);
if (thread != 0)
NativeThread.signal(thread);
if (!isRegistered())
kill();
}
}
@Override
public void kill() throws IOException {
synchronized (stateLock) {
if (state == ChannelState.KILLED)
return;
if (state == ChannelState.UNINITIALIZED) {
state = ChannelState.KILLED;
return;
}
assert !isOpen() && !isRegistered();
// Postpone the kill if there is a thread in accept
if (thread == 0) {
SctpNet.close(fdVal);
state = ChannelState.KILLED;
} else {
state = ChannelState.KILLPENDING;
}
}
}
@Override
public FileDescriptor getFD() {
return fd;
}
@Override
public int getFDVal() {
return fdVal;
}
/**
* Translates native poll revent ops into a ready operation ops
*/
private boolean translateReadyOps(int ops, int initialOps,
SelectionKeyImpl sk) {
int intOps = sk.nioInterestOps();
int oldOps = sk.nioReadyOps();
int newOps = initialOps;
if ((ops & Net.POLLNVAL) != 0) {
/* This should only happen if this channel is pre-closed while a
* selection operation is in progress
* ## Throw an error if this channel has not been pre-closed */
return false;
}
if ((ops & (Net.POLLERR | Net.POLLHUP)) != 0) {
newOps = intOps;
sk.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
if (((ops & Net.POLLIN) != 0) &&
((intOps & SelectionKey.OP_ACCEPT) != 0))
newOps |= SelectionKey.OP_ACCEPT;
sk.nioReadyOps(newOps);
return (newOps & ~oldOps) != 0;
}
@Override
public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk) {
return translateReadyOps(ops, sk.nioReadyOps(), sk);
}
@Override
public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk) {
return translateReadyOps(ops, 0, sk);
}
@Override
public void translateAndSetInterestOps(int ops, SelectionKeyImpl sk) {
int newOps = 0;
/* Translate ops */
if ((ops & SelectionKey.OP_ACCEPT) != 0)
newOps |= Net.POLLIN;
/* Place ops into pollfd array */
sk.selector.putEventOps(sk, newOps);
}
@Override
public <T> SctpServerChannel setOption(SctpSocketOption<T> name, T value)
throws IOException {
if (name == null)
throw new NullPointerException();
if (!supportedOptions().contains(name))
throw new UnsupportedOperationException("'" + name + "' not supported");
synchronized (stateLock) {
if (!isOpen())
throw new ClosedChannelException();
SctpNet.setSocketOption(fdVal, name, value, 0 /*oneToOne*/);
return this;
}
}
@Override
@SuppressWarnings("unchecked")
public <T> T getOption(SctpSocketOption<T> name) throws IOException {
if (name == null)
throw new NullPointerException();
if (!supportedOptions().contains(name))
throw new UnsupportedOperationException("'" + name + "' not supported");
synchronized (stateLock) {
if (!isOpen())
throw new ClosedChannelException();
return (T) SctpNet.getSocketOption(fdVal, name, 0 /*oneToOne*/);
}
}
private static class DefaultOptionsHolder {
static final Set<SctpSocketOption<?>> defaultOptions = defaultOptions();
private static Set<SctpSocketOption<?>> defaultOptions() {
HashSet<SctpSocketOption<?>> set = new HashSet<SctpSocketOption<?>>(1);
set.add(SctpStandardSocketOptions.SCTP_INIT_MAXSTREAMS);
return Collections.unmodifiableSet(set);
}
}
@Override
public final Set<SctpSocketOption<?>> supportedOptions() {
return DefaultOptionsHolder.defaultOptions;
}
@Override
public Set<SocketAddress> getAllLocalAddresses()
throws IOException {
synchronized (stateLock) {
if (!isOpen())
throw new ClosedChannelException();
if (!isBound())
return Collections.emptySet();
return SctpNet.getLocalAddresses(fdVal);
}
}
/* Native */
private static native void initIDs();
private static native int accept0(FileDescriptor ssfd,
FileDescriptor newfd, InetSocketAddress[] isaa) throws IOException;
static {
IOUtil.load(); // loads nio & net native libraries
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
System.loadLibrary("sctp");
return null;
}
});
initIDs();
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.ch.sctp;
import java.nio.ByteBuffer;
import java.net.SocketAddress;
import com.sun.nio.sctp.Association;
import com.sun.nio.sctp.SendFailedNotification;
/**
* An implementation of SendFailedNotification
*/
public class SendFailed extends SendFailedNotification
implements SctpNotification
{
private Association association;
/* assocId is used to lookup the association before the notification is
* returned to user code */
private int assocId;
private SocketAddress address;
private ByteBuffer buffer;
private int errorCode;
private int streamNumber;
/* Invoked from native */
private SendFailed(int assocId,
SocketAddress address,
ByteBuffer buffer,
int errorCode,
int streamNumber) {
this.assocId = assocId;
this.errorCode = errorCode;
this.streamNumber = streamNumber;
this.address = address;
this.buffer = buffer;
}
@Override
public int assocId() {
return assocId;
}
@Override
public void setAssociation(Association association) {
this.association = association;
}
@Override
public Association association() {
/* may be null */
return association;
}
@Override
public SocketAddress address() {
assert address != null;
return address;
}
@Override
public ByteBuffer buffer() {
assert buffer != null;
return buffer;
}
@Override
public int errorCode() {
return errorCode;
}
@Override
public int streamNumber() {
return streamNumber;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(super.toString()).append(" [");
sb.append("Association:").append(association);
sb.append(", Address: ").append(address);
sb.append(", buffer: ").append(buffer);
sb.append(", errorCode: ").append(errorCode);
sb.append(", streamNumber: ").append(streamNumber);
sb.append("]");
return sb.toString();
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.nio.ch.sctp;
import com.sun.nio.sctp.Association;
import com.sun.nio.sctp.ShutdownNotification;
/**
* An implementation of ShutdownNotification
*/
public class Shutdown extends ShutdownNotification
implements SctpNotification
{
private Association association;
/* assocId is used to lookup the association before the notification is
* returned to user code */
private int assocId;
/* Invoked from native */
private Shutdown(int assocId) {
this.assocId = assocId;
}
@Override
public int assocId() {
return assocId;
}
@Override
public void setAssociation(Association association) {
this.association = association;
}
@Override
public Association association() {
assert association != null;
return association;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(super.toString()).append(" [");
sb.append("Association:").append(association).append("]");
return sb.toString();
}
}