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 }