src/java.base/share/classes/sun/nio/ch/Net.java
branchunixdomainchannels
changeset 58847 692de65ab293
parent 58801 119ac9128c1b
child 58848 c3df0f8b6d93
equal deleted inserted replaced
58832:203fceb089fc 58847:692de65ab293
    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
   115     }
   106     }
   116 
   107 
   117     /**
   108     /**
   118      * Returns true if exclusive binding is on
   109      * Returns true if exclusive binding is on
   119      */
   110      */
   120     public static boolean useExclusiveBind() {
   111     static boolean useExclusiveBind() {
   121         return exclusiveBind;
   112         return exclusiveBind;
   122     }
   113     }
   123 
   114 
   124     /**
   115     /**
   125      * Tells whether IPv6 sockets can join IPv4 multicast groups
   116      * Tells whether IPv6 sockets can join IPv4 multicast groups
   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)
   799             exclusiveBind = false;
   800             exclusiveBind = false;
   800         }
   801         }
   801 
   802 
   802         fastLoopback = isFastTcpLoopbackRequested();
   803         fastLoopback = isFastTcpLoopbackRequested();
   803     }
   804     }
   804 
       
   805 
       
   806 }
   805 }