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