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,150 @@
/*
* 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.net.SocketAddress;
import java.net.InetAddress;
import java.io.IOException;
import java.util.Set;
import java.nio.ByteBuffer;
import java.nio.channels.spi.SelectorProvider;
import com.sun.nio.sctp.Association;
import com.sun.nio.sctp.MessageInfo;
import com.sun.nio.sctp.NotificationHandler;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.SctpSocketOption;
/**
* Unimplemented.
*/
public class SctpChannelImpl extends SctpChannel
{
private static final String message = "SCTP not supported on this platform";
public SctpChannelImpl(SelectorProvider provider) {
super(provider);
throw new UnsupportedOperationException(message);
}
@Override
public Association association() {
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel bind(SocketAddress local)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel bindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel unbindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public boolean connect(SocketAddress remote) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public boolean connect(SocketAddress remote, int maxOutStreams,
int maxInStreams) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public boolean isConnectionPending() {
throw new UnsupportedOperationException(message);
}
@Override
public boolean finishConnect() throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SocketAddress> getAllLocalAddresses()
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SocketAddress> getRemoteAddresses()
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel shutdown() throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> T getOption(SctpSocketOption<T> name)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> SctpChannel setOption(SctpSocketOption<T> name, T value)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SctpSocketOption<?>> supportedOptions() {
throw new UnsupportedOperationException(message);
}
@Override
public <T> MessageInfo receive(ByteBuffer dst, T attachment,
NotificationHandler<T> handler) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public int send(ByteBuffer src, MessageInfo messageInfo)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
protected void implConfigureBlocking(boolean block) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public void implCloseSelectableChannel() throws IOException {
throw new UnsupportedOperationException(message);
}
}

View file

@ -0,0 +1,137 @@
/*
* 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.net.SocketAddress;
import java.net.InetAddress;
import java.io.IOException;
import java.util.Set;
import java.nio.ByteBuffer;
import java.nio.channels.spi.SelectorProvider;
import com.sun.nio.sctp.Association;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.MessageInfo;
import com.sun.nio.sctp.NotificationHandler;
import com.sun.nio.sctp.SctpMultiChannel;
import com.sun.nio.sctp.SctpSocketOption;
/**
* Unimplemented.
*/
public class SctpMultiChannelImpl extends SctpMultiChannel
{
private static final String message = "SCTP not supported on this platform";
public SctpMultiChannelImpl(SelectorProvider provider) {
super(provider);
throw new UnsupportedOperationException(message);
}
@Override
public Set<Association> associations() {
throw new UnsupportedOperationException(message);
}
@Override
public SctpMultiChannel bind(SocketAddress local,
int backlog) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpMultiChannel bindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpMultiChannel unbindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SocketAddress> getAllLocalAddresses()
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SocketAddress> getRemoteAddresses
(Association association) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpMultiChannel shutdown(Association association)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> T getOption(SctpSocketOption<T> name,
Association association) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> SctpMultiChannel setOption(SctpSocketOption<T> name,
T value, Association association) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SctpSocketOption<?>> supportedOptions() {
throw new UnsupportedOperationException(message);
}
@Override
public <T> MessageInfo receive(ByteBuffer buffer, T attachment,
NotificationHandler<T> handler) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public int send(ByteBuffer buffer, MessageInfo messageInfo)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel branch(Association association)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
protected void implConfigureBlocking(boolean block) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public void implCloseSelectableChannel() throws IOException {
throw new UnsupportedOperationException(message);
}
}

View file

@ -0,0 +1,102 @@
/*
* 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.net.SocketAddress;
import java.net.InetAddress;
import java.io.IOException;
import java.util.Set;
import java.nio.channels.spi.SelectorProvider;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.SctpServerChannel;
import com.sun.nio.sctp.SctpSocketOption;
/**
* Unimplemented.
*/
public class SctpServerChannelImpl extends SctpServerChannel
{
private static final String message = "SCTP not supported on this platform";
public SctpServerChannelImpl(SelectorProvider provider) {
super(provider);
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel accept() throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpServerChannel bind(SocketAddress local,
int backlog) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpServerChannel bindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpServerChannel unbindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SocketAddress> getAllLocalAddresses()
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> T getOption(SctpSocketOption<T> name) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> SctpServerChannel setOption(SctpSocketOption<T> name,
T value) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SctpSocketOption<?>> supportedOptions() {
throw new UnsupportedOperationException(message);
}
@Override
protected void implConfigureBlocking(boolean block) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public void implCloseSelectableChannel() throws IOException {
throw new UnsupportedOperationException(message);
}
}

View file

@ -0,0 +1,150 @@
/*
* 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.InetAddress;
import java.io.IOException;
import java.util.Set;
import java.nio.ByteBuffer;
import java.nio.channels.spi.SelectorProvider;
import com.sun.nio.sctp.Association;
import com.sun.nio.sctp.MessageInfo;
import com.sun.nio.sctp.NotificationHandler;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.SctpSocketOption;
/**
* Unimplemented.
*/
public class SctpChannelImpl extends SctpChannel
{
private static final String message = "SCTP not supported on this platform";
public SctpChannelImpl(SelectorProvider provider) {
super(provider);
throw new UnsupportedOperationException(message);
}
@Override
public Association association() {
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel bind(SocketAddress local)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel bindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel unbindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public boolean connect(SocketAddress remote) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public boolean connect(SocketAddress remote, int maxOutStreams,
int maxInStreams) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public boolean isConnectionPending() {
throw new UnsupportedOperationException(message);
}
@Override
public boolean finishConnect() throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SocketAddress> getAllLocalAddresses()
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SocketAddress> getRemoteAddresses()
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel shutdown() throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> T getOption(SctpSocketOption<T> name)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> SctpChannel setOption(SctpSocketOption<T> name, T value)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SctpSocketOption<?>> supportedOptions() {
throw new UnsupportedOperationException(message);
}
@Override
public <T> MessageInfo receive(ByteBuffer dst, T attachment,
NotificationHandler<T> handler) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public int send(ByteBuffer src, MessageInfo messageInfo)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
protected void implConfigureBlocking(boolean block) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public void implCloseSelectableChannel() throws IOException {
throw new UnsupportedOperationException(message);
}
}

View file

@ -0,0 +1,137 @@
/*
* 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.InetAddress;
import java.io.IOException;
import java.util.Set;
import java.nio.ByteBuffer;
import java.nio.channels.spi.SelectorProvider;
import com.sun.nio.sctp.Association;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.MessageInfo;
import com.sun.nio.sctp.NotificationHandler;
import com.sun.nio.sctp.SctpMultiChannel;
import com.sun.nio.sctp.SctpSocketOption;
/**
* Unimplemented.
*/
public class SctpMultiChannelImpl extends SctpMultiChannel
{
private static final String message = "SCTP not supported on this platform";
public SctpMultiChannelImpl(SelectorProvider provider) {
super(provider);
throw new UnsupportedOperationException(message);
}
@Override
public Set<Association> associations() {
throw new UnsupportedOperationException(message);
}
@Override
public SctpMultiChannel bind(SocketAddress local,
int backlog) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpMultiChannel bindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpMultiChannel unbindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SocketAddress> getAllLocalAddresses()
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SocketAddress> getRemoteAddresses
(Association association) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpMultiChannel shutdown(Association association)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> T getOption(SctpSocketOption<T> name,
Association association) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> SctpMultiChannel setOption(SctpSocketOption<T> name,
T value, Association association) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SctpSocketOption<?>> supportedOptions() {
throw new UnsupportedOperationException(message);
}
@Override
public <T> MessageInfo receive(ByteBuffer buffer, T attachment,
NotificationHandler<T> handler) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public int send(ByteBuffer buffer, MessageInfo messageInfo)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel branch(Association association)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
protected void implConfigureBlocking(boolean block) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public void implCloseSelectableChannel() throws IOException {
throw new UnsupportedOperationException(message);
}
}

View file

@ -0,0 +1,102 @@
/*
* 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.InetAddress;
import java.io.IOException;
import java.util.Set;
import java.nio.channels.spi.SelectorProvider;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.SctpServerChannel;
import com.sun.nio.sctp.SctpSocketOption;
/**
* Unimplemented.
*/
public class SctpServerChannelImpl extends SctpServerChannel
{
private static final String message = "SCTP not supported on this platform";
public SctpServerChannelImpl(SelectorProvider provider) {
super(provider);
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel accept() throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpServerChannel bind(SocketAddress local,
int backlog) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpServerChannel bindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpServerChannel unbindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SocketAddress> getAllLocalAddresses()
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> T getOption(SctpSocketOption<T> name) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> SctpServerChannel setOption(SctpSocketOption<T> name,
T value) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SctpSocketOption<?>> supportedOptions() {
throw new UnsupportedOperationException(message);
}
@Override
protected void implConfigureBlocking(boolean block) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public void implCloseSelectableChannel() throws IOException {
throw new UnsupportedOperationException(message);
}
}

View file

@ -0,0 +1,140 @@
/*
* 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 com.sun.nio.sctp;
/**
* A skeletal handler that consumes notifications and continues.
*
* <P> This class trivially implements the {@code handleNotification} methods to
* return {@link HandlerResult#CONTINUE CONTINUE} so that all notifications are
* consumed and the channel continues to try and receive a message.
*
* <P> It also provides overloaded versions of the {@code handleNotification}
* methods, one for each of the required supported notification types, {@link
* AssociationChangeNotification}, {@link PeerAddressChangeNotification},
* {@link SendFailedNotification}, and {@link ShutdownNotification}. The
* appropriate method will be invoked when the notification is received.
*
* @since 1.7
*/
public class AbstractNotificationHandler<T>
implements NotificationHandler<T>
{
/**
* Initializes a new instance of this class.
*/
protected AbstractNotificationHandler() {}
/**
* Invoked when an implementation specific notification is received from the
* SCTP stack.
*
* @param notification
* The notification
*
* @param attachment
* The object attached to the {@code receive} operation when it was
* initiated.
*
* @return The handler result
*/
@Override
public HandlerResult handleNotification(Notification notification,
T attachment) {
return HandlerResult.CONTINUE;
}
/**
* Invoked when an {@link AssociationChangeNotification} is received from
* the SCTP stack.
*
* @param notification
* The notification
*
* @param attachment
* The object attached to the {@code receive} operation when it was
* initiated.
*
* @return The handler result
*/
public HandlerResult handleNotification(AssociationChangeNotification notification,
T attachment) {
return HandlerResult.CONTINUE;
}
/**
* Invoked when an {@link PeerAddressChangeNotification} is received from
* the SCTP stack.
*
* @param notification
* The notification
*
* @param attachment
* The object attached to the {@code receive} operation when it was
* initiated.
*
* @return The handler result
*/
public HandlerResult handleNotification(PeerAddressChangeNotification notification,
T attachment) {
return HandlerResult.CONTINUE;
}
/**
* Invoked when an {@link SendFailedNotification} is received from
* the SCTP stack.
*
* @param notification
* The notification
*
* @param attachment
* The object attached to the {@code receive} operation when it was
* initiated.
*
* @return The handler result
*/
public HandlerResult handleNotification(SendFailedNotification notification,
T attachment) {
return HandlerResult.CONTINUE;
}
/**
* Invoked when an {@link ShutdownNotification} is received from
* the SCTP stack.
*
* @param notification
* The notification
*
* @param attachment
* The object attached to the {@code receive} operation when it was
* initiated.
*
* @return The handler result
*/
public HandlerResult handleNotification(ShutdownNotification notification,
T attachment) {
return HandlerResult.CONTINUE;
}
}

View file

@ -0,0 +1,111 @@
/*
* 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 com.sun.nio.sctp;
/**
* A class that represents an SCTP association.
*
* <P> An association exists between two SCTP endpoints. Each endpoint is
* represented by a list of transport addresses through which that endpoint can
* be reached and from which it will originate SCTP messages. The association
* spans over all of the possible source/destination combinations which may be
* generated from each endpoint's lists of addresses.
*
* <P> Associations are identified by their Association ID.
* Association ID's are guaranteed to be unique for the lifetime of the
* association. An association ID may be reused after the association has been
* shutdown. An association ID is not unique across multiple SCTP channels.
* An Association's local and remote addresses may change if the SCTP
* implementation supports <I>Dynamic Address Reconfiguration</I> as defined by
* <A HREF="http://tools.ietf.org/html/rfc5061">RFC5061</A>, see the
* {@code bindAddress} and {@code unbindAddress} methods of {@link SctpChannel},
* {@link SctpServerChannel}, and {@link SctpMultiChannel}.
*
* <P> An {@code Association} is returned from an {@link
* SctpChannel#association SctpChannel} or an {@link
* SctpMultiChannel#associations SctpMultiChannel}, as well
* as being given as a parameter to {@link NotificationHandler
* NotificationHandler} methods.
*
* @since 1.7
*/
public class Association {
private final int associationID;
private final int maxInStreams;
private final int maxOutStreams;
/**
* Initializes a new instance of this class.
*
* @param associationID
* The association ID
* @param maxInStreams
* The maximum number of inbound streams
* @param maxOutStreams
* The maximum number of outbound streams
*/
protected Association(int associationID,
int maxInStreams,
int maxOutStreams) {
this.associationID = associationID;
this.maxInStreams = maxInStreams;
this.maxOutStreams = maxOutStreams;
}
/**
* Returns the associationID.
*
* @return The association ID
*/
public final int associationID() {
return associationID;
};
/**
* Returns the maximum number of inbound streams that this association
* supports.
*
* <P> Data received on this association will be on stream number
* {@code s}, where {@code 0 <= s < maxInboundStreams()}.
*
* @return The maximum number of inbound streams
*/
public final int maxInboundStreams() {
return maxInStreams;
};
/**
* Returns the maximum number of outbound streams that this association
* supports.
*
* <P> Data sent on this association must be on stream number
* {@code s}, where {@code 0 <= s < maxOutboundStreams()}.
*
* @return The maximum number of outbound streams
*/
public final int maxOutboundStreams() {
return maxOutStreams;
};
}

View file

@ -0,0 +1,92 @@
/*
* 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 com.sun.nio.sctp;
/**
* Notification emitted when an association has either opened or closed.
*
* @since 1.7
*/
public abstract class AssociationChangeNotification
implements Notification
{
/**
* Defines the type of change event that happened to the association.
*
* @since 1.7
*/
public enum AssocChangeEvent
{
/**
* A new association is now ready and data may be exchanged with this peer.
*/
COMM_UP,
/**
* The association has failed. A series of SCTP send failed notifications
* will follow this notification, one for each outstanding message.
*/
COMM_LOST,
/**
* SCTP has detected that the peer has restarted.
*/
RESTART,
/**
* The association has gracefully closed.
*/
SHUTDOWN,
/**
* The association failed to setup. If a message was sent on a {@link
* SctpMultiChannel} in non-blocking mode, an
* SCTP send failed notification will follow this notification for the
* outstanding message.
*/
CANT_START
}
/**
* Initializes a new instance of this class.
*/
protected AssociationChangeNotification() {}
/**
* Returns the association that this notification is applicable to.
*
* @return The association whose state has changed, or {@code null} if
* there is no association, that is {@linkplain
* AssocChangeEvent#CANT_START CANT_START}
*/
public abstract Association association();
/**
* Returns the type of change event.
*
* @return The event
*/
public abstract AssocChangeEvent event();
}

View file

@ -0,0 +1,47 @@
/*
* 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 com.sun.nio.sctp;
/**
* Defines notification handler results.
*
* <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
* a message before returning.
*
* @since 1.7
*/
public enum HandlerResult {
/**
* Try to receieve another message or notification.
*/
CONTINUE,
/**
* Return without trying to receive any more data.
*/
RETURN;
}

View file

@ -0,0 +1,52 @@
/*
* 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 com.sun.nio.sctp;
/**
* Unchecked exception thrown when an attempt is made to invoke the
* {@code receive} method of {@link SctpChannel} or {@link SctpMultiChannel}
* from a notification handler.
*
* @since 1.7
*/
public class IllegalReceiveException extends IllegalStateException {
private static final long serialVersionUID = 2296619040988576224L;
/**
* Constructs an instance of this class.
*/
public IllegalReceiveException() { }
/**
* Constructs an instance of this class with the specified message.
*
* @param msg
* The String that contains a detailed message
*/
public IllegalReceiveException(String msg) {
super(msg);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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 com.sun.nio.sctp;
/**
* Unchecked exception thrown when an attempt is made to remove an
* address that is not bound to the channel, or remove an address from a
* channel that has only one address bound to it.
*
* @since 1.7
*/
public class IllegalUnbindException extends IllegalStateException {
private static final long serialVersionUID = -310540883995532224L;
/**
* Constructs an instance of this class.
*/
public IllegalUnbindException() { }
/**
* Constructs an instance of this class with the specified detailed message.
*
* @param msg
* The String that contains a detailed message
*/
public IllegalUnbindException(String msg) {
super(msg);
}
}

View file

@ -0,0 +1,51 @@
/*
* 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 com.sun.nio.sctp;
/**
* Unchecked exception thrown when an attempt is made to send a
* message to an invalid stream.
*
* @since 1.7
*/
public class InvalidStreamException extends IllegalArgumentException {
private static final long serialVersionUID = -9172703378046665558L;
/**
* Constructs an instance of this class.
*/
public InvalidStreamException() { }
/**
* Constructs an instance of this class with the specified detailed message.
*
* @param msg
* The String that contains a detailed message
*/
public InvalidStreamException(String msg) {
super(msg);
}
}

View file

@ -0,0 +1,303 @@
/*
* 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 com.sun.nio.sctp;
import java.net.SocketAddress;
/**
* The {@code MessageInfo} class provides additional ancillary information about
* messages.
*
* <P> Received SCTP messages, returned by
* {@link SctpChannel#receive SctpChannel.receive} and {@link
* SctpMultiChannel#receive SctpMultiChannel.receive},
* return a {@code MessageInfo} instance that can be queried to determine
* ancillary information about the received message. Messages being sent should
* use one of the {@link #createOutgoing(java.net.SocketAddress,int)
* createOutgoing} methods to provide ancillary data for the message being
* sent, and may use the appropriate setter methods to override the default
* values provided for {@link #isUnordered() unordered}, {@link #timeToLive()
* timeToLive}, {@link #isComplete() complete} and {@link #payloadProtocolID()
* payloadProtocolID}, before sending the message.
*
* <P> For out going messages the {@code timeToLive} parameter is a time period
* that the sending side SCTP stack may expire the message if it has not been
* sent. This time period is an indication to the stack that the message is no
* longer required to be sent after the time period expires. It is not a hard
* timeout and may be influenced by whether the association supports the partial
* reliability extension, <a href=http://www.ietf.org/rfc/rfc3758.txt>RFC 3758
* </a>.
*
* <P> {@code MessageInfo} instances are not safe for use by multiple concurrent
* threads. If a MessageInfo is to be used by more than one thread then access
* to the MessageInfo should be controlled by appropriate synchronization.
*
* @since 1.7
*/
public abstract class MessageInfo {
/**
* Initializes a new instance of this class.
*/
protected MessageInfo() {}
/**
* Creates a {@code MessageInfo} instance suitable for use when
* sending a message.
*
* <P> The returned instance will have its {@link #isUnordered() unordered}
* value set to {@code false}, its {@link #timeToLive() timeToLive} value
* set to {@code 0}, its {@link #isComplete() complete} value set
* to {@code true}, and its {@link #payloadProtocolID() payloadProtocolID}
* value set to {@code 0}. These values, if required, can be set through
* the appropriate setter method before sending the message.
*
* @param address
* For a connected {@code SctpChannel} the address is the
* preferred peer address of the association to send the message
* to, or {@code null} to use the peer primary address. For an
* {@code SctpMultiChannel} the address is used to determine
* the association, or if no association exists with a peer of that
* address then one is setup.
*
* @param streamNumber
* The stream number that the message will be sent on
*
* @return The outgoing message info
*
* @throws IllegalArgumentException
* If the streamNumber is negative or greater than {@code 65536}
*/
public static MessageInfo createOutgoing(SocketAddress address,
int streamNumber) {
if (streamNumber < 0 || streamNumber > 65536)
throw new IllegalArgumentException("Invalid stream number");
return new sun.nio.ch.sctp.MessageInfoImpl(null, address, streamNumber);
}
/**
* Creates a {@code MessageInfo} instance suitable for use when
* sending a message to a given association. Typically used for
* {@code SctpMultiChannel} when an association has already been setup.
*
* <P> The returned instance will have its {@link #isUnordered() unordered}
* value set to {@code false}, its {@link #timeToLive() timeToLive} value
* set to {@code 0}, its {@link #isComplete() complete} value set
* to {@code true}, and its {@link #payloadProtocolID() payloadProtocolID}
* value set to {@code 0}. These values, if required, can be set through
* the appropriate setter method before sending the message.
*
* @param association
* The association to send the message on
*
* @param address
* The preferred peer address of the association to send the message
* to, or {@code null} to use the peer primary address
*
* @param streamNumber
* The stream number that the message will be sent on.
*
* @return The outgoing message info
*
* @throws IllegalArgumentException
* If {@code association} is {@code null}, or the streamNumber is
* negative or greater than {@code 65536}
*/
public static MessageInfo createOutgoing(Association association,
SocketAddress address,
int streamNumber) {
if (association == null)
throw new IllegalArgumentException("association cannot be null");
if (streamNumber < 0 || streamNumber > 65536)
throw new IllegalArgumentException("Invalid stream number");
return new sun.nio.ch.sctp.MessageInfoImpl(association,
address, streamNumber);
}
/**
* Returns the source socket address if the message has been received,
* otherwise the preferred destination of the message to be sent.
*
* @return The socket address, or {@code null} if this instance is to be
* used for sending a message and has been construced without
* specifying a preferred destination address
*
*/
public abstract SocketAddress address();
/**
* Returns the association that the message was received on, if the message
* has been received, otherwise the association that the message is to be
* sent on.
*
* @return The association, or {@code null} if this instance is to be
* used for sending a message and has been construced using the
* the {@link #createOutgoing(SocketAddress,int)
* createOutgoing(SocketAddress,int)} static factory method
*/
public abstract Association association();
/**
* Returns the number of bytes read for the received message.
*
* <P> This method is only appicable for received messages, it has no
* meaning for messages being sent.
*
* @return The number of bytes read, {@code -1} if the channel is an {@link
* SctpChannel} that has reached end-of-stream, otherwise
* {@code 0}
*/
public abstract int bytes();
/**
* Tells whether or not the message is complete.
*
* <P> For received messages {@code true} indicates that the message was
* completely received. For messages being sent {@code true} indicates that
* the message is complete, {@code false} indicates that the message is not
* complete. How the send channel interprets this value depends on the value
* of its {@link SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE
* SCTP_EXPLICIT_COMPLETE} socket option.
*
* @return {@code true} if, and only if, the message is complete
*/
public abstract boolean isComplete();
/**
* Sets whether or not the message is complete.
*
* <P> For messages being sent {@code true} indicates that
* the message is complete, {@code false} indicates that the message is not
* complete. How the send channel interprets this value depends on the value
* of its {@link SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE
* SCTP_EXPLICIT_COMPLETE} socket option.
*
* @param complete
* {@code true} if, and only if, the message is complete
*
* @return This MessageInfo
*
* @see MessageInfo#isComplete()
*/
public abstract MessageInfo complete(boolean complete);
/**
* Tells whether or not the message is unordered. For received messages
* {@code true} indicates that the message was sent non-ordered. For
* messages being sent {@code true} requests the un-ordered delivery of the
* message, {@code false} indicates that the message is ordered.
*
* @return {@code true} if the message is unordered, otherwise
* {@code false}
*/
public abstract boolean isUnordered();
/**
* Sets whether or not the message is unordered.
*
* @param unordered
* {@code true} requests the un-ordered delivery of the message,
* {@code false} indicates that the message is ordered.
*
* @return This MessageInfo
*
* @see MessageInfo#isUnordered()
*/
public abstract MessageInfo unordered(boolean unordered);
/**
* Returns the payload protocol Identifier.
*
* <P> A value indicating the type of payload protocol data being
* transmitted/received. This value is passed as opaque data by SCTP.
* {@code 0} indicates an unspecified payload protocol identifier.
*
* @return The Payload Protocol Identifier
*/
public abstract int payloadProtocolID();
/**
* Sets the payload protocol Identifier.
*
* <P> A value indicating the type of payload protocol data being
* transmitted. This value is passed as opaque data by SCTP.
*
* @param ppid
* The Payload Protocol Identifier, or {@code 0} indicate an
* unspecified payload protocol identifier.
*
* @return This MessageInfo
*
* @see MessageInfo#payloadProtocolID()
*/
public abstract MessageInfo payloadProtocolID(int ppid);
/**
* Returns the stream number that the message was received on, if the
* message has been received, otherwise the stream number that the message
* is to be sent on.
*
* @return The stream number
*/
public abstract int streamNumber();
/**
* Sets the stream number that the message is to be sent on.
*
* @param streamNumber
* The stream number
*
* @throws IllegalArgumentException
* If the streamNumber is negative or greater than {@code 65536}
*
* @return This MessageInfo
*/
public abstract MessageInfo streamNumber(int streamNumber);
/**
* The time period that the sending side may expire the message if it has
* not been sent, or {@code 0} to indicate that no timeout should occur. This
* value is only applicable for messages being sent, it has no meaning for
* received messages.
*
* @return The time period in milliseconds, or {@code 0}
*/
public abstract long timeToLive();
/**
* Sets the time period that the sending side may expire the message if it
* has not been sent.
*
* @param millis
* The time period in milliseconds, or {@code 0} to indicate that no
* timeout should occur
*
* @return This MessageInfo
*
* @see MessageInfo#timeToLive()
*/
public abstract MessageInfo timeToLive(long millis);
}

View file

@ -0,0 +1,47 @@
/*
* 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 com.sun.nio.sctp;
/**
* A notification from the SCTP stack.
*
* <P> Objects of this type are passed to the {@link NotificationHandler} when
* a notification is received.
*
* <P> An SCTP channel supports the following notifications: {@link
* AssociationChangeNotification}, {@link PeerAddressChangeNotification},
* {@link SendFailedNotification}, {@link ShutdownNotification}, and may support
* additional implementation specific notifications.
*
* @since 1.7
*/
public interface Notification {
/**
* Returns the association that this notification is applicable to.
*
* @return The association
*/
public Association association();
}

View file

@ -0,0 +1,65 @@
/*
* 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 com.sun.nio.sctp;
/**
* A handler for consuming notifications from the SCTP stack.
*
* <P> The SCTP channels defined in this package allow a notification handler to
* be specified to consume notifications from the SCTP stack. When a
* notification is received the {@linkplain #handleNotification
* handleNotification} method of the handler is invoked to handle that
* notification.
*
* <P> Additionally, an attachment object can be attached to the {@code receive}
* operation to provide context when consuming the notification. The
* attachment is important for cases where a <i>state-less</i> {@code
* NotificationHandler} is used to consume the result of many {@code receive}
* operations.
*
* <P> Handler implementations are encouraged to extend the {@link
* AbstractNotificationHandler} class which implements this interface and
* provide notification specific methods. However, an API should generally use
* this handler interface as the type for parameters, return type, etc. rather
* than the abstract class.
*
* @param T The type of the object attached to the receive operation
*
* @since 1.7
*/
public interface NotificationHandler<T> {
/**
* Invoked when a notification is received from the SCTP stack.
*
* @param notification
* The notification
*
* @param attachment
* The object attached to the receive operation when it was initiated.
*
* @return The handler result
*/
HandlerResult handleNotification(Notification notification, T attachment);
}

View file

@ -0,0 +1,107 @@
/*
* 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 com.sun.nio.sctp;
import java.net.SocketAddress;
/**
* Notification emitted when a destination address on a multi-homed peer
* encounters a change.
*
* @since 1.7
*/
public abstract class PeerAddressChangeNotification
implements Notification
{
/**
* Defines the type of address change event that occurred to the destination
* address on a multi-homed peer when it encounters a change of interface
* details.
*
* <P> Some of these events types are only generated when the association
* supports dynamic address reconfiguration, e.g. {@code SCTP_ADDR_ADDED},
* {@code SCTP_ADDR_REMOVED}, etc.
*
* @since 1.7
*/
public enum AddressChangeEvent {
/**
* This address is now reachable.
*/
ADDR_AVAILABLE,
/**
* The address specified can no longer be reached. Any data sent to this
* address is rerouted to an alternate until this address becomes reachable.
*/
ADDR_UNREACHABLE,
/**
* The address is no longer part of the association.
*/
ADDR_REMOVED,
/**
* The address is now part of the association.
*/
ADDR_ADDED,
/**
* This address has now been made to be the primary destination address.
*/
ADDR_MADE_PRIMARY,
/**
* This address has now been confirmed as a valid address.
*/
ADDR_CONFIRMED;
}
/**
* Initializes a new instance of this class.
*/
protected PeerAddressChangeNotification() {}
/**
* Returns the peer address.
*
* @return The peer address
*/
public abstract SocketAddress address();
/**
* Returns the association that this notification is applicable to.
*
* @return The association whose peer address changed
*/
public abstract Association association();
/**
* Returns the type of change event.
*
* @return The event
*/
public abstract AddressChangeEvent event();
}

View file

@ -0,0 +1,878 @@
/*
* Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.nio.sctp;
import java.net.SocketAddress;
import java.net.InetAddress;
import java.io.IOException;
import java.util.Set;
import java.nio.ByteBuffer;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
/**
* A selectable channel for message-oriented connected SCTP sockets.
*
* <P> An SCTP channel can only control one SCTP association.
* An {@code SCTPChannel} is created by invoking one of the
* {@link #open open} methods of this class. A newly-created channel is open but
* not yet connected, that is, there is no association setup with a remote peer.
* An attempt to invoke an I/O operation upon an unconnected
* channel will cause a {@link java.nio.channels.NotYetConnectedException} to be
* thrown. An association can be setup by connecting the channel using one of
* its {@link #connect connect} methods. Once connected, the channel remains
* connected until it is closed. Whether or not a channel is connected may be
* determined by invoking {@link #getRemoteAddresses getRemoteAddresses}.
*
* <p> SCTP channels support <i>non-blocking connection:</i>&nbsp;A
* channel may be created and the process of establishing the link to
* the remote socket may be initiated via the {@link #connect connect} method
* for later completion by the {@link #finishConnect finishConnect} method.
* Whether or not a connection operation is in progress may be determined by
* invoking the {@link #isConnectionPending isConnectionPending} method.
*
* <p> Socket options are configured using the
* {@link #setOption(SctpSocketOption,Object) setOption} method. An SCTP
* channel support the following options:
* <blockquote>
* <table class="striped">
* <caption style="display:none">Socket options</caption>
* <thead>
* <tr>
* <th scope="col">Option Name</th>
* <th scope="col">Description</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SCTP_DISABLE_FRAGMENTS
* SCTP_DISABLE_FRAGMENTS} </th>
* <td> Enables or disables message fragmentation </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE
* SCTP_EXPLICIT_COMPLETE} </th>
* <td> Enables or disables explicit message completion </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SCTP_FRAGMENT_INTERLEAVE
* SCTP_FRAGMENT_INTERLEAVE} </th>
* <td> Controls how the presentation of messages occur for the message
* receiver </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SCTP_INIT_MAXSTREAMS
* SCTP_INIT_MAXSTREAMS} </th>
* <td> The maximum number of streams requested by the local endpoint during
* association initialization </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SCTP_NODELAY SCTP_NODELAY} </th>
* <td> Enables or disable a Nagle-like algorithm </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SCTP_PRIMARY_ADDR
* SCTP_PRIMARY_ADDR} </th>
* <td> Requests that the local SCTP stack use the given peer address as the
* association primary </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SCTP_SET_PEER_PRIMARY_ADDR
* SCTP_SET_PEER_PRIMARY_ADDR} </th>
* <td> Requests that the peer mark the enclosed address as the association
* primary </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SO_SNDBUF
* SO_SNDBUF} </th>
* <td> The size of the socket send buffer </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SO_RCVBUF
* SO_RCVBUF} </th>
* <td> The size of the socket receive buffer </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SO_LINGER
* SO_LINGER} </th>
* <td> Linger on close if data is present (when configured in blocking mode
* only) </td>
* </tr>
* </tbody>
* </table>
* </blockquote>
* Additional (implementation specific) options may also be supported. The list
* of options supported is obtained by invoking the {@link #supportedOptions()
* supportedOptions} method.
*
* <p> SCTP channels are safe for use by multiple concurrent threads.
* They support concurrent reading and writing, though at most one thread may be
* reading and at most one thread may be writing at any given time. The
* {@link #connect connect} and {@link #finishConnect
* finishConnect} methods are mutually synchronized against each other, and
* an attempt to initiate a send or receive operation while an invocation of one
* of these methods is in progress will block until that invocation is complete.
*
* @since 1.7
*/
public abstract class SctpChannel
extends AbstractSelectableChannel
{
/**
* Initializes a new instance of this class.
*
* @param provider
* The selector provider for this channel
*/
protected SctpChannel(SelectorProvider provider) {
super(provider);
}
/**
* Opens an SCTP channel.
*
* <P> The new channel is unbound and unconnected.
*
* @return A new SCTP channel
*
* @throws UnsupportedOperationException
* If the SCTP protocol is not supported
*
* @throws IOException
* If an I/O error occurs
*/
public static SctpChannel open() throws
IOException {
return new sun.nio.ch.sctp.SctpChannelImpl((SelectorProvider)null);
}
/**
* Opens an SCTP channel and connects it to a remote address.
*
* <P> This is a convenience method and is equivalent to evaluating the
* following expression:
* <blockquote><pre>
* open().connect(remote, maxOutStreams, maxInStreams);
* </pre></blockquote>
*
* @param remote
* The remote address to which the new channel is to be connected
*
* @param maxOutStreams
* The number of streams that the application wishes to be able
* to send to. Must be non negative and no larger than {@code 65536}.
* {@code 0} to use the endpoints default value.
*
* @param maxInStreams
* The maximum number of inbound streams the application is prepared
* to support. Must be non negative and no larger than {@code 65536}.
* {@code 0} to use the endpoints default value.
*
* @return A new SCTP channel connected to the given address
*
* @throws java.nio.channels.AsynchronousCloseException
* If another thread closes this channel
* while the connect operation is in progress
*
* @throws java.nio.channels.ClosedByInterruptException
* If another thread interrupts the current thread
* while the connect operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws java.nio.channels.UnresolvedAddressException
* If the given remote address is not fully resolved
*
* @throws java.nio.channels.UnsupportedAddressTypeException
* If the type of the given remote address is not supported
*
* @throws SecurityException
* If a security manager has been installed
* and it does not permit access to the given remote peer
*
* @throws UnsupportedOperationException
* If the SCTP protocol is not supported
*
* @throws IOException
* If some other I/O error occurs
*/
public static SctpChannel open(SocketAddress remote, int maxOutStreams,
int maxInStreams) throws IOException {
SctpChannel ssc = SctpChannel.open();
ssc.connect(remote, maxOutStreams, maxInStreams);
return ssc;
}
/**
* Returns the association on this channel's socket.
*
* @return the association, or {@code null} if the channel's socket is not
* connected.
*
* @throws ClosedChannelException
* If the channel is closed
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract Association association() throws IOException;
/**
* Binds the channel's socket to a local address.
*
* <P> This method is used to establish a relationship between the socket
* and the local addresses. Once a relationship is established then
* the socket remains bound until the channel is closed. This relationship
* may not necesssarily be with the address {@code local} as it may be removed
* by {@link #unbindAddress unbindAddress}, but there will always be at least
* one local address bound to the channel's socket once an invocation of
* this method successfully completes.
*
* <P> Once the channel's socket has been successfully bound to a specific
* address, that is not automatically assigned, more addresses
* may be bound to it using {@link #bindAddress bindAddress}, or removed
* using {@link #unbindAddress unbindAddress}.
*
* @param local
* The local address to bind the socket, or {@code null} to
* bind the socket to an automatically assigned socket address
*
* @return This channel
*
* @throws java.nio.channels.AlreadyConnectedException
* If this channel is already connected
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.ConnectionPendingException
* If a non-blocking connection operation is already in progress on this channel
*
* @throws java.nio.channels.AlreadyBoundException
* If this channel is already bound
*
* @throws java.nio.channels.UnsupportedAddressTypeException
* If the type of the given address is not supported
*
* @throws IOException
* If some other I/O error occurs
*
* @throws SecurityException
* If a security manager has been installed and its
* {@link SecurityManager#checkListen checkListen} method denies
* the operation
*/
public abstract SctpChannel bind(SocketAddress local)
throws IOException;
/**
* Adds the given address to the bound addresses for the channel's
* socket.
*
* <P> The given address must not be the {@link
* java.net.InetAddress#isAnyLocalAddress wildcard} address.
* The channel must be first bound using {@link #bind bind} before
* invoking this method, otherwise {@link
* java.nio.channels.NotYetBoundException} is thrown. The {@link #bind bind}
* method takes a {@code SocketAddress} as its argument which typically
* contains a port number as well as an address. Addresses subquently bound
* using this method are simply addresses as the SCTP port number remains
* the same for the lifetime of the channel.
*
* <P> Adding addresses to a connected association is optional functionality.
* If the endpoint supports dynamic address reconfiguration then it may
* send the appropriate message to the peer to change the peers address
* lists.
*
* @param address
* The address to add to the bound addresses for the socket
*
* @return This channel
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.ConnectionPendingException
* If a non-blocking connection operation is already in progress on
* this channel
*
* @throws java.nio.channels.NotYetBoundException
* If this channel is not yet bound
*
* @throws java.nio.channels.AlreadyBoundException
* If this channel is already bound to the given address
*
* @throws IllegalArgumentException
* If address is {@code null} or the {@link
* java.net.InetAddress#isAnyLocalAddress wildcard} address
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract SctpChannel bindAddress(InetAddress address)
throws IOException;
/**
* Removes the given address from the bound addresses for the channel's
* socket.
*
* <P> The given address must not be the {@link
* java.net.InetAddress#isAnyLocalAddress wildcard} address.
* The channel must be first bound using {@link #bind bind} before
* invoking this method, otherwise {@link java.nio.channels.NotYetBoundException}
* is thrown. If this method is invoked on a channel that does not have
* {@code address} as one of its bound addresses or that has only one
* local address bound to it, then this method throws
* {@link IllegalUnbindException}.
* The initial address that the channel's socket is bound to using {@link
* #bind bind} may be removed from the bound addresses for the channel's socket.
*
* <P> Removing addresses from a connected association is optional
* functionality. If the endpoint supports dynamic address reconfiguration
* then it may send the appropriate message to the peer to change the peers
* address lists.
*
* @param address
* The address to remove from the bound addresses for the socket
*
* @return This channel
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.ConnectionPendingException
* If a non-blocking connection operation is already in progress on
* this channel
*
* @throws java.nio.channels.NotYetBoundException
* If this channel is not yet bound
*
* @throws IllegalArgumentException
* If address is {@code null} or the {@link
* java.net.InetAddress#isAnyLocalAddress wildcard} address
*
* @throws IllegalUnbindException
* If {@code address} is not bound to the channel's socket. or
* the channel has only one address bound to it
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract SctpChannel unbindAddress(InetAddress address)
throws IOException;
/**
* Connects this channel's socket.
*
* <P> If this channel is in non-blocking mode then an invocation of this
* method initiates a non-blocking connection operation. If the connection
* is established immediately, as can happen with a local connection, then
* this method returns {@code true}. Otherwise this method returns
* {@code false} and the connection operation must later be completed by
* invoking the {@link #finishConnect finishConnect} method.
*
* <P> If this channel is in blocking mode then an invocation of this
* method will block until the connection is established or an I/O error
* occurs.
*
* <P> If a security manager has been installed then this method verifies
* that its {@link java.lang.SecurityManager#checkConnect checkConnect}
* method permits connecting to the address and port number of the given
* remote peer.
*
* <p> This method may be invoked at any time. If a {@link #send send} or
* {@link #receive receive} operation upon this channel is invoked while an
* invocation of this method is in progress then that operation will first
* block until this invocation is complete. If a connection attempt is
* initiated but fails, that is, if an invocation of this method throws a
* checked exception, then the channel will be closed.
*
* @param remote
* The remote peer to which this channel is to be connected
*
* @return {@code true} if a connection was established, {@code false} if
* this channel is in non-blocking mode and the connection
* operation is in progress
*
* @throws java.nio.channels.AlreadyConnectedException
* If this channel is already connected
*
* @throws java.nio.channels.ConnectionPendingException
* If a non-blocking connection operation is already in progress on
* this channel
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.AsynchronousCloseException
* If another thread closes this channel
* while the connect operation is in progress
*
* @throws java.nio.channels.ClosedByInterruptException
* If another thread interrupts the current thread
* while the connect operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws java.nio.channels.UnresolvedAddressException
* If the given remote address is not fully resolved
*
* @throws java.nio.channels.UnsupportedAddressTypeException
* If the type of the given remote address is not supported
*
* @throws SecurityException
* If a security manager has been installed
* and it does not permit access to the given remote peer
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract boolean connect(SocketAddress remote) throws IOException;
/**
* Connects this channel's socket.
*
* <P> This is a convience method and is equivalent to evaluating the
* following expression:
* <blockquote><pre>
* setOption(SctpStandardSocketOptions.SCTP_INIT_MAXSTREAMS, SctpStandardSocketOption.InitMaxStreams.create(maxInStreams, maxOutStreams))
* .connect(remote);
* </pre></blockquote>
*
* <P> The {@code maxOutStreams} and {@code maxInStreams} parameters
* represent the maximum number of streams that the application wishes to be
* able to send to and receive from. They are negotiated with the remote
* peer and may be limited by the operating system.
*
* @param remote
* The remote peer to which this channel is to be connected
*
* @param maxOutStreams
* Must be non negative and no larger than {@code 65536}.
* {@code 0} to use the endpoints default value.
*
* @param maxInStreams
* Must be non negative and no larger than {@code 65536}.
* {@code 0} to use the endpoints default value.
*
* @return {@code true} if a connection was established, {@code false} if
* this channel is in non-blocking mode and the connection operation
* is in progress
*
* @throws java.nio.channels.AlreadyConnectedException
* If this channel is already connected
*
* @throws java.nio.channels.ConnectionPendingException
* If a non-blocking connection operation is already in progress on
* this channel
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.AsynchronousCloseException
* If another thread closes this channel
* while the connect operation is in progress
*
* @throws java.nio.channels.ClosedByInterruptException
* If another thread interrupts the current thread
* while the connect operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws java.nio.channels.UnresolvedAddressException
* If the given remote address is not fully resolved
*
* @throws java.nio.channels.UnsupportedAddressTypeException
* If the type of the given remote address is not supported
*
* @throws SecurityException
* If a security manager has been installed
* and it does not permit access to the given remote peer
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract boolean connect(SocketAddress remote,
int maxOutStreams,
int maxInStreams)
throws IOException;
/**
* Tells whether or not a connection operation is in progress on this channel.
*
* @return {@code true} if, and only if, a connection operation has been initiated
* on this channel but not yet completed by invoking the
* {@link #finishConnect} method
*/
public abstract boolean isConnectionPending();
/**
* Finishes the process of connecting an SCTP channel.
*
* <P> A non-blocking connection operation is initiated by placing a socket
* channel in non-blocking mode and then invoking one of its {@link #connect
* connect} methods. Once the connection is established, or the attempt has
* failed, the channel will become connectable and this method may
* be invoked to complete the connection sequence. If the connection
* operation failed then invoking this method will cause an appropriate
* {@link java.io.IOException} to be thrown.
*
* <P> If this channel is already connected then this method will not block
* and will immediately return {@code true}. If this channel is in
* non-blocking mode then this method will return {@code false} if the
* connection process is not yet complete. If this channel is in blocking
* mode then this method will block until the connection either completes
* or fails, and will always either return {@code true} or throw a checked
* exception describing the failure.
*
* <P> This method may be invoked at any time. If a {@link #send send} or {@link #receive receive}
* operation upon this channel is invoked while an invocation of this
* method is in progress then that operation will first block until this
* invocation is complete. If a connection attempt fails, that is, if an
* invocation of this method throws a checked exception, then the channel
* will be closed.
*
* @return {@code true} if, and only if, this channel's socket is now
* connected
*
* @throws java.nio.channels.NoConnectionPendingException
* If this channel is not connected and a connection operation
* has not been initiated
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.AsynchronousCloseException
* If another thread closes this channel
* while the connect operation is in progress
*
* @throws java.nio.channels.ClosedByInterruptException
* If another thread interrupts the current thread
* while the connect operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract boolean finishConnect() throws IOException;
/**
* Returns all of the socket addresses to which this channel's socket is
* bound.
*
* @return All the socket addresses that this channel's socket is
* bound to, or an empty {@code Set} if the channel's socket is not
* bound
*
* @throws ClosedChannelException
* If the channel is closed
*
* @throws IOException
* If an I/O error occurs
*/
public abstract Set<SocketAddress> getAllLocalAddresses()
throws IOException;
/**
* Returns all of the remote addresses to which this channel's socket
* is connected.
*
* <P> If the channel is connected to a remote peer that is bound to
* multiple addresses then it is these addresses that the channel's socket
* is connected.
*
* @return All of the remote addresses to which this channel's socket
* is connected, or an empty {@code Set} if the channel's socket is
* not connected
*
* @throws ClosedChannelException
* If the channel is closed
*
* @throws IOException
* If an I/O error occurs
*/
public abstract Set<SocketAddress> getRemoteAddresses()
throws IOException;
/**
* Shutdown a connection without closing the channel.
*
* <P> Sends a shutdown command to the remote peer, effectively preventing
* any new data from being written to the socket by either peer. Further
* sends will throw {@link java.nio.channels.ClosedChannelException}. The
* channel remains open to allow the for any data (and notifications) to be
* received that may have been sent by the peer before it received the
* shutdown command. If the channel is already shutdown then invoking this
* method has no effect.
*
* @return This channel
*
* @throws java.nio.channels.NotYetConnectedException
* If this channel is not yet connected
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract SctpChannel shutdown() throws IOException;
/**
* Returns the value of a socket option.
*
* @param <T>
* The type of the socket option value
*
* @param name
* The socket option
*
* @return The value of the socket option. A value of {@code null} may be
* a valid value for some socket options.
*
* @throws UnsupportedOperationException
* If the socket option is not supported by this channel
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws IOException
* If an I/O error occurs
*
* @see SctpStandardSocketOptions
*/
public abstract <T> T getOption(SctpSocketOption<T> name)
throws IOException;
/**
* Sets the value of a socket option.
*
* @param <T>
* The type of the socket option value
*
* @param name
* The socket option
*
* @param value
* The value of the socket option. A value of {@code null} may be
* a valid value for some socket options.
*
* @return This channel
*
* @throws UnsupportedOperationException
* If the socket option is not supported by this channel
*
* @throws IllegalArgumentException
* If the value is not a valid value for this socket option
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws IOException
* If an I/O error occurs
*
* @see SctpStandardSocketOptions
*/
public abstract <T> SctpChannel setOption(SctpSocketOption<T> name, T value)
throws IOException;
/**
* Returns a set of the socket options supported by this channel.
*
* <P> This method will continue to return the set of options even after the
* channel has been closed.
*
* @return A set of the socket options supported by this channel
*/
public abstract Set<SctpSocketOption<?>> supportedOptions();
/**
* Returns an operation set identifying this channel's supported operations.
*
* <P> SCTP channels support connecting, reading, and writing, so this
* method returns {@code (}{@link SelectionKey#OP_CONNECT}
* {@code |}&nbsp;{@link SelectionKey#OP_READ} {@code |}&nbsp;{@link
* SelectionKey#OP_WRITE}{@code )}.
*
* @return The valid-operation set
*/
@Override
public final int validOps() {
return (SelectionKey.OP_READ |
SelectionKey.OP_WRITE |
SelectionKey.OP_CONNECT);
}
/**
* Receives a message into the given buffer and/or handles a notification.
*
* <P> If a message or notification is immediately available, or if this
* channel is in blocking mode and one eventually becomes available, then
* the message or notification is returned or handled, respectively. If this
* channel is in non-blocking mode and a message or notification is not
* immediately available then this method immediately returns {@code null}.
*
* <P> If this method receives a message it is copied into the given byte
* buffer. The message is transferred into the given byte buffer starting at
* its current position and the buffers position is incremented by the
* number of bytes read. If there are fewer bytes remaining in the buffer
* than are required to hold the message, or the underlying input buffer
* does not contain the complete message, then an invocation of {@link
* MessageInfo#isComplete isComplete} on the returned {@code
* MessageInfo} will return {@code false}, and more invocations of this
* method will be necessary to completely consume the messgae. Only
* one message at a time will be partially delivered in any stream. The
* socket option {@link SctpStandardSocketOptions#SCTP_FRAGMENT_INTERLEAVE
* SCTP_FRAGMENT_INTERLEAVE} controls various aspects of what interlacing of
* messages occurs.
*
* <P> If this method receives a notification then the appropriate method of
* the given handler, if there is one, is invoked. If the handler returns
* {@link HandlerResult#CONTINUE CONTINUE} then this method will try to
* receive another message/notification, otherwise, if {@link
* HandlerResult#RETURN RETURN} is returned this method will return {@code
* null}. If an uncaught exception is thrown by the handler it will be
* propagated up the stack through this method.
*
* <P> This method may be invoked at any time. If another thread has
* already initiated a receive operation upon this channel, then an
* invocation of this method will block until the first operation is
* complete. The given handler is invoked without holding any locks used
* to enforce the above synchronization policy, that way handlers
* will not stall other threads from receiving. A handler should not invoke
* the {@code receive} method of this channel, if it does an
* {@link IllegalReceiveException} will be thrown.
*
* @param <T>
* The type of the attachment
*
* @param dst
* The buffer into which message bytes are to be transferred
*
* @param attachment
* The object to attach to the receive operation; can be
* {@code null}
*
* @param handler
* A handler to handle notifications from the SCTP stack, or {@code
* null} to ignore any notifications.
*
* @return The {@code MessageInfo}, {@code null} if this channel is in
* non-blocking mode and no messages are immediately available or
* the notification handler returns {@link HandlerResult#RETURN
* RETURN} after handling a notification
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.AsynchronousCloseException
* If another thread closes this channel
* while the read operation is in progress
*
* @throws java.nio.channels.ClosedByInterruptException
* If another thread interrupts the current thread
* while the read operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws java.nio.channels.NotYetConnectedException
* If this channel is not yet connected
*
* @throws IllegalReceiveException
* If the given handler invokes the {@code receive} method of this
* channel
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract <T> MessageInfo receive(ByteBuffer dst,
T attachment,
NotificationHandler<T> handler)
throws IOException;
/**
* Sends a message via this channel.
*
* <P> If this channel is in non-blocking mode and there is sufficient room
* in the underlying output buffer, or if this channel is in blocking mode
* and sufficient room becomes available, then the remaining bytes in the
* given byte buffer are transmitted as a single message. Sending a message
* is atomic unless explicit message completion {@link
* SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE SCTP_EXPLICIT_COMPLETE}
* socket option is enabled on this channel's socket.
*
* <P> The message is transferred from the byte buffer as if by a regular
* {@link java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer)
* write} operation.
*
* <P> The bytes will be written to the stream number that is specified by
* {@link MessageInfo#streamNumber streamNumber} in the given {@code
* messageInfo}.
*
* <P> This method may be invoked at any time. If another thread has already
* initiated a send operation upon this channel, then an invocation of
* this method will block until the first operation is complete.
*
* @param src
* The buffer containing the message to be sent
*
* @param messageInfo
* Ancillary data about the message to be sent
*
* @return The number of bytes sent, which will be either the number of
* bytes that were remaining in the messages buffer when this method
* was invoked or, if this channel is non-blocking, may be zero if
* there was insufficient room for the message in the underlying
* output buffer
*
* @throws InvalidStreamException
* If {@code streamNumner} is negative or greater than or equal to
* the maximum number of outgoing streams
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.AsynchronousCloseException
* If another thread closes this channel
* while the read operation is in progress
*
* @throws java.nio.channels.ClosedByInterruptException
* If another thread interrupts the current thread
* while the read operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws java.nio.channels.NotYetConnectedException
* If this channel is not yet connected
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract int send(ByteBuffer src, MessageInfo messageInfo)
throws IOException;
}

View file

@ -0,0 +1,748 @@
/*
* Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.nio.sctp;
import java.net.SocketAddress;
import java.net.InetAddress;
import java.io.IOException;
import java.util.Set;
import java.nio.ByteBuffer;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.NotYetBoundException;
import java.nio.channels.SelectionKey;
/**
* A selectable channel for message-oriented SCTP sockets.
*
* <P> An SCTP multi channel supports many associations on a single socket.
* An {@code SctpMultiChannel} is created by invoking the
* {@link #open open} method of this class. A newly-created channel is open but
* not yet bound. An attempt to invoke the {@link #receive receive} method of an
* unbound channel will cause the {@link NotYetBoundException}
* to be thrown. An attempt to invoke the {@link #send send} method of an
* unbound channel will cause it to first invoke the {@link #bind bind} method.
* The address(es) that the channel's socket is bound to can be retrieved by
* calling {@link #getAllLocalAddresses getAllLocalAddresses}.
*
* <P> Messages may be sent and received without explicitly setting up an
* association with the remote peer. The channel will implicitly setup
* a new association whenever it sends or receives a message from a remote
* peer if there is not already an association with that peer. Upon successful
* association setup, an {@link AssociationChangeNotification
* association changed} notification will be put to the SCTP stack with its
* {@code event} parameter set to {@link
* AssociationChangeNotification.AssocChangeEvent#COMM_UP
* COMM_UP}. This notification can be received by invoking {@link #receive
* receive}.
*
* <P> Socket options are configured using the
* {@link #setOption(SctpSocketOption,Object,Association) setOption} method. An
* {@code SctpMultiChannel} supports the following options:
* <blockquote>
* <table class="striped">
* <caption style="display:none">Socket options</caption>
* <thead>
* <tr>
* <th scope="col">Option Name</th>
* <th scope="col">Description</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SCTP_DISABLE_FRAGMENTS
* SCTP_DISABLE_FRAGMENTS} </th>
* <td> Enables or disables message fragmentation </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE
* SCTP_EXPLICIT_COMPLETE} </th>
* <td> Enables or disables explicit message completion </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SCTP_FRAGMENT_INTERLEAVE
* SCTP_FRAGMENT_INTERLEAVE} </th>
* <td> Controls how the presentation of messages occur for the message
* receiver </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SCTP_INIT_MAXSTREAMS
* SCTP_INIT_MAXSTREAMS} </th>
* <td> The maximum number of streams requested by the local endpoint during
* association initialization </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SCTP_NODELAY SCTP_NODELAY} </th>
* <td> Enables or disable a Nagle-like algorithm </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SCTP_PRIMARY_ADDR
* SCTP_PRIMARY_ADDR} </th>
* <td> Requests that the local SCTP stack use the given peer address as the
* association primary </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SCTP_SET_PEER_PRIMARY_ADDR
* SCTP_SET_PEER_PRIMARY_ADDR} </th>
* <td> Requests that the peer mark the enclosed address as the association
* primary </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SO_SNDBUF
* SO_SNDBUF} </th>
* <td> The size of the socket send buffer </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SO_RCVBUF
* SO_RCVBUF} </th>
* <td> The size of the socket receive buffer </td>
* </tr>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SO_LINGER
* SO_LINGER} </th>
* <td> Linger on close if data is present (when configured in blocking mode
* only) </td>
* </tr>
* </tbody>
* </table>
* </blockquote>
* Additional (implementation specific) options may also be supported. The list
* of options supported is obtained by invoking the {@link #supportedOptions()
* supportedOptions} method.
*
* <p> SCTP multi channels are safe for use by multiple concurrent threads.
* They support concurrent sending and receiving, though at most one thread may be
* sending and at most one thread may be receiving at any given time.
*
* @since 1.7
*/
public abstract class SctpMultiChannel
extends AbstractSelectableChannel
{
/**
* Initializes a new instance of this class.
*
* @param provider
* The selector provider for this channel
*/
protected SctpMultiChannel(SelectorProvider provider) {
super(provider);
}
/**
* Opens an SCTP multi channel.
*
* <P> The new channel is unbound.
*
* @return A new SCTP multi channel
*
* @throws UnsupportedOperationException
* If the SCTP protocol is not supported
*
* @throws IOException
* If an I/O error occurs
*/
public static SctpMultiChannel open() throws
IOException {
return new sun.nio.ch.sctp.SctpMultiChannelImpl((SelectorProvider)null);
}
/**
* Returns the open associations on this channel's socket.
*
* <P> Only associations whose {@link AssociationChangeNotification.AssocChangeEvent#COMM_UP
* COMM_UP} association change event has been received are included
* in the returned set of associations. Associations for which a
* {@link AssociationChangeNotification.AssocChangeEvent#COMM_LOST COMM_LOST} or {@link
* AssociationChangeNotification.AssocChangeEvent#SHUTDOWN SHUTDOWN} association change
* event have been receive are removed from the set of associations.
*
* <P> The returned set of associations is a snapshot of the open
* associations at the time that this method is invoked.
*
* @return A {@code Set} containing the open associations, or an empty
* {@code Set} if there are none.
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract Set<Association> associations()
throws IOException;
/**
* Binds the channel's socket to a local address and configures the socket
* to listen for connections.
*
* <P> This method is used to establish a relationship between the socket
* and the local address. Once a relationship is established then
* the socket remains bound until the channel is closed. This relationship
* may not necesssarily be with the address {@code local} as it may be removed
* by {@link #unbindAddress unbindAddress}, but there will always be at least one local
* address bound to the channel's socket once an invocation of this method
* successfully completes.
*
* <P> Once the channel's socket has been successfully bound to a specific
* address, that is not automatically assigned, more addresses
* may be bound to it using {@link #bindAddress bindAddress}, or removed
* using {@link #unbindAddress unbindAddress}.
*
* <P> The backlog parameter is the maximum number of pending connections on
* the socket. Its exact semantics are implementation specific. An implementation
* may impose an implementation specific maximum length or may choose to ignore
* the parameter. If the backlog parameter has the value {@code 0}, or a negative
* value, then an implementation specific default is used.
*
* @param local
* The local address to bind the socket, or {@code null} to
* bind the socket to an automatically assigned socket address
*
* @param backlog
* The maximum number of pending connections
*
* @return This channel
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.AlreadyBoundException
* If this channel is already bound
*
* @throws java.nio.channels.UnsupportedAddressTypeException
* If the type of the given address is not supported
*
* @throws SecurityException
* If a security manager has been installed and its {@link
* java.lang.SecurityManager#checkListen(int) checkListen} method
* denies the operation
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract SctpMultiChannel bind(SocketAddress local,
int backlog)
throws IOException;
/**
* Binds the channel's socket to a local address and configures the socket
* to listen for connections.
*
* <P> This method works as if invoking it were equivalent to evaluating the
* expression:
* <blockquote><pre>
* bind(local, 0);
* </pre></blockquote>
*
* @param local
* The local address to bind the socket, or {@code null} to
* bind the socket to an automatically assigned socket address
*
* @return This channel
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.AlreadyBoundException
* If this channel is already bound
*
* @throws java.nio.channels.UnsupportedAddressTypeException
* If the type of the given address is not supported
*
* @throws SecurityException
* If a security manager has been installed and its {@link
* java.lang.SecurityManager#checkListen(int) checkListen} method
* denies the operation
*
* @throws IOException
* If some other I/O error occurs
*/
public final SctpMultiChannel bind(SocketAddress local)
throws IOException {
return bind(local, 0);
}
/**
* Adds the given address to the bound addresses for the channel's
* socket.
*
* <P> The given address must not be the {@link
* java.net.InetAddress#isAnyLocalAddress wildcard} address.
* The channel must be first bound using {@link #bind bind} before
* invoking this method, otherwise {@link NotYetBoundException} is thrown.
* The {@link #bind bind} method takes a {@code SocketAddress} as its
* argument which typically contains a port number as well as an address.
* Addresses subquently bound using this method are simply addresses as the
* SCTP port number remains the same for the lifetime of the channel.
*
* <P> New associations setup after this method successfully completes
* will be associated with the given address. Adding addresses to existing
* associations is optional functionality. If the endpoint supports
* dynamic address reconfiguration then it may send the appropriate message
* to the peer to change the peers address lists.
*
* @param address
* The address to add to the bound addresses for the socket
*
* @return This channel
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws NotYetBoundException
* If this channel is not yet bound
*
* @throws java.nio.channels.AlreadyBoundException
* If this channel is already bound to the given address
*
* @throws IllegalArgumentException
* If address is {@code null} or the {@link
* java.net.InetAddress#isAnyLocalAddress wildcard} address
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract SctpMultiChannel bindAddress(InetAddress address)
throws IOException;
/**
* Removes the given address from the bound addresses for the channel's
* socket.
*
* <P> The given address must not be the {@link
* java.net.InetAddress#isAnyLocalAddress wildcard} address.
* The channel must be first bound using {@link #bind bind} before
* invoking this method, otherwise {@link NotYetBoundException} is thrown.
*
* <P> If this method is invoked on a channel that does
* not have {@code address} as one of its bound addresses, or that has only
* one local address bound to it, then this method throws
* {@link IllegalUnbindException}.
*
* <P> The initial address that the channel's socket is bound to using
* {@link #bind bind} may be removed from the bound addresses for the
* channel's socket.
*
* <P> New associations setup after this method successfully completes
* will not be associated with the given address. Removing addresses from
* existing associations is optional functionality. If the endpoint supports
* dynamic address reconfiguration then it may send the appropriate message
* to the peer to change the peers address lists.
*
* @param address
* The address to remove from the bound addresses for the socket
*
* @return This channel
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws NotYetBoundException
* If this channel is not yet bound
*
* @throws IllegalUnbindException
* {@code address} is not bound to the channel's socket, or the
* channel has only one address bound to it
*
* @throws IllegalArgumentException
* If address is {@code null} or the {@link
* java.net.InetAddress#isAnyLocalAddress wildcard} address
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract SctpMultiChannel unbindAddress(InetAddress address)
throws IOException;
/**
* Returns all of the socket addresses to which this channel's socket is
* bound.
*
* @return All the socket addresses that this channel's socket is
* bound to, or an empty {@code Set} if the channel's socket is not
* bound
*
* @throws ClosedChannelException
* If the channel is closed
*
* @throws IOException
* If an I/O error occurs
*/
public abstract Set<SocketAddress> getAllLocalAddresses()
throws IOException;
/**
* Returns all of the remote addresses to which the given association on
* this channel's socket is connected.
*
* @param association
* The association
*
* @return All of the remote addresses for the given association, or
* an empty {@code Set} if the association has been shutdown
*
* @throws ClosedChannelException
* If the channel is closed
*
* @throws IOException
* If an I/O error occurs
*/
public abstract Set<SocketAddress> getRemoteAddresses(Association association)
throws IOException;
/**
* Shutdown an association without closing the channel.
*
* @param association
* The association to shutdown
*
* @return This channel
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract SctpMultiChannel shutdown(Association association)
throws IOException;
/**
* Returns the value of a socket option.
*
* <P> Note that some options are retrieved on the channel's socket,
* therefore the {@code association} parameter is not applicable and will be
* ignored if given. However, if the option is association specific then the
* association must be given.
*
* @param <T>
* The type of the socket option value
*
* @param name
* The socket option
*
* @param association
* The association whose option should be retrieved, or {@code null}
* if this option should be retrieved at the channel's socket level.
*
* @return The value of the socket option. A value of {@code null} may be
* a valid value for some socket options.
*
* @throws UnsupportedOperationException
* If the socket option is not supported by this channel
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws IOException
* If an I/O error occurs
*
* @see SctpStandardSocketOptions
*/
public abstract <T> T getOption(SctpSocketOption<T> name,
Association association)
throws IOException;
/**
* Sets the value of a socket option.
*
* <P> Note that some options are retrieved on the channel's socket,
* therefore the {@code association} parameter is not applicable and will be
* ignored if given. However, if the option is association specific then the
* association must be given.
*
* @param <T>
* The type of the socket option value
*
* @param name
* The socket option
*
* @param association
* The association whose option should be set, or {@code null}
* if this option should be set at the channel's socket level.
*
* @param value
* The value of the socket option. A value of {@code null} may be
* a valid value for some socket options.
*
* @return This channel
*
* @throws UnsupportedOperationException
* If the socket option is not supported by this channel
*
* @throws IllegalArgumentException
* If the value is not a valid value for this socket option
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws IOException
* If an I/O error occurs
*
* @see SctpStandardSocketOptions
*/
public abstract <T> SctpMultiChannel setOption(SctpSocketOption<T> name,
T value,
Association association)
throws IOException;
/**
* Returns a set of the socket options supported by this channel.
*
* <P> This method will continue to return the set of options even after the
* channel has been closed.
*
* @return A set of the socket options supported by this channel
*/
public abstract Set<SctpSocketOption<?>> supportedOptions();
/**
* Returns an operation set identifying this channel's supported operations.
*
* <P> SCTP multi channels support reading, and writing, so this
* method returns
* {@code (}{@link SelectionKey#OP_READ} {@code |}&nbsp;{@link
* SelectionKey#OP_WRITE}{@code )}. </p>
*
* @return The valid-operation set
*/
@Override
public final int validOps() {
return (SelectionKey.OP_READ |
SelectionKey.OP_WRITE );
}
/**
* Receives a message and/or handles a notification via this channel.
*
* <P> If a message or notification is immediately available, or if this
* channel is in blocking mode and one eventually becomes available, then
* the message or notification is returned or handled, respectively. If this
* channel is in non-blocking mode and a message or notification is not
* immediately available then this method immediately returns {@code null}.
*
* <P> If this method receives a message it is copied into the given byte
* buffer and an {@link MessageInfo} is returned.
* The message is transferred into the given byte buffer starting at its
* current position and the buffers position is incremented by the number of
* bytes read. If there are fewer bytes remaining in the buffer than are
* required to hold the message, or the underlying input buffer does not
* contain the complete message, then an invocation of {@link
* MessageInfo#isComplete isComplete} on the returned {@code
* MessageInfo} will return {@code false}, and more invocations of this
* method will be necessary to completely consume the messgae. Only
* one message at a time will be partially delivered in any stream. The
* socket option {@link SctpStandardSocketOptions#SCTP_FRAGMENT_INTERLEAVE
* SCTP_FRAGMENT_INTERLEAVE} controls various aspects of what interlacing of
* messages occurs.
*
* <P> If this method receives a notification then the appropriate method of
* the given handler, if there is one, is invoked. If the handler returns {@link
* HandlerResult#CONTINUE CONTINUE} then this method will try to receive another
* message/notification, otherwise, if {@link HandlerResult#RETURN RETURN} is returned
* this method will return {@code null}. If an uncaught exception is thrown by the
* handler it will be propagated up the stack through this method.
*
* <P> If a security manager has been installed then for each new association
* setup this method verifies that the associations source address and port
* number are permitted by the security manager's {@link
* java.lang.SecurityManager#checkAccept(String,int) checkAccept} method.
*
* <P> This method may be invoked at any time. If another thread has
* already initiated a receive operation upon this channel, then an
* invocation of this method will block until the first operation is
* complete. The given handler is invoked without holding any locks used
* to enforce the above synchronization policy, that way handlers
* will not stall other threads from receiving. A handler should not invoke
* the {@code receive} method of this channel, if it does an
* {@link IllegalReceiveException} will be thrown.
*
* @param <T>
* The type of the attachment
*
* @param buffer
* The buffer into which bytes are to be transferred
*
* @param attachment
* The object to attach to the receive operation; can be
* {@code null}
*
* @param handler
* A handler to handle notifications from the SCTP stack, or
* {@code null} to ignore any notifications.
*
* @return The {@code MessageInfo}, {@code null} if this channel is in
* non-blocking mode and no messages are immediately available or
* the notification handler returns {@code RETURN} after handling
* a notification
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.AsynchronousCloseException
* If another thread closes this channel
* while the read operation is in progress
*
* @throws java.nio.channels.ClosedByInterruptException
* If another thread interrupts the current thread
* while the read operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws NotYetBoundException
* If this channel is not yet bound
*
* @throws IllegalReceiveException
* If the given handler invokes the {@code receive} method of this
* channel
*
* @throws SecurityException
* If a security manager has been installed and it does not permit
* new associations to be accepted from the message's sender
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract <T> MessageInfo receive(ByteBuffer buffer,
T attachment,
NotificationHandler<T> handler)
throws IOException;
/**
* Sends a message via this channel.
*
* <P> If this channel is unbound then this method will invoke {@link
* #bind(SocketAddress, int) bind(null, 0)} before sending any data.
*
* <P> If there is no association existing between this channel's socket
* and the intended receiver, identified by the address in the given messageInfo, then one
* will be automatically setup to the intended receiver. This is considered
* to be Implicit Association Setup. Upon successful association setup, an
* {@link AssociationChangeNotification association changed}
* notification will be put to the SCTP stack with its {@code event} parameter set
* to {@link AssociationChangeNotification.AssocChangeEvent#COMM_UP COMM_UP}
* . This notification can be received by invoking {@link #receive
* receive}.
*
* <P> If this channel is in blocking mode, there is sufficient room in the
* underlying output buffer, then the remaining bytes in the given byte
* buffer are transmitted as a single message. Sending a message
* is atomic unless explicit message completion {@link
* SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE SCTP_EXPLICIT_COMPLETE}
* socket option is enabled on this channel's socket.
*
* <P> If this channel is in non-blocking mode, there is sufficient room
* in the underlying output buffer, and an implicit association setup is
* required, then the remaining bytes in the given byte buffer are
* transmitted as a single message, subject to {@link
* SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE SCTP_EXPLICIT_COMPLETE}.
* If for any reason the message cannot
* be delivered an {@link AssociationChangeNotification association
* changed} notification is put on the SCTP stack with its {@code event} parameter set
* to {@link AssociationChangeNotification.AssocChangeEvent#CANT_START CANT_START}.
*
* <P> The message is transferred from the byte buffer as if by a regular
* {@link java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer)
* write} operation.
*
* <P> If a security manager has been installed then for each new association
* setup this method verifies that the given remote peers address and port
* number are permitted by the security manager's {@link
* java.lang.SecurityManager#checkConnect(String,int) checkConnect} method.
*
* <P> This method may be invoked at any time. If another thread has already
* initiated a send operation upon this channel, then an invocation of
* this method will block until the first operation is complete.
*
* @param buffer
* The buffer containing the message to be sent
*
* @param messageInfo
* Ancillary data about the message to be sent
*
* @return The number of bytes sent, which will be either the number of
* bytes that were remaining in the messages buffer when this method
* was invoked or, if this channel is non-blocking, may be zero if
* there was insufficient room for the message in the underlying
* output buffer
*
* @throws InvalidStreamException
* If {@code streamNumber} is negative, or if an association already
* exists and {@code streamNumber} is greater than the maximum number
* of outgoing streams
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.AsynchronousCloseException
* If another thread closes this channel
* while the read operation is in progress
*
* @throws java.nio.channels.ClosedByInterruptException
* If another thread interrupts the current thread
* while the read operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws SecurityException
* If a security manager has been installed and it does not permit
* new associations to be setup with the messages's address
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract int send(ByteBuffer buffer, MessageInfo messageInfo)
throws IOException;
/**
* Branches off an association.
*
* <P> An application can invoke this method to branch off an association
* into a separate channel. The new bound and connected {@link SctpChannel}
* will be created for the association. The branched off association will no
* longer be part of this channel.
*
* <P> This is particularly useful when, for instance, the application
* wishes to have a number of sporadic message senders/receivers remain
* under the original SCTP multi channel but branch off those
* associations carrying high volume data traffic into their own
* separate SCTP channels.
*
* @param association
* The association to branch off
*
* @return The {@code SctpChannel}
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract SctpChannel branch(Association association)
throws IOException;
}

View file

@ -0,0 +1,432 @@
/*
* Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.nio.sctp;
import java.net.SocketAddress;
import java.net.InetAddress;
import java.io.IOException;
import java.util.Set;
import java.nio.channels.SelectionKey;
import java.nio.channels.spi.SelectorProvider;
import java.nio.channels.spi.AbstractSelectableChannel;
/**
* A selectable channel for message-oriented listening SCTP sockets.
*
* <p> An {@code SCTPServerChannel} is created by invoking the
* {@link #open open} method of this class. A newly-created SCTP server
* channel is open but not yet bound. An attempt to invoke the
* {@link #accept accept} method of an unbound channel will cause the
* {@link java.nio.channels.NotYetBoundException} to be thrown. An SCTP server
* channel can be bound by invoking one of the
* {@link #bind(java.net.SocketAddress,int) bind} methods defined by this class.
*
* <p> Socket options are configured using the
* {@link #setOption(SctpSocketOption,Object) setOption} method. SCTP server socket
* channels support the following options:
* <blockquote>
* <table class="striped">
* <caption style="display:none">Socket options</caption>
* <thead>
* <tr>
* <th scope="col">Option Name</th>
* <th scope="col">Description</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <th scope="row"> {@link SctpStandardSocketOptions#SCTP_INIT_MAXSTREAMS
* SCTP_INIT_MAXSTREAMS} </th>
* <td> The maximum number of streams requested by the local endpoint during
* association initialization </td>
* </tr>
* </tbody>
* </table>
* </blockquote>
* Additional (implementation specific) options may also be supported. The list
* of options supported is obtained by invoking the {@link #supportedOptions()
* supportedOptions} method.
*
* <p>SCTP server channels are safe for use by multiple concurrent threads.
*
* @since 1.7
*/
public abstract class SctpServerChannel
extends AbstractSelectableChannel
{
/**
* Initializes a new instance of this class.
*
* @param provider
* The selector provider for this channel
*/
protected SctpServerChannel(SelectorProvider provider) {
super(provider);
}
/**
* Opens an SCTP server channel.
*
* <P> The new channel's socket is initially unbound; it must be bound
* to a specific address via one of its socket's {@link #bind bind}
* methods before associations can be accepted.
*
* @return A new SCTP server channel
*
* @throws UnsupportedOperationException
* If the SCTP protocol is not supported
*
* @throws IOException
* If an I/O error occurs
*/
public static SctpServerChannel open() throws
IOException {
return new sun.nio.ch.sctp.SctpServerChannelImpl((SelectorProvider)null);
}
/**
* Accepts an association on this channel's socket.
*
* <P> If this channel is in non-blocking mode then this method will
* immediately return {@code null} if there are no pending associations.
* Otherwise it will block indefinitely until a new association is
* available or an I/O error occurs.
*
* <P> The {@code SCTPChannel} returned by this method, if any, will be in
* blocking mode regardless of the blocking mode of this channel.
*
* <P> If a security manager has been installed then for each new
* association this method verifies that the address and port number of the
* assocaitions's remote peer are permitted by the security manager's {@link
* java.lang.SecurityManager#checkAccept(String,int) checkAccept} method.
*
* @return The SCTP channel for the new association, or {@code null}
* if this channel is in non-blocking mode and no association is
* available to be accepted
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.AsynchronousCloseException
* If another thread closes this channel
* while the accept operation is in progress
*
* @throws java.nio.channels.ClosedByInterruptException
* If another thread interrupts the current thread
* while the accept operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws java.nio.channels.NotYetBoundException
* If this channel's socket has not yet been bound
*
* @throws SecurityException
* If a security manager has been installed and it does not permit
* access to the remote peer of the new association
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract SctpChannel accept() throws IOException;
/**
* Binds the channel's socket to a local address and configures the socket
* to listen for associations.
*
* <P> This method works as if invoking it were equivalent to evaluating the
* expression:
* <blockquote><pre>
* bind(local, 0);
* </pre></blockquote>
*
* @param local
* The local address to bind the socket, or {@code null} to
* bind the socket to an automatically assigned socket address
*
* @return This channel
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.AlreadyBoundException
* If this channel is already bound
*
* @throws java.nio.channels.UnsupportedAddressTypeException
* If the type of the given address is not supported
*
* @throws SecurityException
* If a security manager has been installed and its {@link
* java.lang.SecurityManager#checkListen(int) checkListen} method
* denies the operation
*
* @throws IOException
* If some other I/O error occurs
*/
public final SctpServerChannel bind(SocketAddress local)
throws IOException {
return bind(local, 0);
}
/**
* Binds the channel's socket to a local address and configures the socket
* to listen for associations.
*
* <P> This method is used to establish a relationship between the socket
* and the local address. Once a relationship is established then
* the socket remains bound until the channel is closed. This relationship
* may not necesssarily be with the address {@code local} as it may be
* removed by {@link #unbindAddress unbindAddress}, but there will always be
* at least one local address bound to the channel's socket once an
* invocation of this method successfully completes.
*
* <P> Once the channel's socket has been successfully bound to a specific
* address, that is not automatically assigned, more addresses
* may be bound to it using {@link #bindAddress bindAddress}, or removed
* using {@link #unbindAddress unbindAddress}.
*
* <P> The backlog parameter is the maximum number of pending associations
* on the socket. Its exact semantics are implementation specific. An
* implementation may impose an implementation specific maximum length or
* may choose to ignore the parameter. If the backlog parameter has the
* value {@code 0}, or a negative value, then an implementation specific
* default is used.
*
* @param local
* The local address to bind the socket, or {@code null} to
* bind the socket to an automatically assigned socket address
*
* @param backlog
* The maximum number of pending associations
*
* @return This channel
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.AlreadyBoundException
* If this channel is already bound
*
* @throws java.nio.channels.UnsupportedAddressTypeException
* If the type of the given address is not supported
*
* @throws SecurityException
* If a security manager has been installed and its {@link
* java.lang.SecurityManager#checkListen(int) checkListen} method
* denies the operation
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract SctpServerChannel bind(SocketAddress local,
int backlog)
throws IOException;
/**
* Adds the given address to the bound addresses for the channel's
* socket.
*
* <P> The given address must not be the {@link
* java.net.InetAddress#isAnyLocalAddress wildcard} address.
* The channel must be first bound using {@link #bind bind} before
* invoking this method, otherwise {@link
* java.nio.channels.NotYetBoundException} is thrown. The {@link #bind bind}
* method takes a {@code SocketAddress} as its argument which typically
* contains a port number as well as an address. Addresses subquently bound
* using this method are simply addresses as the SCTP port number remains
* the same for the lifetime of the channel.
*
* <P> New associations accepted after this method successfully completes
* will be associated with the given address.
*
* @param address
* The address to add to the bound addresses for the socket
*
* @return This channel
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.NotYetBoundException
* If this channel is not yet bound
*
* @throws java.nio.channels.AlreadyBoundException
* If this channel is already bound to the given address
*
* @throws IllegalArgumentException
* If address is {@code null} or the {@link
* java.net.InetAddress#isAnyLocalAddress wildcard} address
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract SctpServerChannel bindAddress(InetAddress address)
throws IOException;
/**
* Removes the given address from the bound addresses for the channel's
* socket.
*
* <P> The given address must not be the {@link
* java.net.InetAddress#isAnyLocalAddress wildcard} address.
* The channel must be first bound using {@link #bind bind} before
* invoking this method, otherwise
* {@link java.nio.channels.NotYetBoundException} is thrown.
* If this method is invoked on a channel that does not have
* {@code address} as one of its bound addresses, or that has only one
* local address bound to it, then this method throws {@link
* IllegalUnbindException}.
* The initial address that the channel's socket is bound to using
* {@link #bind bind} may be removed from the bound addresses for the
* channel's socket.
*
* <P> New associations accepted after this method successfully completes
* will not be associated with the given address.
*
* @param address
* The address to remove from the bound addresses for the socket
*
* @return This channel
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws java.nio.channels.NotYetBoundException
* If this channel is not yet bound
*
* @throws IllegalArgumentException
* If address is {@code null} or the {@link
* java.net.InetAddress#isAnyLocalAddress wildcard} address
*
* @throws IllegalUnbindException
* If the implementation does not support removing addresses from a
* listening socket, {@code address} is not bound to the channel's
* socket, or the channel has only one address bound to it
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract SctpServerChannel unbindAddress(InetAddress address)
throws IOException;
/**
* Returns all of the socket addresses to which this channel's socket is
* bound.
*
* @return All the socket addresses that this channel's socket is
* bound to, or an empty {@code Set} if the channel's socket is not
* bound
*
* @throws java.nio.channels.ClosedChannelException
* If the channel is closed
*
* @throws IOException
* If an I/O error occurs
*/
public abstract Set<SocketAddress> getAllLocalAddresses()
throws IOException;
/**
* Returns the value of a socket option.
*
* @param <T>
* The type of the socket option value
*
* @param name
* The socket option
*
* @return The value of the socket option. A value of {@code null} may be
* a valid value for some socket options.
*
* @throws UnsupportedOperationException
* If the socket option is not supported by this channel
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws IOException
* If an I/O error occurs
*
* @see SctpStandardSocketOptions
*/
public abstract <T> T getOption(SctpSocketOption<T> name) throws IOException;
/**
* Sets the value of a socket option.
*
* @param <T>
* The type of the socket option value
*
* @param name
* The socket option
*
* @param value
* The value of the socket option. A value of {@code null} may be
* a valid value for some socket options.
*
* @return This channel
*
* @throws UnsupportedOperationException
* If the socket option is not supported by this channel
*
* @throws IllegalArgumentException
* If the value is not a valid value for this socket option
*
* @throws java.nio.channels.ClosedChannelException
* If this channel is closed
*
* @throws IOException
* If an I/O error occurs
*
* @see SctpStandardSocketOptions
*/
public abstract <T> SctpServerChannel setOption(SctpSocketOption<T> name,
T value)
throws IOException;
/**
* Returns a set of the socket options supported by this channel.
*
* <P> This method will continue to return the set of options even after the
* channel has been closed.
*
* @return A set of the socket options supported by this channel
*/
public abstract Set<SctpSocketOption<?>> supportedOptions();
/**
* Returns an operation set identifying this channel's supported
* operations.
*
* <P> SCTP server channels only support the accepting of new
* associations, so this method returns
* {@link java.nio.channels.SelectionKey#OP_ACCEPT}.
*
* @return The valid-operation set
*/
@Override
public final int validOps() {
return SelectionKey.OP_ACCEPT;
}
}

View file

@ -0,0 +1,38 @@
/*
* 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 com.sun.nio.sctp;
import java.net.SocketOption;
/**
* A socket option associated with an SCTP channel.
*
* @param <T> The type of the socket option value.
*
* @since 1.7
*
* @see SctpStandardSocketOptions
*/
public interface SctpSocketOption<T> extends SocketOption<T> { }

View file

@ -0,0 +1,419 @@
/*
* 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 com.sun.nio.sctp;
import java.net.SocketAddress;
import sun.nio.ch.sctp.SctpStdSocketOption;
/**
* SCTP channels supports the socket options defined by this class
* (as well as those listed in the particular channel class) and may support
* additional Implementation specific socket options.
*
* @since 1.7
*/
public class SctpStandardSocketOptions {
private SctpStandardSocketOptions() {}
/**
* Enables or disables message fragmentation.
*
* <P> The value of this socket option is a {@code Boolean} that represents
* whether the option is enabled or disabled. If enabled no SCTP message
* fragmentation will be performed. Instead if a message being sent
* exceeds the current PMTU size, the message will NOT be sent and
* an error will be indicated to the user.
*
* <P> It is implementation specific whether or not this option is
* supported.
*/
public static final SctpSocketOption<Boolean> SCTP_DISABLE_FRAGMENTS = new
SctpStdSocketOption<Boolean>("SCTP_DISABLE_FRAGMENTS", Boolean.class,
sun.nio.ch.sctp.SctpStdSocketOption.SCTP_DISABLE_FRAGMENTS);
/**
* Enables or disables explicit message completion.
*
* <p> The value of this socket option is a {@code Boolean} that represents
* whether the option is enabled or disabled. When this option is enabled,
* the {@code send} method may be invoked multiple times to a send message.
* The {@code isComplete} parameter of the {@link MessageInfo} must only
* be set to {@code true} for the final send to indicate that the message is
* complete. If this option is disabled then each individual {@code send}
* invocation is considered complete.
*
* <P> The default value of the option is {@code false} indicating that the
* option is disabled. It is implementation specific whether or not this
* option is supported.
*/
public static final SctpSocketOption<Boolean> SCTP_EXPLICIT_COMPLETE = new
SctpStdSocketOption<Boolean>("SCTP_EXPLICIT_COMPLETE", Boolean.class,
sun.nio.ch.sctp.SctpStdSocketOption.SCTP_EXPLICIT_COMPLETE);
/**
* Fragmented interleave controls how the presentation of messages occur
* for the message receiver. There are three levels of fragment interleave
* defined. Two of the levels effect {@link SctpChannel}, while
* {@link SctpMultiChannel} is effected by all three levels.
*
* <P> This option takes an {@code Integer} value. It can be set to a value
* of {@code 0}, {@code 1} or {@code 2}.
*
* <P> Setting the three levels provides the following receiver
* interactions:
*
* <P> {@code level 0} - Prevents the interleaving of any messages. This
* means that when a partial delivery begins, no other messages will be
* received except the message being partially delivered. If another message
* arrives on a different stream (or association) that could be delivered,
* it will be blocked waiting for the user to read all of the partially
* delivered message.
*
* <P> {@code level 1} - Allows interleaving of messages that are from
* different associations. For {@code SctpChannel}, level 0 and
* level 1 have the same meaning since an {@code SctpChannel} always
* receives messages from the same association. Note that setting an {@code
* SctpMultiChannel} to this level may cause multiple partial
* delivers from different associations but for any given association, only
* one message will be delivered until all parts of a message have been
* delivered. This means that one large message, being read with an
* association identification of "X", will block other messages from
* association "X" from being delivered.
*
* <P> {@code level 2} - Allows complete interleaving of messages. This
* level requires that the sender carefully observe not only the peer
* {@code Association} but also must pay careful attention to the stream
* number. With this option enabled a partially delivered message may begin
* being delivered for association "X" stream "Y" and the next subsequent
* receive may return a message from association "X" stream "Z". Note that
* no other messages would be delivered for association "X" stream "Y"
* until all of stream "Y"'s partially delivered message was read.
* Note that this option effects both channel types. Also note that
* for an {@code SctpMultiChannel} not only may another streams
* message from the same association be delivered from the next receive,
* some other associations message may be delivered upon the next receive.
*
* <P> It is implementation specific whether or not this option is
* supported.
*/
public static final SctpSocketOption<Integer> SCTP_FRAGMENT_INTERLEAVE =
new SctpStdSocketOption<Integer>("SCTP_FRAGMENT_INTERLEAVE",
Integer.class,
sun.nio.ch.sctp.SctpStdSocketOption.SCTP_FRAGMENT_INTERLEAVE);
/**
* The maximum number of streams requested by the local endpoint during
* association initialization.
*
* <P> The value of this socket option is an {@link
* SctpStandardSocketOptions.InitMaxStreams InitMaxStreams}, that represents
* the maximum number of inbound and outbound streams that an association
* on the channel is prepared to support.
*
* <P> For an {@link SctpChannel} this option may only be used to
* change the number of inbound/outbound streams prior to connecting.
*
* <P> For an {@link SctpMultiChannel} this option determines
* the maximum number of inbound/outbound streams new associations setup
* on the channel will be prepared to support.
*
* <P> For an {@link SctpServerChannel} this option determines the
* maximum number of inbound/outbound streams accepted sockets will
* negotiate with their connecting peer.
*
* <P> In all cases the value set by this option is used in the negotiation
* of new associations setup on the channel's socket and the actual
* maximum number of inbound/outbound streams that have been negotiated
* with the peer can be retrieved from the appropriate {@link
* Association}. The {@code Association} can be retrieved from the
* {@link AssociationChangeNotification.AssocChangeEvent#COMM_UP COMM_UP}
* {@link AssociationChangeNotification} belonging to that association.
*
* <p> This value is bounded by the actual implementation. In other
* words the user may be able to support more streams than the Operating
* System. In such a case, the Operating System limit may override the
* value requested by the user. The default value of 0 indicates to use
* the endpoints default value.
*/
public static final SctpSocketOption
<SctpStandardSocketOptions.InitMaxStreams> SCTP_INIT_MAXSTREAMS =
new SctpStdSocketOption<SctpStandardSocketOptions.InitMaxStreams>(
"SCTP_INIT_MAXSTREAMS", SctpStandardSocketOptions.InitMaxStreams.class);
/**
* Enables or disables a Nagle-like algorithm.
*
* <P> The value of this socket option is a {@code Boolean} that represents
* whether the option is enabled or disabled. SCTP uses an algorithm like
* <em>The Nagle Algorithm</em> to coalesce short segments and
* improve network efficiency.
*/
public static final SctpSocketOption<Boolean> SCTP_NODELAY =
new SctpStdSocketOption<Boolean>("SCTP_NODELAY", Boolean.class,
sun.nio.ch.sctp.SctpStdSocketOption.SCTP_NODELAY);
/**
* Requests that the local SCTP stack use the given peer address as
* the association primary.
*
* <P> The value of this socket option is a {@code SocketAddress}
* that represents the peer address that the local SCTP stack should use as
* the association primary. The address must be one of the association
* peer's addresses.
*
* <P> An {@code SctpMultiChannel} can control more than one
* association, the association parameter must be given when setting or
* retrieving this option.
*
* <P> Since {@code SctpChannel} only controls one association,
* the association parameter is not required and this option can be
* set or queried directly.
*/
public static final SctpSocketOption<SocketAddress> SCTP_PRIMARY_ADDR =
new SctpStdSocketOption<SocketAddress>
("SCTP_PRIMARY_ADDR", SocketAddress.class);
/**
* Requests that the peer mark the enclosed address as the association
* primary.
*
* <P> The value of this socket option is a {@code SocketAddress}
* that represents the local address that the peer should use as its
* primary address. The given address must be one of the association's
* locally bound addresses.
*
* <P> An {@code SctpMultiChannel} can control more than one
* association, the association parameter must be given when setting or
* retrieving this option.
*
* <P> Since {@code SctpChannel} only controls one association,
* the association parameter is not required and this option can be
* queried directly.
*
* <P> Note, this is a set only option and cannot be retrieved by {@code
* getOption}. It is implementation specific whether or not this
* option is supported.
*/
public static final SctpSocketOption<SocketAddress> SCTP_SET_PEER_PRIMARY_ADDR =
new SctpStdSocketOption<SocketAddress>
("SCTP_SET_PEER_PRIMARY_ADDR", SocketAddress.class);
/**
* The size of the socket send buffer.
*
* <p> The value of this socket option is an {@code Integer} that is the
* size of the socket send buffer in bytes. The socket send buffer is an
* output buffer used by the networking implementation. It may need to be
* increased for high-volume connections. The value of the socket option is
* a <em>hint</em> to the implementation to size the buffer and the actual
* size may differ. The socket option can be queried to retrieve the actual
* size.
*
* <p> For {@code SctpChannel}, this controls the amount of data
* the SCTP stack may have waiting in internal buffers to be sent. This
* option therefore bounds the maximum size of data that can be sent in a
* single send call.
*
* <P> For {@code SctpMultiChannel}, the effect is the same as for {@code
* SctpChannel}, except that it applies to all associations. The option
* applies to each association's window size separately.
*
* <p> An implementation allows this socket option to be set before the
* socket is bound or connected. Whether an implementation allows the
* socket send buffer to be changed after the socket is bound is system
* dependent.
*/
public static final SctpSocketOption<Integer> SO_SNDBUF =
new SctpStdSocketOption<Integer>("SO_SNDBUF", Integer.class,
sun.nio.ch.sctp.SctpStdSocketOption.SO_SNDBUF);
/**
* The size of the socket receive buffer.
*
* <P> The value of this socket option is an {@code Integer} that is the
* size of the socket receive buffer in bytes. The socket receive buffer is
* an input buffer used by the networking implementation. It may need to be
* increased for high-volume connections or decreased to limit the possible
* backlog of incoming data. The value of the socket option is a
* <em>hint</em> to the implementation to size the buffer and the actual
* size may differ.
*
* <P> For {@code SctpChannel}, this controls the receiver window size.
*
* <P> For {@code SctpMultiChannel}, the meaning is implementation
* dependent. It might control the receive buffer for each association bound
* to the socket descriptor or it might control the receive buffer for the
* whole socket.
*
* <p> An implementation allows this socket option to be set before the
* socket is bound or connected. Whether an implementation allows the
* socket receive buffer to be changed after the socket is bound is system
* dependent.
*/
public static final SctpSocketOption<Integer> SO_RCVBUF =
new SctpStdSocketOption<Integer>("SO_RCVBUF", Integer.class,
sun.nio.ch.sctp.SctpStdSocketOption.SO_RCVBUF);
/**
* Linger on close if data is present.
*
* <p> The value of this socket option is an {@code Integer} that controls
* the action taken when unsent data is queued on the socket and a method
* to close the socket is invoked. If the value of the socket option is zero
* or greater, then it represents a timeout value, in seconds, known as the
* <em>linger interval</em>. The linger interval is the timeout for the
* {@code close} method to block while the operating system attempts to
* transmit the unsent data or it decides that it is unable to transmit the
* data. If the value of the socket option is less than zero then the option
* is disabled. In that case the {@code close} method does not wait until
* unsent data is transmitted; if possible the operating system will transmit
* any unsent data before the connection is closed.
*
* <p> This socket option is intended for use with sockets that are configured
* in {@link java.nio.channels.SelectableChannel#isBlocking() blocking} mode
* only. The behavior of the {@code close} method when this option is
* enabled on a non-blocking socket is not defined.
*
* <p> The initial value of this socket option is a negative value, meaning
* that the option is disabled. The option may be enabled, or the linger
* interval changed, at any time. The maximum value of the linger interval
* is system dependent. Setting the linger interval to a value that is
* greater than its maximum value causes the linger interval to be set to
* its maximum value.
*/
public static final SctpSocketOption<Integer> SO_LINGER =
new SctpStdSocketOption<Integer>("SO_LINGER", Integer.class,
sun.nio.ch.sctp.SctpStdSocketOption.SO_LINGER);
/**
* This class is used to set the maximum number of inbound/outbound streams
* used by the local endpoint during association initialization. An
* instance of this class is used to set the {@link
* SctpStandardSocketOptions#SCTP_INIT_MAXSTREAMS SCTP_INIT_MAXSTREAMS}
* socket option.
*
* @since 1.7
*/
public static class InitMaxStreams {
private int maxInStreams;
private int maxOutStreams;
private InitMaxStreams(int maxInStreams, int maxOutStreams) {
this.maxInStreams = maxInStreams;
this.maxOutStreams = maxOutStreams;
}
/**
* Creates an InitMaxStreams instance.
*
* @param maxInStreams
* The maximum number of inbound streams, where
* {@code 0 <= maxInStreams <= 65536}
*
* @param maxOutStreams
* The maximum number of outbound streams, where
* {@code 0 <= maxOutStreams <= 65536}
*
* @return An {@code InitMaxStreams} instance
*
* @throws IllegalArgumentException
* If an argument is outside of specified bounds
*/
public static InitMaxStreams create
(int maxInStreams, int maxOutStreams) {
if (maxOutStreams < 0 || maxOutStreams > 65535)
throw new IllegalArgumentException(
"Invalid maxOutStreams value");
if (maxInStreams < 0 || maxInStreams > 65535)
throw new IllegalArgumentException(
"Invalid maxInStreams value");
return new InitMaxStreams(maxInStreams, maxOutStreams);
}
/**
* Returns the maximum number of inbound streams.
*
* @return Maximum inbound streams
*/
public int maxInStreams() {
return maxInStreams;
}
/**
* Returns the maximum number of outbound streams.
*
* @return Maximum outbound streams
*/
public int maxOutStreams() {
return maxOutStreams;
}
/**
* Returns a string representation of this init max streams, including
* the maximum in and out bound streams.
*
* @return A string representation of this init max streams
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(super.toString()).append(" [");
sb.append("maxInStreams:").append(maxInStreams);
sb.append("maxOutStreams:").append(maxOutStreams).append("]");
return sb.toString();
}
/**
* Returns true if the specified object is another {@code InitMaxStreams}
* instance with the same number of in and out bound streams.
*
* @param obj
* The object to be compared with this init max streams
*
* @return true if the specified object is another
* {@code InitMaxStreams} instance with the same number of in
* and out bound streams
*/
@Override
public boolean equals(Object obj) {
if (obj != null && obj instanceof InitMaxStreams) {
InitMaxStreams that = (InitMaxStreams) obj;
if (this.maxInStreams == that.maxInStreams &&
this.maxOutStreams == that.maxOutStreams)
return true;
}
return false;
}
/**
* Returns a hash code value for this init max streams.
*/
@Override
public int hashCode() {
int hash = 7 ^ maxInStreams ^ maxOutStreams;
return hash;
}
}
}

View file

@ -0,0 +1,89 @@
/*
* 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 com.sun.nio.sctp;
import java.nio.ByteBuffer;
import java.net.SocketAddress;
/**
* Notification emitted when a send failed notification has been received.
*
* <P> A send failed notification indicates that a message cannot be delivered.
* Typically this is because the association has been shutdown with unsent data
* in the socket output buffer, or in the case of a {@link SctpMultiChannel}
* the association failed to setup.
*
* @since 1.7
*/
public abstract class SendFailedNotification implements Notification {
/**
* Initializes a new instance of this class.
*/
protected SendFailedNotification() {}
/**
* Returns the association that this notification is applicable to.
*
* @return The association that failed to send, or {@code null} if
* there is no association, that is, the notification follows a
* {@linkplain
* com.sun.nio.sctp.AssociationChangeNotification.AssocChangeEvent#CANT_START}
*/
@Override
public abstract Association association();
/**
* Returns the address.
*
* @return The peer primary address of the association or the address that
* the message was sent to
*/
public abstract SocketAddress address();
/**
* Returns the data that was to be sent.
*
* @return The user data. The buffers position will be {@code 0} and its
* limit will be set to the end of the data.
*/
public abstract ByteBuffer buffer();
/**
* Returns the error code.
*
* <P> The errorCode gives the reason why the send failed, and if set, will
* be a SCTP protocol error code as defined in RFC2960 section 3.3.10
*
* @return The error code
*/
public abstract int errorCode();
/**
* Returns the stream number that the messge was to be sent on.
*
* @return The stream number
*/
public abstract int streamNumber();
}

View file

@ -0,0 +1,47 @@
/*
* 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 com.sun.nio.sctp;
/**
* Notification emitted when a peers shutdowns an the association.
*
* <P> When a peer sends a <i>SHUTDOWN</i>, the SCTP stack delivers this
* notification to inform the application that it should cease sending data.
*
* @since 1.7
*/
public abstract class ShutdownNotification implements Notification {
/**
* Initializes a new instance of this class.
*/
protected ShutdownNotification() {}
/**
* Returns the association that this notification is applicable to.
*
* @return The association that received the shutdown
*/
public abstract Association association();
}

View file

@ -0,0 +1,75 @@
/*
* 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.
*/
/**
* A Java API for Stream Control Transport Protocol.
*
* <P> The Stream Control Transport Protocol (SCTP) is a reliable,
* message-oriented, transport protocol existing at an equivalent level with UDP
* (User Datagram Protocol) and TCP (Transmission Control Protocol). SCTP is
* session oriented and an association between the endpoints must be established
* before any data can be transmitted.
*
* <P> SCTP has direct support for multi-homing, meaning than an endpoint may be
* represented by more than one address and each address may be used for sending
* and receiving data, thus providing network redundancy. The connection between
* two endpoints is referred to as an association between those endpoints.
* Endpoints can exchange a list of addresses during association setup. One
* address is designated as the primary address, this is the default address that
* the peer will use for sending data. A single port number is used across the
* entire address list at an endpoint for a specific session.
*
* <P> SCTP is message based. I/O operations operate upon messages and message
* boundaries are preserved. Each association may support multiple independent
* logical streams. Each stream represents a sequence of messages within a single
* association and streams are independent of one another, meaning that stream
* identifiers and sequence numbers are included in the data packet to allow
* sequencing of messages on a per-stream basis.
*
* <P> This package provides two programming model styles. The one-to-one style
* supported by {@link com.sun.nio.sctp.SctpChannel} and {@link
* com.sun.nio.sctp.SctpServerChannel}, and the one-to-many
* style supported by {@link com.sun.nio.sctp.SctpMultiChannel}.
* The semantics of the one-to-one style interface are very similar to TCP.
* An {@code SctpChannel} can only control one SCTP association. The
* semantics of the one-to-many style interface are very similar to UDP. An
* {@code SctpMutliChannel} can control multiple SCTP associations.
*
* <P> Applications can send and receive per-message ancillary information through
* {@link com.sun.nio.sctp.MessageInfo}. For example, the stream number that
* the message it is to be sent or received from. The SCTP stack is event driven
* and applications can receive notifications of certain SCTP events by invoking
* the {@code receive} method of the SCTP channel with an appropriate {@link
* com.sun.nio.sctp.NotificationHandler notification handler}.
*
* <P> The SCTP protocol is defined by
* <A HREF="http://tools.ietf.org/html/rfc4960">RFC4960</A>, and the optional
* extension for <I>Dynamic Address Reconfiguration</I> is defined by
* <A HREF="http://tools.ietf.org/html/rfc5061">RFC5061</A>.
*
* @since 1.7
*/
package com.sun.nio.sctp;

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2014, 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.
*/
/**
* Defines the JDK-specific API for SCTP.
*
* @moduleGraph
* @since 9
*/
module jdk.sctp {
exports com.sun.nio.sctp;
}

View file

@ -0,0 +1,170 @@
/*
* 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.net.SocketAddress;
import com.sun.nio.sctp.MessageInfo;
import com.sun.nio.sctp.Association;
/**
* An implementation of a MessageInfo.
*/
public class MessageInfoImpl extends MessageInfo {
private final SocketAddress address;
private final int bytes; /* 0 */
private Association association;
private int assocId;
private int streamNumber;
private boolean complete = true;
private boolean unordered; /* false */
private long timeToLive; /* 0L */
private int ppid; /* 0 */
public MessageInfoImpl(Association association,
SocketAddress address,
int streamNumber) {
this.association = association;
this.address = address;
this.streamNumber = streamNumber;
bytes = 0;
}
/* Invoked from native */
private MessageInfoImpl(int assocId,
SocketAddress address,
int bytes,
int streamNumber,
boolean complete,
boolean unordered,
int ppid) {
this.assocId = assocId;
this.address = address;
this.bytes = bytes;
this.streamNumber = streamNumber;
this.complete = complete;
this.unordered = unordered;
this.ppid = ppid;
}
@Override
public Association association() {
return association;
}
/**
* MessageInfoImpl instances created from native will need to have their
* association set from the channel.
*/
void setAssociation(Association association) {
this.association = association;
}
int associationID() {
return assocId;
}
@Override
public SocketAddress address() {
return address;
}
@Override
public int bytes() {
return bytes;
}
@Override
public int streamNumber() {
return streamNumber;
}
@Override
public MessageInfo streamNumber(int streamNumber) {
if (streamNumber < 0 || streamNumber > 65536)
throw new IllegalArgumentException("Invalid stream number");
this.streamNumber = streamNumber;
return this;
}
@Override
public int payloadProtocolID() {
return ppid;
}
@Override
public MessageInfo payloadProtocolID(int ppid) {
this.ppid = ppid;
return this;
}
@Override
public boolean isComplete() {
return complete;
}
@Override
public MessageInfo complete(boolean complete) {
this.complete = complete;
return this;
}
@Override
public boolean isUnordered() {
return unordered;
}
@Override
public MessageInfo unordered(boolean unordered) {
this.unordered = unordered;
return this;
}
@Override
public long timeToLive() {
return timeToLive;
}
@Override
public MessageInfo timeToLive(long millis) {
timeToLive = millis;
return this;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(super.toString());
sb.append( "[Address: ").append(address)
.append(", Association: ").append(association)
.append(", Assoc ID: ").append(assocId)
.append(", Bytes: ").append(bytes)
.append(", Stream Number: ").append(streamNumber)
.append(", Complete: ").append(complete)
.append(", isUnordered: ").append(unordered)
.append("]");
return sb.toString();
}
}

View file

@ -0,0 +1,77 @@
/*
* 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.SctpSocketOption;
import java.lang.annotation.Native;
public class SctpStdSocketOption<T>
implements SctpSocketOption<T>
{
/* for native mapping of int options */
@Native public static final int SCTP_DISABLE_FRAGMENTS = 1;
@Native public static final int SCTP_EXPLICIT_COMPLETE = 2;
@Native public static final int SCTP_FRAGMENT_INTERLEAVE = 3;
@Native public static final int SCTP_NODELAY = 4;
@Native public static final int SO_SNDBUF = 5;
@Native public static final int SO_RCVBUF = 6;
@Native public static final int SO_LINGER = 7;
private final String name;
private final Class<T> type;
/* for native mapping of int options */
private int constValue;
public SctpStdSocketOption(String name, Class<T> type) {
this.name = name;
this.type = type;
}
public SctpStdSocketOption(String name, Class<T> type, int constValue) {
this.name = name;
this.type = type;
this.constValue = constValue;
}
@Override
public String name() {
return name;
}
@Override
public Class<T> type() {
return type;
}
@Override
public String toString() {
return name;
}
int constValue() {
return constValue;
}
}

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();
}
}

View file

@ -0,0 +1,334 @@
/*
* 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.
*/
#ifndef SUN_NIO_CH_SCTP_H
#define SUN_NIO_CH_SCTP_H
#ifdef __solaris__
#define _XPG4_2
#define __EXTENSIONS__
#include <sys/socket.h>
#include <netinet/sctp.h>
#include "jni.h"
/* Current Solaris headers don't comply with draft rfc */
#ifndef SCTP_EOF
#define SCTP_EOF MSG_EOF
#endif
#ifndef SCTP_UNORDERED
#define SCTP_UNORDERED MSG_UNORDERED
#endif
/* The current version of the socket API extension shipped with Solaris does
* not define the following options that the Java API (optionally) supports */
#ifndef SCTP_EXPLICIT_EOR
#define SCTP_EXPLICIT_EOR -1
#endif
#ifndef SCTP_FRAGMENT_INTERLEAVE
#define SCTP_FRAGMENT_INTERLEAVE -1
#endif
#ifndef SCTP_SET_PEER_PRIMARY_ADDR
#define SCTP_SET_PEER_PRIMARY_ADDR -1
#endif
/* Function types to support dynamic linking of socket API extension functions
* for SCTP. This is so that there is no linkage depandancy during build or
* runtime for libsctp.*/
typedef int sctp_getladdrs_func(int sock, sctp_assoc_t id, void **addrs);
typedef int sctp_freeladdrs_func(void* addrs);
typedef int sctp_getpaddrs_func(int sock, sctp_assoc_t id, void **addrs);
typedef int sctp_freepaddrs_func(void *addrs);
typedef int sctp_bindx_func(int sock, void *addrs, int addrcnt, int flags);
typedef int sctp_peeloff_func(int sock, sctp_assoc_t id);
#else /* __linux__ */
#include <stdint.h>
#include <linux/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "jni.h"
//Causes compiler error if not found, should make warning and uncomment
/*#include <netinet/sctp.h>*/
#ifndef IPPROTO_SCTP
#define IPPROTO_SCTP 132
#endif
/* The current version of lksctp does
* not define the following option that the Java API (optionally) supports */
#ifndef SCTP_EXPLICIT_EOR
#define SCTP_EXPLICIT_EOR -1
#endif
/* Definitions taken from lksctp-tools-1.0.8/src/include/netinet/sctp.h */
#ifndef SCTP_INITMSG
enum sctp_optname {
SCTP_RTOINFO,
#define SCTP_RTOINFO SCTP_RTOINFO
SCTP_ASSOCINFO,
#define SCTP_ASSOCINFO SCTP_ASSOCINFO
SCTP_INITMSG,
#define SCTP_INITMSG SCTP_INITMSG
SCTP_NODELAY, /* Get/set nodelay option. */
#define SCTP_NODELAY SCTP_NODELAY
SCTP_AUTOCLOSE,
#define SCTP_AUTOCLOSE SCTP_AUTOCLOSE
SCTP_SET_PEER_PRIMARY_ADDR,
#define SCTP_SET_PEER_PRIMARY_ADDR SCTP_SET_PEER_PRIMARY_ADDR
SCTP_PRIMARY_ADDR,
#define SCTP_PRIMARY_ADDR SCTP_PRIMARY_ADDR
SCTP_ADAPTATION_LAYER,
#define SCTP_ADAPTATION_LAYER SCTP_ADAPTATION_LAYER
SCTP_DISABLE_FRAGMENTS,
#define SCTP_DISABLE_FRAGMENTS SCTP_DISABLE_FRAGMENTS
SCTP_PEER_ADDR_PARAMS,
#define SCTP_PEER_ADDR_PARAMS SCTP_PEER_ADDR_PARAMS
SCTP_DEFAULT_SEND_PARAM,
#define SCTP_DEFAULT_SEND_PARAM SCTP_DEFAULT_SEND_PARAM
SCTP_EVENTS,
#define SCTP_EVENTS SCTP_EVENTS
SCTP_I_WANT_MAPPED_V4_ADDR, /* Turn on/off mapped v4 addresses */
#define SCTP_I_WANT_MAPPED_V4_ADDR SCTP_I_WANT_MAPPED_V4_ADDR
SCTP_MAXSEG, /* Get/set maximum fragment. */
#define SCTP_MAXSEG SCTP_MAXSEG
SCTP_STATUS,
#define SCTP_STATUS SCTP_STATUS
SCTP_GET_PEER_ADDR_INFO,
#define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO
SCTP_DELAYED_ACK_TIME,
#define SCTP_DELAYED_ACK_TIME SCTP_DELAYED_ACK_TIME
SCTP_CONTEXT, /* Receive Context */
#define SCTP_CONTEXT SCTP_CONTEXT
SCTP_FRAGMENT_INTERLEAVE,
#define SCTP_FRAGMENT_INTERLEAVE SCTP_FRAGMENT_INTERLEAVE
SCTP_PARTIAL_DELIVERY_POINT, /* Set/Get partial delivery point */
#define SCTP_PARTIAL_DELIVERY_POINT SCTP_PARTIAL_DELIVERY_POINT
SCTP_MAX_BURST, /* Set/Get max burst */
#define SCTP_MAX_BURST SCTP_MAX_BURST
};
enum sctp_sac_state {
SCTP_COMM_UP,
SCTP_COMM_LOST,
SCTP_RESTART,
SCTP_SHUTDOWN_COMP,
SCTP_CANT_STR_ASSOC,
};
enum sctp_spc_state {
SCTP_ADDR_AVAILABLE,
SCTP_ADDR_UNREACHABLE,
SCTP_ADDR_REMOVED,
SCTP_ADDR_ADDED,
SCTP_ADDR_MADE_PRIM,
SCTP_ADDR_CONFIRMED,
};
enum sctp_sinfo_flags {
SCTP_UNORDERED = 1, /* Send/receive message unordered. */
SCTP_ADDR_OVER = 2, /* Override the primary destination. */
SCTP_ABORT=4, /* Send an ABORT message to the peer. */
SCTP_EOF=MSG_FIN, /* Initiate graceful shutdown process. */
};
enum sctp_sn_type {
SCTP_SN_TYPE_BASE = (1<<15),
SCTP_ASSOC_CHANGE,
SCTP_PEER_ADDR_CHANGE,
SCTP_SEND_FAILED,
SCTP_REMOTE_ERROR,
SCTP_SHUTDOWN_EVENT,
SCTP_PARTIAL_DELIVERY_EVENT,
SCTP_ADAPTATION_INDICATION,
};
typedef enum sctp_cmsg_type {
SCTP_INIT, /* 5.2.1 SCTP Initiation Structure */
#define SCTP_INIT SCTP_INIT
SCTP_SNDRCV, /* 5.2.2 SCTP Header Information Structure */
#define SCTP_SNDRCV SCTP_SNDRCV
} sctp_cmsg_t;
enum sctp_msg_flags {
MSG_NOTIFICATION = 0x8000,
#define MSG_NOTIFICATION MSG_NOTIFICATION
};
#define SCTP_BINDX_ADD_ADDR 0x01
#define SCTP_BINDX_REM_ADDR 0x02
typedef __s32 sctp_assoc_t;
struct sctp_initmsg {
__u16 sinit_num_ostreams;
__u16 sinit_max_instreams;
__u16 sinit_max_attempts;
__u16 sinit_max_init_timeo;
};
struct sctp_sndrcvinfo {
__u16 sinfo_stream;
__u16 sinfo_ssn;
__u16 sinfo_flags;
__u32 sinfo_ppid;
__u32 sinfo_context;
__u32 sinfo_timetolive;
__u32 sinfo_tsn;
__u32 sinfo_cumtsn;
sctp_assoc_t sinfo_assoc_id;
};
struct sctp_event_subscribe {
__u8 sctp_data_io_event;
__u8 sctp_association_event;
__u8 sctp_address_event;
__u8 sctp_send_failure_event;
__u8 sctp_peer_error_event;
__u8 sctp_shutdown_event;
__u8 sctp_partial_delivery_event;
__u8 sctp_adaptation_layer_event;
};
struct sctp_send_failed {
__u16 ssf_type;
__u16 ssf_flags;
__u32 ssf_length;
__u32 ssf_error;
struct sctp_sndrcvinfo ssf_info;
sctp_assoc_t ssf_assoc_id;
__u8 ssf_data[0];
};
struct sctp_assoc_change {
__u16 sac_type;
__u16 sac_flags;
__u32 sac_length;
__u16 sac_state;
__u16 sac_error;
__u16 sac_outbound_streams;
__u16 sac_inbound_streams;
sctp_assoc_t sac_assoc_id;
__u8 sac_info[0];
};
struct sctp_shutdown_event {
__u16 sse_type;
__u16 sse_flags;
__u32 sse_length;
sctp_assoc_t sse_assoc_id;
};
struct sctp_paddr_change {
__u16 spc_type;
__u16 spc_flags;
__u32 spc_length;
struct sockaddr_storage spc_aaddr;
int spc_state;
int spc_error;
sctp_assoc_t spc_assoc_id;
} __attribute__((packed, aligned(4)));
struct sctp_remote_error {
__u16 sre_type;
__u16 sre_flags;
__u32 sre_length;
__u16 sre_error;
sctp_assoc_t sre_assoc_id;
__u8 sre_data[0];
};
struct sctp_adaptation_event {
__u16 sai_type;
__u16 sai_flags;
__u32 sai_length;
__u32 sai_adaptation_ind;
sctp_assoc_t sai_assoc_id;
};
struct sctp_setprim {
sctp_assoc_t ssp_assoc_id;
struct sockaddr_storage ssp_addr;
} __attribute__((packed, aligned(4)));
struct sctp_setpeerprim {
sctp_assoc_t sspp_assoc_id;
struct sockaddr_storage sspp_addr;
} __attribute__((packed, aligned(4)));
struct sctp_pdapi_event {
__u16 pdapi_type;
__u16 pdapi_flags;
__u32 pdapi_length;
__u32 pdapi_indication;
sctp_assoc_t pdapi_assoc_id;
};
union sctp_notification {
struct {
__u16 sn_type; /* Notification type. */
__u16 sn_flags;
__u32 sn_length;
} sn_header;
struct sctp_assoc_change sn_assoc_change;
struct sctp_paddr_change sn_paddr_change;
struct sctp_remote_error sn_remote_error;
struct sctp_send_failed sn_send_failed;
struct sctp_shutdown_event sn_shutdown_event;
struct sctp_adaptation_event sn_adaptation_event;
struct sctp_pdapi_event sn_pdapi_event;
};
#endif /* SCTP_INITMSG */
/* Function types to support dynamic linking of socket API extension functions
* for SCTP. This is so that there is no linkage depandancy during build or
* runtime for libsctp.*/
typedef int sctp_getladdrs_func(int sd, sctp_assoc_t id, struct sockaddr **addrs);
typedef int sctp_freeladdrs_func(struct sockaddr *addrs);
typedef int sctp_getpaddrs_func(int sd, sctp_assoc_t id, struct sockaddr **addrs);
typedef int sctp_freepaddrs_func(struct sockaddr *addrs);
typedef int sctp_bindx_func(int sd, struct sockaddr *addrs, int addrcnt, int flags);
typedef int sctp_peeloff_func(int sock, sctp_assoc_t id);
#endif /* __linux__ */
sctp_getladdrs_func* nio_sctp_getladdrs;
sctp_freeladdrs_func* nio_sctp_freeladdrs;
sctp_getpaddrs_func* nio_sctp_getpaddrs;
sctp_freepaddrs_func* nio_sctp_freepaddrs;
sctp_bindx_func* nio_sctp_bindx;
sctp_peeloff_func* nio_sctp_peeloff;
jboolean loadSocketExtensionFuncs(JNIEnv* env);
#endif /* !SUN_NIO_CH_SCTP_H */

View file

@ -0,0 +1,610 @@
/*
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <stdlib.h>
#include <string.h>
#include "Sctp.h"
#include "jni.h"
#include "nio_util.h"
#include "nio.h"
#include "net_util.h"
#include "net_util_md.h"
#include "sun_nio_ch_sctp_SctpNet.h"
#include "sun_nio_ch_sctp_SctpChannelImpl.h"
#include "sun_nio_ch_sctp_AssociationChange.h"
#include "sun_nio_ch_sctp_ResultContainer.h"
#include "sun_nio_ch_sctp_PeerAddrChange.h"
static int SCTP_NOTIFICATION_SIZE = sizeof(union sctp_notification);
#define MESSAGE_IMPL_CLASS "sun/nio/ch/sctp/MessageInfoImpl"
#define RESULT_CONTAINER_CLASS "sun/nio/ch/sctp/ResultContainer"
#define SEND_FAILED_CLASS "sun/nio/ch/sctp/SendFailed"
#define ASSOC_CHANGE_CLASS "sun/nio/ch/sctp/AssociationChange"
#define PEER_CHANGE_CLASS "sun/nio/ch/sctp/PeerAddrChange"
#define SHUTDOWN_CLASS "sun/nio/ch/sctp/Shutdown"
struct controlData {
int assocId;
unsigned short streamNumber;
jboolean unordered;
unsigned int ppid;
};
static jclass smi_class; /* sun.nio.ch.sctp.MessageInfoImpl */
static jmethodID smi_ctrID; /* sun.nio.ch.sctp.MessageInfoImpl.<init> */
static jfieldID src_valueID; /* sun.nio.ch.sctp.ResultContainer.value */
static jfieldID src_typeID; /* sun.nio.ch.sctp.ResultContainer.type */
static jclass ssf_class; /* sun.nio.ch.sctp.SendFailed */
static jmethodID ssf_ctrID; /* sun.nio.ch.sctp.SendFailed.<init> */
static jclass sac_class; /* sun.nio.ch.sctp.AssociationChange */
static jmethodID sac_ctrID; /* sun.nio.ch.sctp.AssociationChange.<init> */
static jclass spc_class; /* sun.nio.ch.sctp.PeerAddressChanged */
static jmethodID spc_ctrID; /* sun.nio.ch.sctp.PeerAddressChanged.<init> */
static jclass ss_class; /* sun.nio.ch.sctp.Shutdown */
static jmethodID ss_ctrID; /* sun.nio.ch.sctp.Shutdown.<init> */
/* defined in SctpNet.c */
jobject SockAddrToInetSocketAddress(JNIEnv* env, struct sockaddr* addr);
jint handleSocketError(JNIEnv *env, jint errorValue);
/* use SocketChannelImpl's checkConnect implementation */
extern jint Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv* env,
jobject this, jobject fdo, jboolean block, jboolean ready);
/*
* Class: sun_nio_ch_sctp_SctpChannelImpl
* Method: initIDs
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_initIDs
(JNIEnv *env, jclass klass) {
jclass cls;
/* MessageInfoImpl */
cls = (*env)->FindClass(env, MESSAGE_IMPL_CLASS);
CHECK_NULL(cls);
smi_class = (*env)->NewGlobalRef(env, cls);
CHECK_NULL(smi_class);
smi_ctrID = (*env)->GetMethodID(env, cls, "<init>",
"(ILjava/net/SocketAddress;IIZZI)V");
CHECK_NULL(smi_ctrID);
/* ResultContainer */
cls = (*env)->FindClass(env, RESULT_CONTAINER_CLASS);
CHECK_NULL(cls);
src_valueID = (*env)->GetFieldID(env, cls, "value", "Ljava/lang/Object;");
CHECK_NULL(src_valueID);
src_typeID = (*env)->GetFieldID(env, cls, "type", "I");
CHECK_NULL(src_typeID);
/* SendFailed */
cls = (*env)->FindClass(env, SEND_FAILED_CLASS);
CHECK_NULL(cls);
ssf_class = (*env)->NewGlobalRef(env, cls);
CHECK_NULL(ssf_class);
ssf_ctrID = (*env)->GetMethodID(env, cls, "<init>",
"(ILjava/net/SocketAddress;Ljava/nio/ByteBuffer;II)V");
CHECK_NULL(ssf_ctrID);
/* AssociationChange */
cls = (*env)->FindClass(env, ASSOC_CHANGE_CLASS);
CHECK_NULL(cls);
sac_class = (*env)->NewGlobalRef(env, cls);
CHECK_NULL(sac_class);
sac_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(IIII)V");
CHECK_NULL(sac_ctrID);
/* PeerAddrChange */
cls = (*env)->FindClass(env, PEER_CHANGE_CLASS);
CHECK_NULL(cls);
spc_class = (*env)->NewGlobalRef(env, cls);
CHECK_NULL(spc_class);
spc_ctrID = (*env)->GetMethodID(env, cls, "<init>",
"(ILjava/net/SocketAddress;I)V");
CHECK_NULL(spc_ctrID);
/* Shutdown */
cls = (*env)->FindClass(env, SHUTDOWN_CLASS);
CHECK_NULL(cls);
ss_class = (*env)->NewGlobalRef(env, cls);
CHECK_NULL(ss_class);
ss_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(I)V");
CHECK_NULL(ss_ctrID);
}
void getControlData
(struct msghdr* msg, struct controlData* cdata) {
struct cmsghdr* cmsg;
for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
if (cmsg->cmsg_level == IPPROTO_SCTP && cmsg->cmsg_type == SCTP_SNDRCV) {
struct sctp_sndrcvinfo *sri;
sri = (struct sctp_sndrcvinfo *) CMSG_DATA(cmsg);
cdata->assocId = sri->sinfo_assoc_id;
cdata->streamNumber = sri->sinfo_stream;
cdata->unordered = (sri->sinfo_flags & SCTP_UNORDERED) ? JNI_TRUE :
JNI_FALSE;
cdata->ppid = ntohl(sri->sinfo_ppid);
return;
}
}
return;
}
void setControlData
(struct msghdr* msg, struct controlData* cdata) {
struct cmsghdr* cmsg;
struct sctp_sndrcvinfo *sri;
cmsg = CMSG_FIRSTHDR(msg);
cmsg->cmsg_level = IPPROTO_SCTP;
cmsg->cmsg_type = SCTP_SNDRCV;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
/* Initialize the payload */
sri = (struct sctp_sndrcvinfo*) CMSG_DATA(cmsg);
memset(sri, 0, sizeof (*sri));
if (cdata->streamNumber > 0) {
sri->sinfo_stream = cdata->streamNumber;
}
if (cdata->assocId > 0) {
sri->sinfo_assoc_id = cdata->assocId;
}
if (cdata->unordered == JNI_TRUE) {
sri->sinfo_flags = sri->sinfo_flags | SCTP_UNORDERED;
}
if (cdata->ppid > 0) {
sri->sinfo_ppid = htonl(cdata->ppid);
}
/* Sum of the length of all control messages in the buffer. */
msg->msg_controllen = cmsg->cmsg_len;
}
// TODO: test: can create send failed without any data? if so need to
// update API so that buffer can be null if no data.
void handleSendFailed
(JNIEnv* env, int fd, jobject resultContainerObj, struct sctp_send_failed *ssf,
int read, jboolean isEOR, struct sockaddr* sap) {
jobject bufferObj = NULL, resultObj, isaObj;
char *addressP;
struct sctp_sndrcvinfo *sri;
int remaining, dataLength;
/* the actual undelivered message data is directly after the ssf */
int dataOffset = sizeof(struct sctp_send_failed);
sri = (struct sctp_sndrcvinfo*) &ssf->ssf_info;
/* the number of bytes remaining to be read in the sctp_send_failed notif*/
remaining = ssf->ssf_length - read;
/* the size of the actual undelivered message */
dataLength = ssf->ssf_length - dataOffset;
/* retrieved address from sockaddr */
isaObj = SockAddrToInetSocketAddress(env, sap);
CHECK_NULL(isaObj);
/* data retrieved from sff_data */
if (dataLength > 0) {
struct iovec iov[1];
struct msghdr msg[1];
int rv, alreadyRead;
char *dataP = (char*) ssf;
dataP += dataOffset;
if ((addressP = malloc(dataLength)) == NULL) {
JNU_ThrowOutOfMemoryError(env, "handleSendFailed");
return;
}
memset(msg, 0, sizeof (*msg));
msg->msg_iov = iov;
msg->msg_iovlen = 1;
bufferObj = (*env)->NewDirectByteBuffer(env, addressP, dataLength);
CHECK_NULL(bufferObj);
alreadyRead = read - dataOffset;
if (alreadyRead > 0) {
memcpy(addressP, /*ssf->ssf_data*/ dataP, alreadyRead);
iov->iov_base = addressP + alreadyRead;
iov->iov_len = dataLength - alreadyRead;
} else {
iov->iov_base = addressP;
iov->iov_len = dataLength;
}
if (remaining > 0) {
if ((rv = recvmsg(fd, msg, 0)) < 0) {
handleSocketError(env, errno);
return;
}
if (rv != (dataLength - alreadyRead) || !(msg->msg_flags & MSG_EOR)) {
//TODO: assert false: "should not reach here";
return;
}
// TODO: Set and document (in API) buffers position.
}
}
/* create SendFailed */
resultObj = (*env)->NewObject(env, ssf_class, ssf_ctrID, ssf->ssf_assoc_id,
isaObj, bufferObj, ssf->ssf_error, sri->sinfo_stream);
CHECK_NULL(resultObj);
(*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
(*env)->SetIntField(env, resultContainerObj, src_typeID,
sun_nio_ch_sctp_ResultContainer_SEND_FAILED);
}
void handleAssocChange
(JNIEnv* env, jobject resultContainerObj, struct sctp_assoc_change *sac) {
jobject resultObj;
int state = 0;
switch (sac->sac_state) {
case SCTP_COMM_UP :
state = sun_nio_ch_sctp_AssociationChange_SCTP_COMM_UP;
break;
case SCTP_COMM_LOST :
state = sun_nio_ch_sctp_AssociationChange_SCTP_COMM_LOST;
break;
case SCTP_RESTART :
state = sun_nio_ch_sctp_AssociationChange_SCTP_RESTART;
break;
case SCTP_SHUTDOWN_COMP :
state = sun_nio_ch_sctp_AssociationChange_SCTP_SHUTDOWN;
break;
case SCTP_CANT_STR_ASSOC :
state = sun_nio_ch_sctp_AssociationChange_SCTP_CANT_START;
}
/* create AssociationChange */
resultObj = (*env)->NewObject(env, sac_class, sac_ctrID, sac->sac_assoc_id,
state, sac->sac_outbound_streams, sac->sac_inbound_streams);
CHECK_NULL(resultObj);
(*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
(*env)->SetIntField(env, resultContainerObj, src_typeID,
sun_nio_ch_sctp_ResultContainer_ASSOCIATION_CHANGED);
}
void handleShutdown
(JNIEnv* env, jobject resultContainerObj, struct sctp_shutdown_event* sse) {
/* create Shutdown */
jobject resultObj = (*env)->NewObject(env, ss_class, ss_ctrID, sse->sse_assoc_id);
CHECK_NULL(resultObj);
(*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
(*env)->SetIntField(env, resultContainerObj, src_typeID,
sun_nio_ch_sctp_ResultContainer_SHUTDOWN);
}
void handlePeerAddrChange
(JNIEnv* env, jobject resultContainerObj, struct sctp_paddr_change* spc) {
int event = 0;
jobject addressObj, resultObj;
unsigned int state = spc->spc_state;
switch (state) {
case SCTP_ADDR_AVAILABLE :
event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_AVAILABLE;
break;
case SCTP_ADDR_UNREACHABLE :
event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_UNREACHABLE;
break;
case SCTP_ADDR_REMOVED :
event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_REMOVED;
break;
case SCTP_ADDR_ADDED :
event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_ADDED;
break;
case SCTP_ADDR_MADE_PRIM :
event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_MADE_PRIM;
#ifdef __linux__ /* Solaris currently doesn't support SCTP_ADDR_CONFIRMED */
break;
case SCTP_ADDR_CONFIRMED :
event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_CONFIRMED;
#endif /* __linux__ */
}
addressObj = SockAddrToInetSocketAddress(env, (struct sockaddr*)&spc->spc_aaddr);
CHECK_NULL(addressObj);
/* create PeerAddressChanged */
resultObj = (*env)->NewObject(env, spc_class, spc_ctrID, spc->spc_assoc_id,
addressObj, event);
CHECK_NULL(resultObj);
(*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
(*env)->SetIntField(env, resultContainerObj, src_typeID,
sun_nio_ch_sctp_ResultContainer_PEER_ADDRESS_CHANGED);
}
void handleUninteresting
(union sctp_notification *snp) {
//fprintf(stdout,"\nNative: handleUninterestingNotification: Receive notification type [%u]", snp->sn_header.sn_type);
}
/**
* Handle notifications from the SCTP stack.
* Returns JNI_TRUE if the notification is one that is of interest to the
* Java API, otherwise JNI_FALSE.
*/
jboolean handleNotification
(JNIEnv* env, int fd, jobject resultContainerObj, union sctp_notification* snp,
int read, jboolean isEOR, struct sockaddr* sap) {
switch (snp->sn_header.sn_type) {
case SCTP_SEND_FAILED:
handleSendFailed(env, fd, resultContainerObj, &snp->sn_send_failed,
read, isEOR, sap);
return JNI_TRUE;
case SCTP_ASSOC_CHANGE:
handleAssocChange(env, resultContainerObj, &snp->sn_assoc_change);
return JNI_TRUE;
case SCTP_SHUTDOWN_EVENT:
handleShutdown(env, resultContainerObj, &snp->sn_shutdown_event);
return JNI_TRUE;
case SCTP_PEER_ADDR_CHANGE:
handlePeerAddrChange(env, resultContainerObj, &snp->sn_paddr_change);
return JNI_TRUE;
default :
/* the Java API is not interested in this event, maybe we are? */
handleUninteresting(snp);
}
return JNI_FALSE;
}
void handleMessage
(JNIEnv* env, jobject resultContainerObj, struct msghdr* msg,int read,
jboolean isEOR, struct sockaddr* sap) {
jobject isa, resultObj;
struct controlData cdata[1];
if (read == 0) {
/* we reached EOF */
read = -1;
}
isa = SockAddrToInetSocketAddress(env, sap);
CHECK_NULL(isa);
getControlData(msg, cdata);
/* create MessageInfoImpl */
resultObj = (*env)->NewObject(env, smi_class, smi_ctrID, cdata->assocId,
isa, read, cdata->streamNumber,
isEOR ? JNI_TRUE : JNI_FALSE,
cdata->unordered, cdata->ppid);
CHECK_NULL(resultObj);
(*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
(*env)->SetIntField(env, resultContainerObj, src_typeID,
sun_nio_ch_sctp_ResultContainer_MESSAGE);
}
/*
* Class: sun_nio_ch_sctp_SctpChannelImpl
* Method: receive0
* Signature: (ILsun/nio/ch/sctp/ResultContainer;JIZ)I
*/
JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_receive0
(JNIEnv *env, jclass klass, jint fd, jobject resultContainerObj,
jlong address, jint length, jboolean peek) {
SOCKETADDRESS sa;
ssize_t rv = 0;
jlong *addr = jlong_to_ptr(address);
struct iovec iov[1];
struct msghdr msg[1];
char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))];
int flags = peek == JNI_TRUE ? MSG_PEEK : 0;
/* Set up the msghdr structure for receiving */
memset(msg, 0, sizeof (*msg));
msg->msg_name = &sa;
msg->msg_namelen = sizeof(sa);
iov->iov_base = addr;
iov->iov_len = length;
msg->msg_iov = iov;
msg->msg_iovlen = 1;
msg->msg_control = cbuf;
msg->msg_controllen = sizeof(cbuf);
msg->msg_flags = 0;
do {
if ((rv = recvmsg(fd, msg, flags)) < 0) {
if (errno == EWOULDBLOCK) {
return IOS_UNAVAILABLE;
} else if (errno == EINTR) {
return IOS_INTERRUPTED;
#ifdef __linux__
} else if (errno == ENOTCONN) {
/* ENOTCONN when EOF reached */
rv = 0;
/* there will be no control data */
msg->msg_controllen = 0;
#endif /* __linux__ */
} else {
handleSocketError(env, errno);
return 0;
}
}
if (msg->msg_flags & MSG_NOTIFICATION) {
char *bufp = (char*)addr;
union sctp_notification *snp;
jboolean allocated = JNI_FALSE;
if (!(msg->msg_flags & MSG_EOR) && length < SCTP_NOTIFICATION_SIZE) {
char* newBuf;
int rvSAVE = rv;
if ((newBuf = malloc(SCTP_NOTIFICATION_SIZE)) == NULL) {
JNU_ThrowOutOfMemoryError(env, "Out of native heap space.");
return -1;
}
allocated = JNI_TRUE;
memcpy(newBuf, addr, rv);
iov->iov_base = newBuf + rv;
iov->iov_len = SCTP_NOTIFICATION_SIZE - rv;
if ((rv = recvmsg(fd, msg, flags)) < 0) {
handleSocketError(env, errno);
return 0;
}
bufp = newBuf;
rv += rvSAVE;
}
#ifdef __sparc
else if ((intptr_t)addr & 0x3) {
/* the given buffer is not 4 byte aligned */
char* newBuf;
if ((newBuf = malloc(SCTP_NOTIFICATION_SIZE)) == NULL) {
JNU_ThrowOutOfMemoryError(env, "Out of native heap space.");
return -1;
}
allocated = JNI_TRUE;
memcpy(newBuf, addr, rv);
bufp = newBuf;
}
#endif
snp = (union sctp_notification *) bufp;
if (handleNotification(env, fd, resultContainerObj, snp, rv,
(msg->msg_flags & MSG_EOR),
&sa.sa) == JNI_TRUE) {
/* We have received a notification that is of interest
to the Java API. The appropriate notification will be
set in the result container. */
if (allocated == JNI_TRUE) {
free(bufp);
}
return 0;
}
if (allocated == JNI_TRUE) {
free(bufp);
}
// set iov back to addr, and reset msg_controllen
iov->iov_base = addr;
iov->iov_len = length;
msg->msg_control = cbuf;
msg->msg_controllen = sizeof(cbuf);
}
} while (msg->msg_flags & MSG_NOTIFICATION);
handleMessage(env, resultContainerObj, msg, rv,
(msg->msg_flags & MSG_EOR), &sa.sa);
return rv;
}
/*
* Class: sun_nio_ch_sctp_SctpChannelImpl
* Method: send0
* Signature: (IJILjava/net/InetAddress;IIIZI)I
*/
JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_send0
(JNIEnv *env, jclass klass, jint fd, jlong address, jint length,
jobject targetAddress, jint targetPort, jint assocId, jint streamNumber,
jboolean unordered, jint ppid) {
SOCKETADDRESS sa;
int sa_len = 0;
ssize_t rv = 0;
jlong *addr = jlong_to_ptr(address);
struct iovec iov[1];
struct msghdr msg[1];
int cbuf_size = CMSG_SPACE(sizeof (struct sctp_sndrcvinfo));
char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))];
struct controlData cdata[1];
/* SctpChannel:
* targetAddress may contain the preferred address or NULL to use primary,
* assocId will always be -1
* SctpMultiChannell:
* Setup new association, targetAddress will contain address, assocId = -1
* Association already existing, assocId != -1, targetAddress = preferred addr
*/
if (targetAddress != NULL /*&& assocId <= 0*/) {
if (NET_InetAddressToSockaddr(env, targetAddress, targetPort, &sa,
&sa_len, JNI_TRUE) != 0) {
return IOS_THROWN;
}
} else {
memset(&sa, '\x0', sizeof(sa));
}
/* Set up the msghdr structure for sending */
memset(msg, 0, sizeof (*msg));
memset(cbuf, 0, cbuf_size);
msg->msg_name = &sa;
msg->msg_namelen = sa_len;
iov->iov_base = addr;
iov->iov_len = length;
msg->msg_iov = iov;
msg->msg_iovlen = 1;
msg->msg_control = cbuf;
msg->msg_controllen = cbuf_size;
msg->msg_flags = 0;
cdata->streamNumber = streamNumber;
cdata->assocId = assocId;
cdata->unordered = unordered;
cdata->ppid = ppid;
setControlData(msg, cdata);
if ((rv = sendmsg(fd, msg, 0)) < 0) {
if (errno == EWOULDBLOCK) {
return IOS_UNAVAILABLE;
} else if (errno == EINTR) {
return IOS_INTERRUPTED;
} else if (errno == EPIPE) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket is shutdown for writing");
} else {
handleSocketError(env, errno);
return 0;
}
}
return rv;
}
/*
* Class: sun_nio_ch_sctp_SctpChannelImpl
* Method: checkConnect
* Signature: (Ljava/io/FileDescriptor;ZZ)I
*/
JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_checkConnect
(JNIEnv* env, jobject this, jobject fdo, jboolean block, jboolean ready) {
return Java_sun_nio_ch_SocketChannelImpl_checkConnect(env, this,
fdo, block, ready);
}

