Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpNet.java
32300 views
/*1* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package sun.nio.ch.sctp;2526import java.io.FileDescriptor;27import java.io.IOException;28import java.net.InetAddress;29import java.net.InetSocketAddress;30import java.net.SocketAddress;31import java.nio.channels.AlreadyBoundException;32import java.util.Set;33import java.util.HashSet;34import java.security.AccessController;35import sun.security.action.GetPropertyAction;36import sun.nio.ch.IOUtil;37import sun.nio.ch.Net;38import com.sun.nio.sctp.SctpSocketOption;39import static com.sun.nio.sctp.SctpStandardSocketOptions.*;4041public class SctpNet {42static final String osName = AccessController.doPrivileged(43new GetPropertyAction("os.name"));4445/* -- Miscellaneous SCTP utilities -- */4647private static boolean IPv4MappedAddresses() {48if ("SunOS".equals(osName)) {49/* Solaris supports IPv4Mapped Addresses with bindx */50return true;51} /* else { //other OS/implementations */5253/* lksctp/linux requires Ipv4 addresses */54return false;55}5657static boolean throwAlreadyBoundException() throws IOException {58throw new AlreadyBoundException();59}6061static void listen(int fd, int backlog) throws IOException {62listen0(fd, backlog);63}6465static int connect(int fd, InetAddress remote, int remotePort)66throws IOException {67return connect0(fd, remote, remotePort);68}6970static void close(int fd) throws IOException {71close0(fd);72}7374static void preClose(int fd) throws IOException {75preClose0(fd);76}7778/**79* @param oneToOne80* if {@code true} returns a one-to-one sctp socket, otherwise81* returns a one-to-many sctp socket82*/83static FileDescriptor socket(boolean oneToOne) throws IOException {84int nativefd = socket0(oneToOne);85return IOUtil.newFD(nativefd);86}8788static void bindx(int fd, InetAddress[] addrs, int port, boolean add)89throws IOException {90bindx(fd, addrs, port, addrs.length, add,91IPv4MappedAddresses());92}9394static Set<SocketAddress> getLocalAddresses(int fd)95throws IOException {96Set<SocketAddress> set = null;97SocketAddress[] saa = getLocalAddresses0(fd);9899if (saa != null) {100set = getRevealedLocalAddressSet(saa);101}102103return set;104}105106private static Set<SocketAddress> getRevealedLocalAddressSet(107SocketAddress[] saa)108{109SecurityManager sm = System.getSecurityManager();110Set<SocketAddress> set = new HashSet<>(saa.length);111for (SocketAddress sa : saa) {112set.add(getRevealedLocalAddress(sa, sm));113}114return set;115}116117private static SocketAddress getRevealedLocalAddress(SocketAddress sa,118SecurityManager sm)119{120if (sm == null || sa == null)121return sa;122InetSocketAddress ia = (InetSocketAddress)sa;123try{124sm.checkConnect(ia.getAddress().getHostAddress(), -1);125// Security check passed126} catch (SecurityException e) {127// Return loopback address128return new InetSocketAddress(InetAddress.getLoopbackAddress(),129ia.getPort());130}131return sa;132}133134static Set<SocketAddress> getRemoteAddresses(int fd, int assocId)135throws IOException {136HashSet<SocketAddress> set = null;137SocketAddress[] saa = getRemoteAddresses0(fd, assocId);138139if (saa != null) {140set = new HashSet<SocketAddress>(saa.length);141for (SocketAddress sa : saa)142set.add(sa);143}144145return set;146}147148static <T> void setSocketOption(int fd,149SctpSocketOption<T> name,150T value,151int assocId)152throws IOException {153if (value == null)154throw new IllegalArgumentException("Invalid option value");155156if (name.equals(SCTP_INIT_MAXSTREAMS)) {157InitMaxStreams maxStreamValue = (InitMaxStreams)value;158SctpNet.setInitMsgOption0(fd,159maxStreamValue.maxInStreams(), maxStreamValue.maxOutStreams());160} else if (name.equals(SCTP_PRIMARY_ADDR) ||161name.equals(SCTP_SET_PEER_PRIMARY_ADDR)) {162163SocketAddress addr = (SocketAddress) value;164if (addr == null)165throw new IllegalArgumentException("Invalid option value");166167Net.checkAddress(addr);168InetSocketAddress netAddr = (InetSocketAddress)addr;169170if (name.equals(SCTP_PRIMARY_ADDR)) {171setPrimAddrOption0(fd,172assocId,173netAddr.getAddress(),174netAddr.getPort());175} else {176setPeerPrimAddrOption0(fd,177assocId,178netAddr.getAddress(),179netAddr.getPort(),180IPv4MappedAddresses());181}182} else if (name.equals(SCTP_DISABLE_FRAGMENTS) ||183name.equals(SCTP_EXPLICIT_COMPLETE) ||184name.equals(SCTP_FRAGMENT_INTERLEAVE) ||185name.equals(SCTP_NODELAY) ||186name.equals(SO_SNDBUF) ||187name.equals(SO_RCVBUF) ||188name.equals(SO_LINGER)) {189setIntOption(fd, name, value);190} else {191throw new AssertionError("Unknown socket option");192}193}194195static Object getSocketOption(int fd, SctpSocketOption<?> name, int assocId)196throws IOException {197if (name.equals(SCTP_SET_PEER_PRIMARY_ADDR)) {198throw new IllegalArgumentException(199"SCTP_SET_PEER_PRIMARY_ADDR cannot be retrieved");200} else if (name.equals(SCTP_INIT_MAXSTREAMS)) {201/* container for holding maxIn/Out streams */202int[] values = new int[2];203SctpNet.getInitMsgOption0(fd, values);204return InitMaxStreams.create(values[0], values[1]);205} else if (name.equals(SCTP_PRIMARY_ADDR)) {206return getPrimAddrOption0(fd, assocId);207} else if (name.equals(SCTP_DISABLE_FRAGMENTS) ||208name.equals(SCTP_EXPLICIT_COMPLETE) ||209name.equals(SCTP_FRAGMENT_INTERLEAVE) ||210name.equals(SCTP_NODELAY) ||211name.equals(SO_SNDBUF) ||212name.equals(SO_RCVBUF) ||213name.equals(SO_LINGER)) {214return getIntOption(fd, name);215} else {216throw new AssertionError("Unknown socket option");217}218}219220static void setIntOption(int fd, SctpSocketOption<?> name, Object value)221throws IOException {222if (value == null)223throw new IllegalArgumentException("Invalid option value");224225Class<?> type = name.type();226if (type != Integer.class && type != Boolean.class)227throw new AssertionError("Should not reach here");228229if (name == SO_RCVBUF ||230name == SO_SNDBUF)231{232int i = ((Integer)value).intValue();233if (i < 0)234throw new IllegalArgumentException(235"Invalid send/receive buffer size");236} else if (name == SO_LINGER) {237int i = ((Integer)value).intValue();238if (i < 0)239value = Integer.valueOf(-1);240if (i > 65535)241value = Integer.valueOf(65535);242} else if (name.equals(SCTP_FRAGMENT_INTERLEAVE)) {243int i = ((Integer)value).intValue();244if (i < 0 || i > 2)245throw new IllegalArgumentException(246"Invalid value for SCTP_FRAGMENT_INTERLEAVE");247}248249int arg;250if (type == Integer.class) {251arg = ((Integer)value).intValue();252} else {253boolean b = ((Boolean)value).booleanValue();254arg = (b) ? 1 : 0;255}256257setIntOption0(fd, ((SctpStdSocketOption)name).constValue(), arg);258}259260static Object getIntOption(int fd, SctpSocketOption<?> name)261throws IOException {262Class<?> type = name.type();263264if (type != Integer.class && type != Boolean.class)265throw new AssertionError("Should not reach here");266267if (!(name instanceof SctpStdSocketOption))268throw new AssertionError("Should not reach here");269270int value = getIntOption0(fd,271((SctpStdSocketOption)name).constValue());272273if (type == Integer.class) {274return Integer.valueOf(value);275} else {276return (value == 0) ? Boolean.FALSE : Boolean.TRUE;277}278}279280static void shutdown(int fd, int assocId)281throws IOException {282shutdown0(fd, assocId);283}284285static FileDescriptor branch(int fd, int assocId) throws IOException {286int nativefd = branch0(fd, assocId);287return IOUtil.newFD(nativefd);288}289290/* Native Methods */291static native int socket0(boolean oneToOne) throws IOException;292293static native void listen0(int fd, int backlog) throws IOException;294295static native int connect0(int fd, InetAddress remote, int remotePort)296throws IOException;297298static native void close0(int fd) throws IOException;299300static native void preClose0(int fd) throws IOException;301302static native void bindx(int fd, InetAddress[] addrs, int port, int length,303boolean add, boolean preferIPv6) throws IOException;304305static native int getIntOption0(int fd, int opt) throws IOException;306307static native void setIntOption0(int fd, int opt, int arg)308throws IOException;309310static native SocketAddress[] getLocalAddresses0(int fd) throws IOException;311312static native SocketAddress[] getRemoteAddresses0(int fd, int assocId)313throws IOException;314315static native int branch0(int fd, int assocId) throws IOException;316317static native void setPrimAddrOption0(int fd, int assocId, InetAddress ia,318int port) throws IOException;319320static native void setPeerPrimAddrOption0(int fd, int assocId,321InetAddress ia, int port, boolean preferIPv6) throws IOException;322323static native SocketAddress getPrimAddrOption0(int fd, int assocId)324throws IOException;325326/* retVals [0] maxInStreams, [1] maxOutStreams */327static native void getInitMsgOption0(int fd, int[] retVals) throws IOException;328329static native void setInitMsgOption0(int fd, int arg1, int arg2)330throws IOException;331332static native void shutdown0(int fd, int assocId);333334static native void init();335336static {337init();338}339}340341342343