24 */ |
24 */ |
25 |
25 |
26 package sun.nio.ch; |
26 package sun.nio.ch; |
27 |
27 |
28 import java.io.FileDescriptor; |
28 import java.io.FileDescriptor; |
|
29 import java.io.FilePermission; |
29 import java.io.IOException; |
30 import java.io.IOException; |
30 import java.net.Inet4Address; |
31 import java.net.Inet4Address; |
31 import java.net.Inet6Address; |
32 import java.net.Inet6Address; |
32 import java.net.InetAddress; |
33 import java.net.InetAddress; |
33 import java.net.InetSocketAddress; |
34 import java.net.InetSocketAddress; |
55 import sun.security.action.GetPropertyAction; |
56 import sun.security.action.GetPropertyAction; |
56 |
57 |
57 |
58 |
58 public class Net { |
59 public class Net { |
59 |
60 |
60 public Net() { } |
61 private Net() { } |
61 |
62 |
62 private static final boolean unixDomainSupported; |
63 private static final boolean unixDomainSupported = |
63 //private static final boolean abstractNamesSupported; |
64 unixDomainSocketSupported(); |
64 |
65 |
65 // unspecified protocol family |
66 // unspecified protocol family |
66 public static final ProtocolFamily UNSPEC = new ProtocolFamily() { |
67 static final ProtocolFamily UNSPEC = new ProtocolFamily() { |
67 public String name() { |
68 public String name() { |
68 return "UNSPEC"; |
69 return "UNSPEC"; |
69 } |
70 } |
70 }; |
71 }; |
71 |
|
72 static { |
|
73 unixDomainSupported = unixDomainSocketSupported(); |
|
74 String name = GetPropertyAction.privilegedGetProperty("os.name") |
|
75 .toLowerCase(); |
|
76 |
|
77 // Windows claims to support it but doesn't. Disable for now |
|
78 //abstractNamesSupported = name.startsWith("linux"); |
|
79 // || name.startsWith("windows"); |
|
80 } |
|
81 |
72 |
82 // set to true if exclusive binding is on for Windows |
73 // set to true if exclusive binding is on for Windows |
83 private static final boolean exclusiveBind; |
74 private static final boolean exclusiveBind; |
84 |
75 |
85 // set to true if the fast tcp loopback should be enabled on Windows |
76 // set to true if the fast tcp loopback should be enabled on Windows |
324 // -- Socket options |
315 // -- Socket options |
325 |
316 |
326 static final ExtendedSocketOptions extendedOptions = |
317 static final ExtendedSocketOptions extendedOptions = |
327 ExtendedSocketOptions.getInstance(); |
318 ExtendedSocketOptions.getInstance(); |
328 |
319 |
329 public static void setSocketOption(FileDescriptor fd, SocketOption<?> name, Object value) |
320 static void setSocketOption(FileDescriptor fd, SocketOption<?> name, Object value) |
330 throws IOException |
321 throws IOException |
331 { |
322 { |
332 setSocketOption(fd, Net.UNSPEC, name, value); |
323 setSocketOption(fd, Net.UNSPEC, name, value); |
333 } |
324 } |
334 |
325 |
335 public static void setSocketOption(FileDescriptor fd, ProtocolFamily family, |
326 static void setSocketOption(FileDescriptor fd, ProtocolFamily family, |
336 SocketOption<?> name, Object value) |
327 SocketOption<?> name, Object value) |
337 throws IOException |
328 throws IOException |
338 { |
329 { |
339 if (value == null) |
330 if (value == null) |
340 throw new IllegalArgumentException("Invalid option value"); |
331 throw new IllegalArgumentException("Invalid option value"); |
392 boolean mayNeedConversion = (family == UNSPEC); |
383 boolean mayNeedConversion = (family == UNSPEC); |
393 boolean isIPv6 = (family == StandardProtocolFamily.INET6); |
384 boolean isIPv6 = (family == StandardProtocolFamily.INET6); |
394 setIntOption0(fd, mayNeedConversion, key.level(), key.name(), arg, isIPv6); |
385 setIntOption0(fd, mayNeedConversion, key.level(), key.name(), arg, isIPv6); |
395 } |
386 } |
396 |
387 |
397 public static Object getSocketOption(FileDescriptor fd, SocketOption<?> name) |
388 static Object getSocketOption(FileDescriptor fd, SocketOption<?> name) |
398 throws IOException |
389 throws IOException |
399 { |
390 { |
400 return getSocketOption(fd, Net.UNSPEC, name); |
391 return getSocketOption(fd, Net.UNSPEC, name); |
401 } |
392 } |
402 |
393 |
403 public static Object getSocketOption(FileDescriptor fd, ProtocolFamily family, SocketOption<?> name) |
394 static Object getSocketOption(FileDescriptor fd, ProtocolFamily family, SocketOption<?> name) |
404 throws IOException |
395 throws IOException |
405 { |
396 { |
406 Class<?> type = name.type(); |
397 Class<?> type = name.type(); |
407 |
398 |
408 if (extendedOptions.isOptionSupported(name)) { |
399 if (extendedOptions.isOptionSupported(name)) { |
457 boolean preferIPv6 = isIPv6Available() && |
448 boolean preferIPv6 = isIPv6Available() && |
458 (family != StandardProtocolFamily.INET); |
449 (family != StandardProtocolFamily.INET); |
459 return IOUtil.newFD(socket0(preferIPv6, stream, false, fastLoopback)); |
450 return IOUtil.newFD(socket0(preferIPv6, stream, false, fastLoopback)); |
460 } |
451 } |
461 |
452 |
462 public static FileDescriptor serverSocket(boolean stream) { |
453 static FileDescriptor serverSocket(boolean stream) { |
463 return IOUtil.newFD(socket0(isIPv6Available(), stream, true, fastLoopback)); |
454 return IOUtil.newFD(socket0(isIPv6Available(), stream, true, fastLoopback)); |
464 } |
455 } |
465 |
456 |
466 // Due to oddities SO_REUSEADDR on windows reuse is ignored |
457 // Due to oddities SO_REUSEADDR on windows reuse is ignored |
467 private static native int socket0(boolean preferIPv6, boolean stream, boolean reuse, |
458 private static native int socket0(boolean preferIPv6, boolean stream, boolean reuse, |
487 private static native void bind0(FileDescriptor fd, boolean preferIPv6, |
478 private static native void bind0(FileDescriptor fd, boolean preferIPv6, |
488 boolean useExclBind, InetAddress addr, |
479 boolean useExclBind, InetAddress addr, |
489 int port) |
480 int port) |
490 throws IOException; |
481 throws IOException; |
491 |
482 |
492 public static native void listen(FileDescriptor fd, int backlog) throws IOException; |
483 static native void listen(FileDescriptor fd, int backlog) throws IOException; |
493 |
484 |
494 static int connect(FileDescriptor fd, InetAddress remote, int remotePort) |
485 static int connect(FileDescriptor fd, InetAddress remote, int remotePort) |
495 throws IOException |
486 throws IOException |
496 { |
487 { |
497 return connect(UNSPEC, fd, remote, remotePort); |
488 return connect(UNSPEC, fd, remote, remotePort); |
521 |
512 |
522 public static final int SHUT_RD = 0; |
513 public static final int SHUT_RD = 0; |
523 public static final int SHUT_WR = 1; |
514 public static final int SHUT_WR = 1; |
524 public static final int SHUT_RDWR = 2; |
515 public static final int SHUT_RDWR = 2; |
525 |
516 |
526 public static native void shutdown(FileDescriptor fd, int how) throws IOException; |
517 static native void shutdown(FileDescriptor fd, int how) throws IOException; |
527 |
518 |
528 private static native int localPort(FileDescriptor fd) |
519 private static native int localPort(FileDescriptor fd) |
529 throws IOException; |
520 throws IOException; |
530 |
521 |
531 private static native InetAddress localInetAddress(FileDescriptor fd) |
522 private static native InetAddress localInetAddress(FileDescriptor fd) |
588 * Performs a non-blocking poll of a connecting socket to test if the |
579 * Performs a non-blocking poll of a connecting socket to test if the |
589 * connection has been established. |
580 * connection has been established. |
590 * |
581 * |
591 * @return true if connected |
582 * @return true if connected |
592 */ |
583 */ |
593 public static boolean pollConnectNow(FileDescriptor fd) throws IOException { |
584 static boolean pollConnectNow(FileDescriptor fd) throws IOException { |
594 return pollConnect(fd, 0); |
585 return pollConnect(fd, 0); |
595 } |
586 } |
596 |
587 |
597 /** |
588 /** |
598 * Return the number of bytes in the socket input buffer. |
589 * Return the number of bytes in the socket input buffer. |
599 */ |
590 */ |
600 public static native int available(FileDescriptor fd) throws IOException; |
591 static native int available(FileDescriptor fd) throws IOException; |
601 |
592 |
602 /** |
593 /** |
603 * Send one byte of urgent data (MSG_OOB) on the socket. |
594 * Send one byte of urgent data (MSG_OOB) on the socket. |
604 */ |
595 */ |
605 static native int sendOOB(FileDescriptor fd, byte data) throws IOException; |
596 static native int sendOOB(FileDescriptor fd, byte data) throws IOException; |
706 * Event masks for the various poll system calls. |
697 * Event masks for the various poll system calls. |
707 * They will be set platform dependent in the static initializer below. |
698 * They will be set platform dependent in the static initializer below. |
708 */ |
699 */ |
709 public static final short POLLIN; |
700 public static final short POLLIN; |
710 public static final short POLLOUT; |
701 public static final short POLLOUT; |
711 |
|
712 public static boolean isUnixDomainSupported() { |
|
713 return unixDomainSupported; |
|
714 } |
|
715 |
702 |
716 public static UnixDomainSocketAddress checkUnixAddress(SocketAddress sa) { |
703 public static UnixDomainSocketAddress checkUnixAddress(SocketAddress sa) { |
717 if (sa == null) |
704 if (sa == null) |
718 throw new NullPointerException(); |
705 throw new NullPointerException(); |
719 if (!(sa instanceof UnixDomainSocketAddress)) |
706 if (!(sa instanceof UnixDomainSocketAddress)) |
720 throw new UnsupportedAddressTypeException(); |
707 throw new UnsupportedAddressTypeException(); |
721 UnixDomainSocketAddress usa = (UnixDomainSocketAddress)sa; |
708 UnixDomainSocketAddress usa = (UnixDomainSocketAddress)sa; |
722 //if (usa.isAbstract() && !abstractNamesSupported()) |
|
723 //throw new UnsupportedAddressTypeException(); |
|
724 return usa; |
709 return usa; |
725 } |
710 } |
726 |
711 |
727 /** |
712 public static boolean isUnixDomainSupported() { |
728 * 2 methods to be implemented if fine-grained security to be used |
713 return unixDomainSupported; |
729 */ |
714 } |
|
715 |
|
716 private static UnixDomainSocketAddress UNNAMED = new UnixDomainSocketAddress(""); |
|
717 |
730 static UnixDomainSocketAddress getRevealedLocalAddress(UnixDomainSocketAddress addr) { |
718 static UnixDomainSocketAddress getRevealedLocalAddress(UnixDomainSocketAddress addr) { |
|
719 SecurityManager sm = System.getSecurityManager(); |
|
720 if (addr == null || sm == null) |
|
721 return addr; |
|
722 |
|
723 try{ |
|
724 FilePermission p = new FilePermission(addr.getPath(), "read"); |
|
725 sm.checkPermission(p); |
|
726 // Security check passed |
|
727 } catch (SecurityException e) { |
|
728 // Return unnamed address only if security check fails |
|
729 addr = UNNAMED; |
|
730 } |
731 return addr; |
731 return addr; |
732 } |
732 } |
733 |
733 |
734 static String getRevealedLocalAddressAsString(UnixDomainSocketAddress addr) { |
734 static String getRevealedLocalAddressAsString(UnixDomainSocketAddress addr) { |
735 return addr.toString(); |
735 return System.getSecurityManager() == null ? addr.toString() : |
|
736 UNNAMED.toString(); |
736 } |
737 } |
737 |
738 |
738 // -- Socket operations -- |
739 // -- Socket operations -- |
739 |
740 |
740 public static FileDescriptor unixDomainSocket() throws IOException { |
741 public static FileDescriptor unixDomainSocket() throws IOException { |
741 return IOUtil.newFD(unixDomainSocket0()); |
742 return IOUtil.newFD(unixDomainSocket0()); |
742 } |
743 } |
743 |
744 |
744 public static native boolean unixDomainSocketSupported(); |
|
745 |
|
746 private static native int unixDomainSocket0(); |
745 private static native int unixDomainSocket0(); |
|
746 |
|
747 private static native boolean unixDomainSocketSupported(); |
747 |
748 |
748 static native void unixDomainBind(FileDescriptor fd, UnixDomainSocketAddress addr) |
749 static native void unixDomainBind(FileDescriptor fd, UnixDomainSocketAddress addr) |
749 throws IOException; |
750 throws IOException; |
750 |
751 |
751 static native int unixDomainConnect(FileDescriptor fd, UnixDomainSocketAddress remote) |
752 static native int unixDomainConnect(FileDescriptor fd, UnixDomainSocketAddress remote) |