View file

@ -0,0 +1,748 @@
/*
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include "Sctp.h"
#include "jni.h"
#include "jni_util.h"
#include "nio_util.h"
#include "nio.h"
#include "net_util.h"
#include "net_util_md.h"
#include "sun_nio_ch_sctp_SctpNet.h"
#include "sun_nio_ch_sctp_SctpStdSocketOption.h"
static jclass isaCls = 0;
static jmethodID isaCtrID = 0;
static const char* nativeSctpLib = "libsctp.so.1";
static jboolean funcsLoaded = JNI_FALSE;
JNIEXPORT jint JNICALL DEF_JNI_OnLoad
(JavaVM *vm, void *reserved) {
return JNI_VERSION_1_2;
}
static int preCloseFD = -1; /* File descriptor to which we dup other fd's
before closing them for real */
/**
* Loads the native sctp library that contains the socket extension
* functions, as well as locating the individual functions.
* There will be a pending exception if this method returns false.
*/
jboolean loadSocketExtensionFuncs
(JNIEnv* env) {
if (dlopen(nativeSctpLib, RTLD_GLOBAL | RTLD_LAZY) == NULL) {
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
dlerror());
return JNI_FALSE;
}
if ((nio_sctp_getladdrs = (sctp_getladdrs_func*)
dlsym(RTLD_DEFAULT, "sctp_getladdrs")) == NULL) {
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
dlerror());
return JNI_FALSE;
}
if ((nio_sctp_freeladdrs = (sctp_freeladdrs_func*)
dlsym(RTLD_DEFAULT, "sctp_freeladdrs")) == NULL) {
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
dlerror());
return JNI_FALSE;
}
if ((nio_sctp_getpaddrs = (sctp_getpaddrs_func*)
dlsym(RTLD_DEFAULT, "sctp_getpaddrs")) == NULL) {
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
dlerror());
return JNI_FALSE;
}
if ((nio_sctp_freepaddrs = (sctp_freepaddrs_func*)
dlsym(RTLD_DEFAULT, "sctp_freepaddrs")) == NULL) {
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
dlerror());
return JNI_FALSE;
}
if ((nio_sctp_bindx = (sctp_bindx_func*)
dlsym(RTLD_DEFAULT, "sctp_bindx")) == NULL) {
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
dlerror());
return JNI_FALSE;
}
if ((nio_sctp_peeloff = (sctp_peeloff_func*)
dlsym(RTLD_DEFAULT, "sctp_peeloff")) == NULL) {
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
dlerror());
return JNI_FALSE;
}
funcsLoaded = JNI_TRUE;
return JNI_TRUE;
}
jint
handleSocketError(JNIEnv *env, jint errorValue)
{
char *xn;
switch (errorValue) {
case EINPROGRESS: /* Non-blocking connect */
return 0;
case EPROTO:
xn= JNU_JAVANETPKG "ProtocolException";
break;
case ECONNREFUSED:
xn = JNU_JAVANETPKG "ConnectException";
break;
case ETIMEDOUT:
xn = JNU_JAVANETPKG "ConnectException";
break;
case EHOSTUNREACH:
xn = JNU_JAVANETPKG "NoRouteToHostException";
break;
case EADDRINUSE: /* Fall through */
case EADDRNOTAVAIL:
xn = JNU_JAVANETPKG "BindException";
break;
default:
xn = JNU_JAVANETPKG "SocketException";
break;
}
errno = errorValue;
JNU_ThrowByNameWithLastError(env, xn, "NioSocketError");
return IOS_THROWN;
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: init
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_sun_nio_ch_sctp_SctpNet_init
(JNIEnv *env, jclass cl) {
int sp[2];
if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) < 0) {
JNU_ThrowIOExceptionWithLastError(env, "socketpair failed");
return;
}
preCloseFD = sp[0];
close(sp[1]);
initInetAddressIDs(env);
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: socket0
* Signature: (Z)I
*/
JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpNet_socket0
(JNIEnv *env, jclass klass, jboolean oneToOne) {
int fd;
struct sctp_event_subscribe event;
#ifdef AF_INET6
int domain = ipv6_available() ? AF_INET6 : AF_INET;
#else
int domain = AF_INET;
#endif
/* Try to load the socket API extension functions */
if (!funcsLoaded && !loadSocketExtensionFuncs(env)) {
return 0;
}
fd = socket(domain, (oneToOne ? SOCK_STREAM : SOCK_SEQPACKET), IPPROTO_SCTP);
if (fd < 0) {
return handleSocketError(env, errno);
}
/* Enable events */
memset(&event, 0, sizeof(event));
event.sctp_data_io_event = 1;
event.sctp_association_event = 1;
event.sctp_address_event = 1;
event.sctp_send_failure_event = 1;
//event.sctp_peer_error_event = 1;
event.sctp_shutdown_event = 1;
//event.sctp_partial_delivery_event = 1;
//event.sctp_adaptation_layer_event = 1;
if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)) != 0) {
handleSocketError(env, errno);
}
return fd;
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: bindx
* Signature: (I[Ljava/net/InetAddress;IIZ)V
*/
JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_bindx
(JNIEnv *env, jclass klass, jint fd, jobjectArray addrs, jint port,
jint addrsLength, jboolean add, jboolean preferIPv6) {
SOCKETADDRESS *sap, *tmpSap;
int i;
jobject ia;
if (addrsLength < 1)
return;
if ((sap = calloc(addrsLength, sizeof(SOCKETADDRESS))) == NULL) {
JNU_ThrowOutOfMemoryError(env, "heap allocation failure");
return;
}
tmpSap = sap;
for (i = 0; i < addrsLength; i++) {
ia = (*env)->GetObjectArrayElement(env, addrs, i);
if (NET_InetAddressToSockaddr(env, ia, port, tmpSap, NULL,
preferIPv6) != 0) {
free(sap);
return;
}
tmpSap++;
}
if (nio_sctp_bindx(fd, (void *)sap, addrsLength, add ? SCTP_BINDX_ADD_ADDR :
SCTP_BINDX_REM_ADDR) != 0) {
handleSocketError(env, errno);
}
free(sap);
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: listen0
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_sun_nio_ch_sctp_SctpNet_listen0
(JNIEnv *env, jclass cl, jint fd, jint backlog) {
if (listen(fd, backlog) < 0)
handleSocketError(env, errno);
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: connect0
* Signature: (ILjava/net/InetAddress;I)I
*/
JNIEXPORT jint JNICALL
Java_sun_nio_ch_sctp_SctpNet_connect0
(JNIEnv *env, jclass clazz, int fd, jobject iao, jint port) {
SOCKETADDRESS sa;
int sa_len = 0;
int rv;
if (NET_InetAddressToSockaddr(env, iao, port, &sa, &sa_len,
JNI_TRUE) != 0) {
return IOS_THROWN;
}
rv = connect(fd, &sa.sa, sa_len);
if (rv != 0) {
if (errno == EINPROGRESS) {
return IOS_UNAVAILABLE;
} else if (errno == EINTR) {
return IOS_INTERRUPTED;
}
return handleSocketError(env, errno);
}
return 1;
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: close0
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_sun_nio_ch_sctp_SctpNet_close0
(JNIEnv *env, jclass clazz, jint fd) {
if (fd != -1) {
int rv = close(fd);
if (rv < 0)
JNU_ThrowIOExceptionWithLastError(env, "Close failed");
}
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: preClose0
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_sun_nio_ch_sctp_SctpNet_preClose0
(JNIEnv *env, jclass clazz, jint fd) {
if (preCloseFD >= 0) {
if (dup2(preCloseFD, fd) < 0)
JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");
}
}
void initializeISA(JNIEnv* env) {
if (isaCls == 0) {
jclass c = (*env)->FindClass(env, "java/net/InetSocketAddress");
CHECK_NULL(c);
isaCtrID = (*env)->GetMethodID(env, c, "<init>",
"(Ljava/net/InetAddress;I)V");
CHECK_NULL(isaCtrID);
isaCls = (*env)->NewGlobalRef(env, c);
CHECK_NULL(isaCls);
(*env)->DeleteLocalRef(env, c);
}
}
jobject SockAddrToInetSocketAddress(JNIEnv *env, SOCKETADDRESS *sap) {
int port = 0;
jobject ia = NET_SockaddrToInetAddress(env, sap, &port);
if (ia == NULL)
return NULL;
if (isaCls == 0) {
initializeISA(env);
CHECK_NULL_RETURN(isaCls, NULL);
}
return (*env)->NewObject(env, isaCls, isaCtrID, ia, port);
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: getLocalAddresses0
* Signature: (I)[Ljava/net/SocketAddress;
*/
JNIEXPORT jobjectArray JNICALL Java_sun_nio_ch_sctp_SctpNet_getLocalAddresses0
(JNIEnv *env, jclass klass, jint fd)
{
void *addr_buf, *laddr;
int i, addrCount;
jobjectArray isaa;
#ifdef __solaris__
if ((addrCount = nio_sctp_getladdrs(fd, 0, (void **)&addr_buf)) == -1) {
#else /* __linux__ */
if ((addrCount = nio_sctp_getladdrs(fd, 0, (struct sockaddr **)&addr_buf)) == -1) {
#endif
handleSocketError(env, errno);
return NULL;
}
if (addrCount < 1)
return NULL;
if (isaCls == 0) {
initializeISA(env);
CHECK_NULL_RETURN(isaCls, NULL);
}
isaa = (*env)->NewObjectArray(env, addrCount, isaCls, NULL);
if (isaa == NULL) {
nio_sctp_freeladdrs(addr_buf);
return NULL;
}
laddr = addr_buf;
for (i = 0; i < addrCount; i++) {
int port = 0;
jobject ia, isa = NULL;
ia = NET_SockaddrToInetAddress(env, (SOCKETADDRESS *)addr_buf, &port);
if (ia != NULL)
isa = (*env)->NewObject(env, isaCls, isaCtrID, ia, port);
if (isa == NULL)
break;
(*env)->SetObjectArrayElement(env, isaa, i, isa);
if (((struct sockaddr *)addr_buf)->sa_family == AF_INET)
addr_buf = ((struct sockaddr_in *)addr_buf) + 1;
else
addr_buf = ((struct sockaddr_in6 *)addr_buf) + 1;
}
nio_sctp_freeladdrs(laddr);
return isaa;
}
jobjectArray getRemoteAddresses(JNIEnv *env, jint fd, sctp_assoc_t id) {
void *addr_buf, *paddr;
int i, addrCount;
jobjectArray isaa;
#if __solaris__
if ((addrCount = nio_sctp_getpaddrs(fd, id, (void **)&addr_buf)) == -1) {
#else /* __linux__ */
if ((addrCount = nio_sctp_getpaddrs(fd, id, (struct sockaddr **)&addr_buf)) == -1) {
#endif
handleSocketError(env, errno);
return NULL;
}
if (addrCount < 1)
return NULL;
if (isaCls == 0) {
initializeISA(env);
CHECK_NULL_RETURN(isaCls, NULL);
}
isaa = (*env)->NewObjectArray(env, addrCount, isaCls, NULL);
if (isaa == NULL) {
nio_sctp_freepaddrs(addr_buf);
return NULL;
}
paddr = addr_buf;
for (i = 0; i < addrCount; i++) {
int port = 0;
jobject ia, isa = NULL;
ia = NET_SockaddrToInetAddress(env, (SOCKETADDRESS *)addr_buf, &port);
if (ia != NULL)
isa = (*env)->NewObject(env, isaCls, isaCtrID, ia, port);
if (isa == NULL)
break;
(*env)->SetObjectArrayElement(env, isaa, i, isa);
if (((struct sockaddr *)addr_buf)->sa_family == AF_INET)
addr_buf = ((struct sockaddr_in *)addr_buf) + 1;
else
addr_buf = ((struct sockaddr_in6 *)addr_buf) + 1;
}
nio_sctp_freepaddrs(paddr);
return isaa;
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: getRemoteAddresses0
* Signature: (II)[Ljava/net/SocketAddress;
*/
JNIEXPORT jobjectArray JNICALL Java_sun_nio_ch_sctp_SctpNet_getRemoteAddresses0
(JNIEnv *env, jclass klass, jint fd, jint assocId) {
return getRemoteAddresses(env, fd, assocId);
}
/* Map the Java level option to the native level */
int mapSocketOption
(jint cmd, int *level, int *optname) {
static struct {
jint cmd;
int level;
int optname;
} const opts[] = {
{ sun_nio_ch_sctp_SctpStdSocketOption_SCTP_DISABLE_FRAGMENTS, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS },
{ sun_nio_ch_sctp_SctpStdSocketOption_SCTP_EXPLICIT_COMPLETE, IPPROTO_SCTP, SCTP_EXPLICIT_EOR },
{ sun_nio_ch_sctp_SctpStdSocketOption_SCTP_FRAGMENT_INTERLEAVE, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE },
{ sun_nio_ch_sctp_SctpStdSocketOption_SCTP_NODELAY, IPPROTO_SCTP, SCTP_NODELAY },
{ sun_nio_ch_sctp_SctpStdSocketOption_SO_SNDBUF, SOL_SOCKET, SO_SNDBUF },
{ sun_nio_ch_sctp_SctpStdSocketOption_SO_RCVBUF, SOL_SOCKET, SO_RCVBUF },
{ sun_nio_ch_sctp_SctpStdSocketOption_SO_LINGER, SOL_SOCKET, SO_LINGER } };
int i;
for (i=0; i<(int)(sizeof(opts) / sizeof(opts[0])); i++) {
if (cmd == opts[i].cmd) {
*level = opts[i].level;
*optname = opts[i].optname;
return 0;
}
}
/* not found */
return -1;
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: setIntOption0
* Signature: (III)V
*/
JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_setIntOption0
(JNIEnv *env, jclass klass, jint fd, jint opt, int arg) {
int klevel, kopt;
int result;
struct linger linger;
void *parg;
int arglen;
if (mapSocketOption(opt, &klevel, &kopt) < 0) {
JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
"Unsupported socket option");
return;
}
if (opt == sun_nio_ch_sctp_SctpStdSocketOption_SO_LINGER) {
parg = (void *)&linger;
arglen = sizeof(linger);
if (arg >= 0) {
linger.l_onoff = 1;
linger.l_linger = arg;
} else {
linger.l_onoff = 0;
linger.l_linger = 0;
}
} else {
parg = (void *)&arg;
arglen = sizeof(arg);
}
if (NET_SetSockOpt(fd, klevel, kopt, parg, arglen) < 0) {
JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
"sun_nio_ch_sctp_SctpNet.setIntOption0");
}
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: getIntOption0
* Signature: (II)I
*/
JNIEXPORT int JNICALL Java_sun_nio_ch_sctp_SctpNet_getIntOption0
(JNIEnv *env, jclass klass, jint fd, jint opt) {
int klevel, kopt;
int result;
struct linger linger;
void *arg;
int arglen;
memset((char *) &linger, 0, sizeof(linger));
if (mapSocketOption(opt, &klevel, &kopt) < 0) {
JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
"Unsupported socket option");
return -1;
}
if (opt == sun_nio_ch_sctp_SctpStdSocketOption_SO_LINGER) {
arg = (void *)&linger;
arglen = sizeof(linger);
} else {
arg = (void *)&result;
arglen = sizeof(result);
}
if (NET_GetSockOpt(fd, klevel, kopt, arg, &arglen) < 0) {
JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
"sun.nio.ch.Net.getIntOption");
return -1;
}
if (opt == sun_nio_ch_sctp_SctpStdSocketOption_SO_LINGER)
return linger.l_onoff ? linger.l_linger : -1;
else
return result;
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: getPrimAddrOption0
* Signature: (II)Ljava/net/SocketAddress;
*/
JNIEXPORT jobject JNICALL Java_sun_nio_ch_sctp_SctpNet_getPrimAddrOption0
(JNIEnv *env, jclass klass, jint fd, jint assocId) {
struct sctp_setprim prim;
unsigned int prim_len = sizeof(prim);
prim.ssp_assoc_id = assocId;
if (getsockopt(fd, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &prim, &prim_len) < 0) {
JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
"sun.nio.ch.SctpNet.getPrimAddrOption0");
return NULL;
}
return SockAddrToInetSocketAddress(env, (SOCKETADDRESS *)&prim.ssp_addr);
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: setPrimAddrOption0
* Signature: (IILjava/net/InetAddress;I)V
*/
JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_setPrimAddrOption0
(JNIEnv *env, jclass klass, jint fd, jint assocId, jobject iaObj, jint port) {
struct sctp_setprim prim;
if (NET_InetAddressToSockaddr(env, iaObj, port,
(SOCKETADDRESS *)&prim.ssp_addr,
NULL, JNI_TRUE) != 0) {
return;
}
prim.ssp_assoc_id = assocId;
if (setsockopt(fd, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &prim, sizeof(prim)) < 0) {
JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
"sun.nio.ch.SctpNet.setPrimAddrOption0");
}
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: setPeerPrimAddrOption0
* Signature: (IILjava/net/InetAddress;I)V
*/
JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_setPeerPrimAddrOption0
(JNIEnv *env, jclass klass, jint fd, jint assocId,
jobject iaObj, jint port, jboolean preferIPv6) {
struct sctp_setpeerprim prim;
if (NET_InetAddressToSockaddr(env, iaObj, port,
(SOCKETADDRESS *)&prim.sspp_addr,
NULL, preferIPv6) != 0) {
return;
}
prim.sspp_assoc_id = assocId;
if (setsockopt(fd, IPPROTO_SCTP, SCTP_SET_PEER_PRIMARY_ADDR, &prim,
sizeof(prim)) < 0) {
JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
"sun.nio.ch.SctpNet.setPeerPrimAddrOption0");
}
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: getInitMsgOption0
* Signature: (I[I)V
*/
JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_getInitMsgOption0
(JNIEnv *env, jclass klass, jint fd, jintArray retVal) {
struct sctp_initmsg sctp_initmsg;
unsigned int sim_len = sizeof(sctp_initmsg);
int vals[2];
if (getsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &sctp_initmsg,
&sim_len) < 0) {
JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
"sun.nio.ch.SctpNet.getInitMsgOption0");
return;
}
vals[0] = sctp_initmsg.sinit_max_instreams;
vals[1] = sctp_initmsg.sinit_num_ostreams;
(*env)->SetIntArrayRegion(env, retVal, 0, 2, vals);
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: setInitMsgOption0
* Signature: (III)V
*/
JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_setInitMsgOption0
(JNIEnv *env, jclass klass, jint fd, jint inArg, jint outArg) {
struct sctp_initmsg sctp_initmsg;
sctp_initmsg.sinit_max_instreams = (unsigned int)inArg;
sctp_initmsg.sinit_num_ostreams = (unsigned int)outArg;
sctp_initmsg.sinit_max_attempts = 0; // default
sctp_initmsg.sinit_max_init_timeo = 0; // default
if (setsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &sctp_initmsg,
sizeof(sctp_initmsg)) < 0) {
JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
"sun.nio.ch.SctpNet.setInitMsgOption0");
}
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: shutdown0
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpNet_shutdown0
(JNIEnv *env, jclass klass, jint fd, jint assocId) {
int rv;
struct msghdr msg[1];
struct iovec iov[1];
int cbuf_size = CMSG_SPACE(sizeof (struct sctp_sndrcvinfo));
char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))];
struct cmsghdr* cmsg;
struct sctp_sndrcvinfo *sri;
/* SctpSocketChannel */
if (assocId < 0) {
shutdown(fd, SHUT_WR);
return;
}
memset(msg, 0, sizeof (*msg));
memset(cbuf, 0, cbuf_size);
msg->msg_name = NULL;
msg->msg_namelen = 0;
iov->iov_base = NULL;
iov->iov_len = 0;
msg->msg_iov = iov;
msg->msg_iovlen = 1;
msg->msg_control = cbuf;
msg->msg_controllen = cbuf_size;
msg->msg_flags = 0;
cmsg = CMSG_FIRSTHDR(msg);
cmsg->cmsg_level = IPPROTO_SCTP;
cmsg->cmsg_type = SCTP_SNDRCV;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
/* Initialize the payload: */
sri = (struct sctp_sndrcvinfo*) CMSG_DATA(cmsg);
memset(sri, 0, sizeof (*sri));
if (assocId > 0) {
sri->sinfo_assoc_id = assocId;
}
sri->sinfo_flags = sri->sinfo_flags | SCTP_EOF;
/* Sum of the length of all control messages in the buffer. */
msg->msg_controllen = cmsg->cmsg_len;
if ((rv = sendmsg(fd, msg, 0)) < 0) {
handleSocketError(env, errno);
}
}
/*
* Class: sun_nio_ch_sctp_SctpNet
* Method: branch
* Signature: (II)I
*/
JNIEXPORT int JNICALL Java_sun_nio_ch_sctp_SctpNet_branch0
(JNIEnv *env, jclass klass, jint fd, jint assocId) {
int newfd = 0;
if ((newfd = nio_sctp_peeloff(fd, assocId)) < 0) {
handleSocketError(env, errno);
}
return newfd;
}

View file

@ -0,0 +1,53 @@
/*
* 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.
*/
#include "sun_nio_ch_sctp_SctpServerChannelImpl.h"
extern void Java_sun_nio_ch_ServerSocketChannelImpl_initIDs(JNIEnv* env,
jclass c);
extern jint Java_sun_nio_ch_ServerSocketChannelImpl_accept0(JNIEnv* env,
jobject this, jobject ssfdo, jobject newfdo, jobjectArray isaa);
/*
* Class: sun_nio_ch_sctp_SctpServerChannelImpl
* Method: initIDs
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_sun_nio_ch_sctp_SctpServerChannelImpl_initIDs
(JNIEnv* env, jclass c) {
Java_sun_nio_ch_ServerSocketChannelImpl_initIDs(env, c);
}
/*
* Class: sun_nio_ch_sctp_SctpServerChannelImpl
* Method: accept0
* Signature: (Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;[Ljava/net/InetSocketAddress;)I
*/
JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpServerChannelImpl_accept0
(JNIEnv* env, jobject this, jobject ssfdo, jobject newfdo, jobjectArray isaa) {
return Java_sun_nio_ch_ServerSocketChannelImpl_accept0(env, this,
ssfdo, newfdo, isaa);
}

View file

@ -0,0 +1,150 @@
/*
* 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.net.SocketAddress;
import java.net.InetAddress;
import java.io.IOException;
import java.util.Set;
import java.nio.ByteBuffer;
import java.nio.channels.spi.SelectorProvider;
import com.sun.nio.sctp.Association;
import com.sun.nio.sctp.MessageInfo;
import com.sun.nio.sctp.NotificationHandler;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.SctpSocketOption;
/**
* Unimplemented.
*/
public class SctpChannelImpl extends SctpChannel
{
private static final String message = "SCTP not supported on this platform";
public SctpChannelImpl(SelectorProvider provider) {
super(provider);
throw new UnsupportedOperationException(message);
}
@Override
public Association association() {
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel bind(SocketAddress local)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel bindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel unbindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public boolean connect(SocketAddress remote) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public boolean connect(SocketAddress remote, int maxOutStreams,
int maxInStreams) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public boolean isConnectionPending() {
throw new UnsupportedOperationException(message);
}
@Override
public boolean finishConnect() throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SocketAddress> getAllLocalAddresses()
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SocketAddress> getRemoteAddresses()
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel shutdown() throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> T getOption(SctpSocketOption<T> name)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> SctpChannel setOption(SctpSocketOption<T> name, T value)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SctpSocketOption<?>> supportedOptions() {
throw new UnsupportedOperationException(message);
}
@Override
public <T> MessageInfo receive(ByteBuffer dst, T attachment,
NotificationHandler<T> handler) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public int send(ByteBuffer src, MessageInfo messageInfo)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
protected void implConfigureBlocking(boolean block) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public void implCloseSelectableChannel() throws IOException {
throw new UnsupportedOperationException(message);
}
}

View file

@ -0,0 +1,137 @@
/*
* 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.net.SocketAddress;
import java.net.InetAddress;
import java.io.IOException;
import java.util.Set;
import java.nio.ByteBuffer;
import java.nio.channels.spi.SelectorProvider;
import com.sun.nio.sctp.Association;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.MessageInfo;
import com.sun.nio.sctp.NotificationHandler;
import com.sun.nio.sctp.SctpMultiChannel;
import com.sun.nio.sctp.SctpSocketOption;
/**
* Unimplemented.
*/
public class SctpMultiChannelImpl extends SctpMultiChannel
{
private static final String message = "SCTP not supported on this platform";
public SctpMultiChannelImpl(SelectorProvider provider) {
super(provider);
throw new UnsupportedOperationException(message);
}
@Override
public Set<Association> associations() {
throw new UnsupportedOperationException(message);
}
@Override
public SctpMultiChannel bind(SocketAddress local,
int backlog) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpMultiChannel bindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpMultiChannel unbindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SocketAddress> getAllLocalAddresses()
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SocketAddress> getRemoteAddresses
(Association association) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpMultiChannel shutdown(Association association)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> T getOption(SctpSocketOption<T> name,
Association association) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> SctpMultiChannel setOption(SctpSocketOption<T> name,
T value, Association association) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SctpSocketOption<?>> supportedOptions() {
throw new UnsupportedOperationException(message);
}
@Override
public <T> MessageInfo receive(ByteBuffer buffer, T attachment,
NotificationHandler<T> handler) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public int send(ByteBuffer buffer, MessageInfo messageInfo)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel branch(Association association)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
protected void implConfigureBlocking(boolean block) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public void implCloseSelectableChannel() throws IOException {
throw new UnsupportedOperationException(message);
}
}

View file

@ -0,0 +1,102 @@
/*
* 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.net.SocketAddress;
import java.net.InetAddress;
import java.io.IOException;
import java.util.Set;
import java.nio.channels.spi.SelectorProvider;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.SctpServerChannel;
import com.sun.nio.sctp.SctpSocketOption;
/**
* Unimplemented.
*/
public class SctpServerChannelImpl extends SctpServerChannel
{
private static final String message = "SCTP not supported on this platform";
public SctpServerChannelImpl(SelectorProvider provider) {
super(provider);
throw new UnsupportedOperationException(message);
}
@Override
public SctpChannel accept() throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpServerChannel bind(SocketAddress local,
int backlog) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpServerChannel bindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public SctpServerChannel unbindAddress(InetAddress address)
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SocketAddress> getAllLocalAddresses()
throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> T getOption(SctpSocketOption<T> name) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public <T> SctpServerChannel setOption(SctpSocketOption<T> name,
T value) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public Set<SctpSocketOption<?>> supportedOptions() {
throw new UnsupportedOperationException(message);
}
@Override
protected void implConfigureBlocking(boolean block) throws IOException {
throw new UnsupportedOperationException(message);
}
@Override
public void implCloseSelectableChannel() throws IOException {
throw new UnsupportedOperationException(message);
}
}