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