1 /*
   2  * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.nio.ch;
  27 
  28 import java.io.FileDescriptor;
  29 import java.io.IOException;
  30 import java.net.Inet4Address;
  31 import java.net.Inet6Address;
  32 import java.net.InetAddress;
  33 import java.net.InetSocketAddress;
  34 import java.net.NetworkInterface;
  35 import java.net.ProtocolFamily;
  36 import java.net.SocketAddress;
  37 import java.net.SocketException;
  38 import java.net.SocketOption;
  39 import java.net.StandardProtocolFamily;
  40 import java.net.StandardSocketOptions;
  41 import java.net.UnknownHostException;
  42 import java.nio.channels.AlreadyBoundException;
  43 import java.nio.channels.ClosedChannelException;
  44 import java.nio.channels.NotYetBoundException;
  45 import java.nio.channels.NotYetConnectedException;
  46 import java.nio.channels.UnresolvedAddressException;
  47 import java.nio.channels.UnsupportedAddressTypeException;
  48 import java.security.AccessController;
  49 import java.security.PrivilegedAction;
  50 import java.util.Enumeration;
  51 
  52 import sun.net.ext.ExtendedSocketOptions;
  53 import sun.net.util.IPAddressUtil;
  54 import sun.security.action.GetPropertyAction;
  55 
  56 public class Net {
  57 
  58     private Net() { }
  59 
  60     // unspecified protocol family
  61     static final ProtocolFamily UNSPEC = new ProtocolFamily() {
  62         public String name() {
  63             return "UNSPEC";
  64         }
  65     };
  66 
  67     // set to true if exclusive binding is on for Windows
  68     private static final boolean exclusiveBind;
  69 
  70     // set to true if the fast tcp loopback should be enabled on Windows
  71     private static final boolean fastLoopback;
  72 
  73     // -- Miscellaneous utilities --
  74 
  75     private static volatile boolean checkedIPv6;
  76     private static volatile boolean isIPv6Available;
  77     private static volatile boolean checkedReusePort;
  78     private static volatile boolean isReusePortAvailable;
  79 
  80     /**
  81      * Tells whether dual-IPv4/IPv6 sockets should be used.
  82      */
  83     static boolean isIPv6Available() {
  84         if (!checkedIPv6) {
  85             isIPv6Available = isIPv6Available0();
  86             checkedIPv6 = true;
  87         }
  88         return isIPv6Available;
  89     }
  90 
  91     /**
  92      * Tells whether SO_REUSEPORT is supported.
  93      */
  94     static boolean isReusePortAvailable() {
  95         if (!checkedReusePort) {
  96             isReusePortAvailable = isReusePortAvailable0();
  97             checkedReusePort = true;
  98         }
  99         return isReusePortAvailable;
 100     }
 101 
 102     /**
 103      * Returns true if exclusive binding is on
 104      */
 105     static boolean useExclusiveBind() {
 106         return exclusiveBind;
 107     }
 108 
 109     /**
 110      * Tells whether IPv6 sockets can join IPv4 multicast groups
 111      */
 112     static boolean canIPv6SocketJoinIPv4Group() {
 113         return canIPv6SocketJoinIPv4Group0();
 114     }
 115 
 116     /**
 117      * Tells whether {@link #join6} can be used to join an IPv4
 118      * multicast group (IPv4 group as IPv4-mapped IPv6 address)
 119      */
 120     static boolean canJoin6WithIPv4Group() {
 121         return canJoin6WithIPv4Group0();
 122     }
 123 
 124     public static InetSocketAddress checkAddress(SocketAddress sa) {
 125         if (sa == null)
 126             throw new NullPointerException();
 127         if (!(sa instanceof InetSocketAddress))
 128             throw new UnsupportedAddressTypeException(); // ## needs arg
 129         InetSocketAddress isa = (InetSocketAddress)sa;
 130         if (isa.isUnresolved())
 131             throw new UnresolvedAddressException(); // ## needs arg
 132         InetAddress addr = isa.getAddress();
 133         if (!(addr instanceof Inet4Address || addr instanceof Inet6Address))
 134             throw new IllegalArgumentException("Invalid address type");
 135         return isa;
 136     }
 137 
 138     static InetSocketAddress checkAddress(SocketAddress sa, ProtocolFamily family) {
 139         InetSocketAddress isa = checkAddress(sa);
 140         if (family == StandardProtocolFamily.INET) {
 141             InetAddress addr = isa.getAddress();
 142             if (!(addr instanceof Inet4Address))
 143                 throw new UnsupportedAddressTypeException();
 144         }
 145         return isa;
 146     }
 147 
 148     static InetSocketAddress asInetSocketAddress(SocketAddress sa) {
 149         if (!(sa instanceof InetSocketAddress))
 150             throw new UnsupportedAddressTypeException();
 151         return (InetSocketAddress)sa;
 152     }
 153 
 154     static void translateToSocketException(Exception x)
 155         throws SocketException
 156     {
 157         if (x instanceof SocketException)
 158             throw (SocketException)x;
 159         Exception nx = x;
 160         if (x instanceof ClosedChannelException)
 161             nx = new SocketException("Socket is closed");
 162         else if (x instanceof NotYetConnectedException)
 163             nx = new SocketException("Socket is not connected");
 164         else if (x instanceof AlreadyBoundException)
 165             nx = new SocketException("Already bound");
 166         else if (x instanceof NotYetBoundException)
 167             nx = new SocketException("Socket is not bound yet");
 168         else if (x instanceof UnsupportedAddressTypeException)
 169             nx = new SocketException("Unsupported address type");
 170         else if (x instanceof UnresolvedAddressException) {
 171             nx = new SocketException("Unresolved address");
 172         }
 173         if (nx != x)
 174             nx.initCause(x);
 175 
 176         if (nx instanceof SocketException)
 177             throw (SocketException)nx;
 178         else if (nx instanceof RuntimeException)
 179             throw (RuntimeException)nx;
 180         else
 181             throw new Error("Untranslated exception", nx);
 182     }
 183 
 184     static void translateException(Exception x,
 185                                    boolean unknownHostForUnresolved)
 186         throws IOException
 187     {
 188         if (x instanceof IOException)
 189             throw (IOException)x;
 190         // Throw UnknownHostException from here since it cannot
 191         // be thrown as a SocketException
 192         if (unknownHostForUnresolved &&
 193             (x instanceof UnresolvedAddressException))
 194         {
 195              throw new UnknownHostException();
 196         }
 197         translateToSocketException(x);
 198     }
 199 
 200     static void translateException(Exception x)
 201         throws IOException
 202     {
 203         translateException(x, false);
 204     }
 205 
 206     /**
 207      * Returns the local address after performing a SecurityManager#checkConnect.
 208      */
 209     static InetSocketAddress getRevealedLocalAddress(InetSocketAddress addr) {
 210         SecurityManager sm = System.getSecurityManager();
 211         if (addr == null || sm == null)
 212             return addr;
 213 
 214         try{
 215             sm.checkConnect(addr.getAddress().getHostAddress(), -1);
 216             // Security check passed
 217         } catch (SecurityException e) {
 218             // Return loopback address only if security check fails
 219             addr = getLoopbackAddress(addr.getPort());
 220         }
 221         return addr;
 222     }
 223 
 224     static String getRevealedLocalAddressAsString(InetSocketAddress addr) {
 225         return System.getSecurityManager() == null ? addr.toString() :
 226                 getLoopbackAddress(addr.getPort()).toString();
 227     }
 228 
 229     private static InetSocketAddress getLoopbackAddress(int port) {
 230         return new InetSocketAddress(InetAddress.getLoopbackAddress(),
 231                                      port);
 232     }
 233 
 234     /**
 235      * Returns any IPv4 address of the given network interface, or
 236      * null if the interface does not have any IPv4 addresses.
 237      */
 238     static Inet4Address anyInet4Address(final NetworkInterface interf) {
 239         return AccessController.doPrivileged(new PrivilegedAction<Inet4Address>() {
 240             public Inet4Address run() {
 241                 Enumeration<InetAddress> addrs = interf.getInetAddresses();
 242                 while (addrs.hasMoreElements()) {
 243                     InetAddress addr = addrs.nextElement();
 244                     if (addr instanceof Inet4Address) {
 245                         return (Inet4Address)addr;
 246                     }
 247                 }
 248                 return null;
 249             }
 250         });
 251     }
 252 
 253     /**
 254      * Returns an IPv4 address as an int.
 255      */
 256     static int inet4AsInt(InetAddress ia) {
 257         if (ia instanceof Inet4Address) {
 258             byte[] addr = ia.getAddress();
 259             int address  = addr[3] & 0xFF;
 260             address |= ((addr[2] << 8) & 0xFF00);
 261             address |= ((addr[1] << 16) & 0xFF0000);
 262             address |= ((addr[0] << 24) & 0xFF000000);
 263             return address;
 264         }
 265         throw new AssertionError("Should not reach here");
 266     }
 267 
 268     /**
 269      * Returns an InetAddress from the given IPv4 address
 270      * represented as an int.
 271      */
 272     static InetAddress inet4FromInt(int address) {
 273         byte[] addr = new byte[4];
 274         addr[0] = (byte) ((address >>> 24) & 0xFF);
 275         addr[1] = (byte) ((address >>> 16) & 0xFF);
 276         addr[2] = (byte) ((address >>> 8) & 0xFF);
 277         addr[3] = (byte) (address & 0xFF);
 278         try {
 279             return InetAddress.getByAddress(addr);
 280         } catch (UnknownHostException uhe) {
 281             throw new AssertionError("Should not reach here");
 282         }
 283     }
 284 
 285     /**
 286      * Returns an IPv6 address as a byte array
 287      */
 288     static byte[] inet6AsByteArray(InetAddress ia) {
 289         if (ia instanceof Inet6Address) {
 290             return ia.getAddress();
 291         }
 292 
 293         // need to construct IPv4-mapped address
 294         if (ia instanceof Inet4Address) {
 295             byte[] ip4address = ia.getAddress();
 296             byte[] address = new byte[16];
 297             address[10] = (byte)0xff;
 298             address[11] = (byte)0xff;
 299             address[12] = ip4address[0];
 300             address[13] = ip4address[1];
 301             address[14] = ip4address[2];
 302             address[15] = ip4address[3];
 303             return address;
 304         }
 305 
 306         throw new AssertionError("Should not reach here");
 307     }
 308 
 309     // -- Socket options
 310 
 311     static final ExtendedSocketOptions extendedOptions =
 312             ExtendedSocketOptions.getInstance();
 313 
 314     static void setSocketOption(FileDescriptor fd, SocketOption<?> name, Object value)
 315         throws IOException
 316     {
 317         setSocketOption(fd, Net.UNSPEC, name, value);
 318     }
 319 
 320     static void setSocketOption(FileDescriptor fd, ProtocolFamily family,
 321                                 SocketOption<?> name, Object value)
 322         throws IOException
 323     {
 324         if (value == null)
 325             throw new IllegalArgumentException("Invalid option value");
 326 
 327         // only simple values supported by this method
 328         Class<?> type = name.type();
 329 
 330         if (extendedOptions.isOptionSupported(name)) {
 331             extendedOptions.setOption(fd, name, value);
 332             return;
 333         }
 334 
 335         if (type != Integer.class && type != Boolean.class)
 336             throw new AssertionError("Should not reach here");
 337 
 338         // special handling
 339         if (name == StandardSocketOptions.SO_RCVBUF ||
 340             name == StandardSocketOptions.SO_SNDBUF)
 341         {
 342             int i = ((Integer)value).intValue();
 343             if (i < 0)
 344                 throw new IllegalArgumentException("Invalid send/receive buffer size");
 345         }
 346         if (name == StandardSocketOptions.SO_LINGER) {
 347             int i = ((Integer)value).intValue();
 348             if (i < 0)
 349                 value = Integer.valueOf(-1);
 350             if (i > 65535)
 351                 value = Integer.valueOf(65535);
 352         }
 353         if (name == StandardSocketOptions.IP_TOS) {
 354             int i = ((Integer)value).intValue();
 355             if (i < 0 || i > 255)
 356                 throw new IllegalArgumentException("Invalid IP_TOS value");
 357         }
 358         if (name == StandardSocketOptions.IP_MULTICAST_TTL) {
 359             int i = ((Integer)value).intValue();
 360             if (i < 0 || i > 255)
 361                 throw new IllegalArgumentException("Invalid TTL/hop value");
 362         }
 363 
 364         // map option name to platform level/name
 365         OptionKey key = SocketOptionRegistry.findOption(name, family);
 366         if (key == null)
 367             throw new AssertionError("Option not found");
 368 
 369         int arg;
 370         if (type == Integer.class) {
 371             arg = ((Integer)value).intValue();
 372         } else {
 373             boolean b = ((Boolean)value).booleanValue();
 374             arg = (b) ? 1 : 0;
 375         }
 376 
 377         boolean mayNeedConversion = (family == UNSPEC);
 378         boolean isIPv6 = (family == StandardProtocolFamily.INET6);
 379         setIntOption0(fd, mayNeedConversion, key.level(), key.name(), arg, isIPv6);
 380     }
 381 
 382     static Object getSocketOption(FileDescriptor fd, SocketOption<?> name)
 383         throws IOException
 384     {
 385         return getSocketOption(fd, Net.UNSPEC, name);
 386     }
 387 
 388     static Object getSocketOption(FileDescriptor fd, ProtocolFamily family, SocketOption<?> name)
 389         throws IOException
 390     {
 391         Class<?> type = name.type();
 392 
 393         if (extendedOptions.isOptionSupported(name)) {
 394             return extendedOptions.getOption(fd, name);
 395         }
 396 
 397         // only simple values supported by this method
 398         if (type != Integer.class && type != Boolean.class)
 399             throw new AssertionError("Should not reach here");
 400 
 401         // map option name to platform level/name
 402         OptionKey key = SocketOptionRegistry.findOption(name, family);
 403         if (key == null)
 404             throw new AssertionError("Option not found");
 405 
 406         boolean mayNeedConversion = (family == UNSPEC);
 407         int value = getIntOption0(fd, mayNeedConversion, key.level(), key.name());
 408 
 409         if (type == Integer.class) {
 410             return Integer.valueOf(value);
 411         } else {
 412             return (value == 0) ? Boolean.FALSE : Boolean.TRUE;
 413         }
 414     }
 415 
 416     public static boolean isFastTcpLoopbackRequested() {
 417         String loopbackProp = GetPropertyAction
 418                 .privilegedGetProperty("jdk.net.useFastTcpLoopback", "false");
 419         return loopbackProp.isEmpty() ? true : Boolean.parseBoolean(loopbackProp);
 420     }
 421 
 422     // -- Socket operations --
 423 
 424     private static native boolean isIPv6Available0();
 425 
 426     private static native boolean isReusePortAvailable0();
 427 
 428     /*
 429      * Returns 1 for Windows and -1 for Solaris/Linux/Mac OS
 430      */
 431     private static native int isExclusiveBindAvailable();
 432 
 433     private static native boolean canIPv6SocketJoinIPv4Group0();
 434 
 435     private static native boolean canJoin6WithIPv4Group0();
 436 
 437     static FileDescriptor socket(boolean stream) throws IOException {
 438         return socket(UNSPEC, stream);
 439     }
 440 
 441     static FileDescriptor socket(ProtocolFamily family, boolean stream) throws IOException {
 442         boolean preferIPv6 = isIPv6Available() &&
 443             (family != StandardProtocolFamily.INET);
 444         return IOUtil.newFD(socket0(preferIPv6, stream, false, fastLoopback));
 445     }
 446 
 447     static FileDescriptor serverSocket(boolean stream) {
 448         return IOUtil.newFD(socket0(isIPv6Available(), stream, true, fastLoopback));
 449     }
 450 
 451     // Due to oddities SO_REUSEADDR on windows reuse is ignored
 452     private static native int socket0(boolean preferIPv6, boolean stream, boolean reuse,
 453                                       boolean fastLoopback);
 454 
 455     public static void bind(FileDescriptor fd, InetAddress addr, int port)
 456         throws IOException
 457     {
 458         bind(UNSPEC, fd, addr, port);
 459     }
 460 
 461     static void bind(ProtocolFamily family, FileDescriptor fd,
 462                      InetAddress addr, int port) throws IOException
 463     {
 464         boolean preferIPv6 = isIPv6Available() &&
 465             (family != StandardProtocolFamily.INET);
 466         if (addr.isLinkLocalAddress()) {
 467             addr = IPAddressUtil.toScopedAddress(addr);
 468         }
 469         bind0(fd, preferIPv6, exclusiveBind, addr, port);
 470     }
 471 
 472     private static native void bind0(FileDescriptor fd, boolean preferIPv6,
 473                                      boolean useExclBind, InetAddress addr,
 474                                      int port)
 475         throws IOException;
 476 
 477     static native void listen(FileDescriptor fd, int backlog) throws IOException;
 478 
 479     static int connect(FileDescriptor fd, InetAddress remote, int remotePort)
 480         throws IOException
 481     {
 482         return connect(UNSPEC, fd, remote, remotePort);
 483     }
 484 
 485     static int connect(ProtocolFamily family, FileDescriptor fd, InetAddress remote, int remotePort)
 486         throws IOException
 487     {
 488         if (remote.isLinkLocalAddress()) {
 489             remote = IPAddressUtil.toScopedAddress(remote);
 490         }
 491         boolean preferIPv6 = isIPv6Available() &&
 492             (family != StandardProtocolFamily.INET);
 493         return connect0(preferIPv6, fd, remote, remotePort);
 494     }
 495 
 496     private static native int connect0(boolean preferIPv6,
 497                                        FileDescriptor fd,
 498                                        InetAddress remote,
 499                                        int remotePort)
 500         throws IOException;
 501 
 502     public static native int accept(FileDescriptor fd,
 503                                     FileDescriptor newfd,
 504                                     InetSocketAddress[] isaa)
 505         throws IOException;
 506 
 507     public static final int SHUT_RD = 0;
 508     public static final int SHUT_WR = 1;
 509     public static final int SHUT_RDWR = 2;
 510 
 511     static native void shutdown(FileDescriptor fd, int how) throws IOException;
 512 
 513     private static native int localPort(FileDescriptor fd)
 514         throws IOException;
 515 
 516     private static native InetAddress localInetAddress(FileDescriptor fd)
 517         throws IOException;
 518 
 519     public static InetSocketAddress localAddress(FileDescriptor fd)
 520         throws IOException
 521     {
 522         return new InetSocketAddress(localInetAddress(fd), localPort(fd));
 523     }
 524 
 525     private static native int remotePort(FileDescriptor fd)
 526         throws IOException;
 527 
 528     private static native InetAddress remoteInetAddress(FileDescriptor fd)
 529         throws IOException;
 530 
 531     static InetSocketAddress remoteAddress(FileDescriptor fd)
 532         throws IOException
 533     {
 534         return new InetSocketAddress(remoteInetAddress(fd), remotePort(fd));
 535     }
 536 
 537     private static native int getIntOption0(FileDescriptor fd, boolean mayNeedConversion,
 538                                             int level, int opt)
 539         throws IOException;
 540 
 541     private static native void setIntOption0(FileDescriptor fd, boolean mayNeedConversion,
 542                                              int level, int opt, int arg, boolean isIPv6)
 543         throws IOException;
 544 
 545     /**
 546      * Polls a file descriptor for events.
 547      * @param timeout the timeout to wait; 0 to not wait, -1 to wait indefinitely
 548      * @return the polled events or 0 if no events are polled
 549      */
 550     static native int poll(FileDescriptor fd, int events, long timeout)
 551         throws IOException;
 552 
 553     /**
 554      * Performs a non-blocking poll of a file descriptor.
 555      * @return the polled events or 0 if no events are polled
 556      */
 557     static int pollNow(FileDescriptor fd, int events) throws IOException {
 558         return poll(fd, events, 0);
 559     }
 560 
 561     /**
 562      * Polls a connecting socket to test if the connection has been established.
 563      *
 564      * @apiNote This method is public to allow it be used by code in jdk.sctp.
 565      *
 566      * @param timeout the timeout to wait; 0 to not wait, -1 to wait indefinitely
 567      * @return true if connected
 568      */
 569     public static native boolean pollConnect(FileDescriptor fd, long timeout)
 570         throws IOException;
 571 
 572     /**
 573      * Performs a non-blocking poll of a connecting socket to test if the
 574      * connection has been established.
 575      *
 576      * @return true if connected
 577      */
 578     static boolean pollConnectNow(FileDescriptor fd) throws IOException {
 579         return pollConnect(fd, 0);
 580     }
 581 
 582     /**
 583      * Return the number of bytes in the socket input buffer.
 584      */
 585     static native int available(FileDescriptor fd) throws IOException;
 586 
 587     /**
 588      * Send one byte of urgent data (MSG_OOB) on the socket.
 589      */
 590     static native int sendOOB(FileDescriptor fd, byte data) throws IOException;
 591 
 592 
 593     // -- Multicast support --
 594 
 595     /**
 596      * Join IPv4 multicast group
 597      */
 598     static int join4(FileDescriptor fd, int group, int interf, int source)
 599         throws IOException
 600     {
 601         return joinOrDrop4(true, fd, group, interf, source);
 602     }
 603 
 604     /**
 605      * Drop membership of IPv4 multicast group
 606      */
 607     static void drop4(FileDescriptor fd, int group, int interf, int source)
 608         throws IOException
 609     {
 610         joinOrDrop4(false, fd, group, interf, source);
 611     }
 612 
 613     private static native int joinOrDrop4(boolean join, FileDescriptor fd, int group, int interf, int source)
 614         throws IOException;
 615 
 616     /**
 617      * Block IPv4 source
 618      */
 619     static int block4(FileDescriptor fd, int group, int interf, int source)
 620         throws IOException
 621     {
 622         return blockOrUnblock4(true, fd, group, interf, source);
 623     }
 624 
 625     /**
 626      * Unblock IPv6 source
 627      */
 628     static void unblock4(FileDescriptor fd, int group, int interf, int source)
 629         throws IOException
 630     {
 631         blockOrUnblock4(false, fd, group, interf, source);
 632     }
 633 
 634     private static native int blockOrUnblock4(boolean block, FileDescriptor fd, int group,
 635                                               int interf, int source)
 636         throws IOException;
 637 
 638     /**
 639      * Join IPv6 multicast group
 640      */
 641     static int join6(FileDescriptor fd, byte[] group, int index, byte[] source)
 642         throws IOException
 643     {
 644         return joinOrDrop6(true, fd, group, index, source);
 645     }
 646 
 647     /**
 648      * Drop membership of IPv6 multicast group
 649      */
 650     static void drop6(FileDescriptor fd, byte[] group, int index, byte[] source)
 651         throws IOException
 652     {
 653         joinOrDrop6(false, fd, group, index, source);
 654     }
 655 
 656     private static native int joinOrDrop6(boolean join, FileDescriptor fd, byte[] group, int index, byte[] source)
 657         throws IOException;
 658 
 659     /**
 660      * Block IPv6 source
 661      */
 662     static int block6(FileDescriptor fd, byte[] group, int index, byte[] source)
 663         throws IOException
 664     {
 665         return blockOrUnblock6(true, fd, group, index, source);
 666     }
 667 
 668     /**
 669      * Unblock IPv6 source
 670      */
 671     static void unblock6(FileDescriptor fd, byte[] group, int index, byte[] source)
 672         throws IOException
 673     {
 674         blockOrUnblock6(false, fd, group, index, source);
 675     }
 676 
 677     static native int blockOrUnblock6(boolean block, FileDescriptor fd, byte[] group, int index, byte[] source)
 678         throws IOException;
 679 
 680     static native void setInterface4(FileDescriptor fd, int interf) throws IOException;
 681 
 682     static native int getInterface4(FileDescriptor fd) throws IOException;
 683 
 684     static native void setInterface6(FileDescriptor fd, int index) throws IOException;
 685 
 686     static native int getInterface6(FileDescriptor fd) throws IOException;
 687 
 688     private static native void initIDs();
 689 
 690     /**
 691      * Event masks for the various poll system calls.
 692      * They will be set platform dependent in the static initializer below.
 693      */
 694     public static final short POLLIN;
 695     public static final short POLLOUT;
 696     public static final short POLLERR;
 697     public static final short POLLHUP;
 698     public static final short POLLNVAL;
 699     public static final short POLLCONN;
 700 
 701     static native short pollinValue();
 702     static native short polloutValue();
 703     static native short pollerrValue();
 704     static native short pollhupValue();
 705     static native short pollnvalValue();
 706     static native short pollconnValue();
 707 
 708     static {
 709         IOUtil.load();
 710         initIDs();
 711 
 712         POLLIN     = pollinValue();
 713         POLLOUT    = polloutValue();
 714         POLLERR    = pollerrValue();
 715         POLLHUP    = pollhupValue();
 716         POLLNVAL   = pollnvalValue();
 717         POLLCONN   = pollconnValue();
 718     }
 719 
 720     static {
 721         int availLevel = isExclusiveBindAvailable();
 722         if (availLevel >= 0) {
 723             String exclBindProp = GetPropertyAction
 724                     .privilegedGetProperty("sun.net.useExclusiveBind");
 725             if (exclBindProp != null) {
 726                 exclusiveBind = exclBindProp.isEmpty() ?
 727                         true : Boolean.parseBoolean(exclBindProp);
 728             } else if (availLevel == 1) {
 729                 exclusiveBind = true;
 730             } else {
 731                 exclusiveBind = false;
 732             }
 733         } else {
 734             exclusiveBind = false;
 735         }
 736 
 737         fastLoopback = isFastTcpLoopbackRequested();
 738     }
 739 }