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