jdk/src/share/classes/sun/nio/ch/Net.java
changeset 1152 29d6145d1097
parent 2 90ce3da70b43
child 1247 b4c26443dee5
equal deleted inserted replaced
1151:4070cecdb99d 1152:29d6145d1097
    24  */
    24  */
    25 
    25 
    26 package sun.nio.ch;
    26 package sun.nio.ch;
    27 
    27 
    28 import java.io.*;
    28 import java.io.*;
    29 import java.lang.reflect.*;
       
    30 import java.net.*;
    29 import java.net.*;
    31 import java.nio.channels.*;
    30 import java.nio.channels.*;
       
    31 import java.util.*;
       
    32 import java.security.AccessController;
       
    33 import java.security.PrivilegedAction;
    32 
    34 
    33 
    35 
    34 class Net {                                             // package-private
    36 class Net {                                             // package-private
    35 
    37 
    36     private Net() { }
    38     private Net() { }
    37 
    39 
       
    40     // unspecified protocol family
       
    41     static final ProtocolFamily UNSPEC = new ProtocolFamily() {
       
    42         public String name() {
       
    43             return "UNSPEC";
       
    44         }
       
    45     };
    38 
    46 
    39     // -- Miscellaneous utilities --
    47     // -- Miscellaneous utilities --
       
    48 
       
    49     private static volatile boolean checkedIPv6 = false;
       
    50     private static volatile boolean isIPv6Available;
       
    51 
       
    52     /**
       
    53      * Tells whether dual-IPv4/IPv6 sockets should be used.
       
    54      */
       
    55     static boolean isIPv6Available() {
       
    56         if (!checkedIPv6) {
       
    57             isIPv6Available = isIPv6Available0();
       
    58             checkedIPv6 = true;
       
    59         }
       
    60         return isIPv6Available;
       
    61     }
    40 
    62 
    41     static InetSocketAddress checkAddress(SocketAddress sa) {
    63     static InetSocketAddress checkAddress(SocketAddress sa) {
    42         if (sa == null)
    64         if (sa == null)
    43             throw new IllegalArgumentException();
    65             throw new NullPointerException();
    44         if (!(sa instanceof InetSocketAddress))
    66         if (!(sa instanceof InetSocketAddress))
    45             throw new UnsupportedAddressTypeException(); // ## needs arg
    67             throw new UnsupportedAddressTypeException(); // ## needs arg
    46         InetSocketAddress isa = (InetSocketAddress)sa;
    68         InetSocketAddress isa = (InetSocketAddress)sa;
    47         if (isa.isUnresolved())
    69         if (isa.isUnresolved())
    48             throw new UnresolvedAddressException(); // ## needs arg
    70             throw new UnresolvedAddressException(); // ## needs arg
    61         if (x instanceof SocketException)
    83         if (x instanceof SocketException)
    62             throw (SocketException)x;
    84             throw (SocketException)x;
    63         Exception nx = x;
    85         Exception nx = x;
    64         if (x instanceof ClosedChannelException)
    86         if (x instanceof ClosedChannelException)
    65             nx = new SocketException("Socket is closed");
    87             nx = new SocketException("Socket is closed");
       
    88         else if (x instanceof NotYetConnectedException)
       
    89             nx = new SocketException("Socket is not connected");
    66         else if (x instanceof AlreadyBoundException)
    90         else if (x instanceof AlreadyBoundException)
    67             nx = new SocketException("Already bound");
    91             nx = new SocketException("Already bound");
    68         else if (x instanceof NotYetBoundException)
    92         else if (x instanceof NotYetBoundException)
    69             nx = new SocketException("Socket is not bound yet");
    93             nx = new SocketException("Socket is not bound yet");
    70         else if (x instanceof UnsupportedAddressTypeException)
    94         else if (x instanceof UnsupportedAddressTypeException)
   103         throws IOException
   127         throws IOException
   104     {
   128     {
   105         translateException(x, false);
   129         translateException(x, false);
   106     }
   130     }
   107 
   131 
       
   132     /**
       
   133      * Returns any IPv4 address of the given network interface, or
       
   134      * null if the interface does not have any IPv4 addresses.
       
   135      */
       
   136     static Inet4Address anyInet4Address(final NetworkInterface interf) {
       
   137         return AccessController.doPrivileged(new PrivilegedAction<Inet4Address>() {
       
   138             public Inet4Address run() {
       
   139                 Enumeration<InetAddress> addrs = interf.getInetAddresses();
       
   140                 while (addrs.hasMoreElements()) {
       
   141                     InetAddress addr = addrs.nextElement();
       
   142                     if (addr instanceof Inet4Address) {
       
   143                         return (Inet4Address)addr;
       
   144                     }
       
   145                 }
       
   146                 return null;
       
   147             }
       
   148         });
       
   149     }
       
   150 
       
   151     /**
       
   152      * Returns an IPv4 address as an int.
       
   153      */
       
   154     static int inet4AsInt(InetAddress ia) {
       
   155         if (ia instanceof Inet4Address) {
       
   156             byte[] addr = ia.getAddress();
       
   157             int address  = addr[3] & 0xFF;
       
   158             address |= ((addr[2] << 8) & 0xFF00);
       
   159             address |= ((addr[1] << 16) & 0xFF0000);
       
   160             address |= ((addr[0] << 24) & 0xFF000000);
       
   161             return address;
       
   162         }
       
   163         throw new AssertionError("Should not reach here");
       
   164     }
       
   165 
       
   166     /**
       
   167      * Returns an InetAddress from the given IPv4 address
       
   168      * represented as an int.
       
   169      */
       
   170     static InetAddress inet4FromInt(int address) {
       
   171         byte[] addr = new byte[4];
       
   172         addr[0] = (byte) ((address >>> 24) & 0xFF);
       
   173         addr[1] = (byte) ((address >>> 16) & 0xFF);
       
   174         addr[2] = (byte) ((address >>> 8) & 0xFF);
       
   175         addr[3] = (byte) (address & 0xFF);
       
   176         try {
       
   177             return InetAddress.getByAddress(addr);
       
   178         } catch (UnknownHostException uhe) {
       
   179             throw new AssertionError("Should not reach here");
       
   180         }
       
   181     }
       
   182 
       
   183     /**
       
   184      * Returns an IPv6 address as a byte array
       
   185      */
       
   186     static byte[] inet6AsByteArray(InetAddress ia) {
       
   187         if (ia instanceof Inet6Address) {
       
   188             return ia.getAddress();
       
   189         }
       
   190 
       
   191         // need to construct IPv4-mapped address
       
   192         if (ia instanceof Inet4Address) {
       
   193             byte[] ip4address = ia.getAddress();
       
   194             byte[] address = new byte[16];
       
   195             address[10] = (byte)0xff;
       
   196             address[11] = (byte)0xff;
       
   197             address[12] = ip4address[0];
       
   198             address[13] = ip4address[1];
       
   199             address[14] = ip4address[2];
       
   200             address[15] = ip4address[3];
       
   201             return address;
       
   202         }
       
   203 
       
   204         throw new AssertionError("Should not reach here");
       
   205     }
       
   206 
       
   207     // -- Socket options
       
   208 
       
   209     static void setSocketOption(FileDescriptor fd, ProtocolFamily family,
       
   210                                 SocketOption name, Object value)
       
   211         throws IOException
       
   212     {
       
   213         if (value == null)
       
   214             throw new IllegalArgumentException("Invalid option value");
       
   215 
       
   216         // only simple values supported by this method
       
   217         Class<?> type = name.type();
       
   218         if (type != Integer.class && type != Boolean.class)
       
   219             throw new AssertionError("Should not reach here");
       
   220 
       
   221         // special handling
       
   222         if (name == StandardSocketOption.SO_RCVBUF ||
       
   223             name == StandardSocketOption.SO_SNDBUF)
       
   224         {
       
   225             int i = ((Integer)value).intValue();
       
   226             if (i < 0)
       
   227                 throw new IllegalArgumentException("Invalid send/receive buffer size");
       
   228         }
       
   229         if (name == StandardSocketOption.SO_LINGER) {
       
   230             int i = ((Integer)value).intValue();
       
   231             if (i < 0)
       
   232                 value = Integer.valueOf(-1);
       
   233             if (i > 65535)
       
   234                 value = Integer.valueOf(65535);
       
   235         }
       
   236         if (name == StandardSocketOption.IP_TOS) {
       
   237             int i = ((Integer)value).intValue();
       
   238             if (i < 0 || i > 255)
       
   239                 throw new IllegalArgumentException("Invalid IP_TOS value");
       
   240         }
       
   241         if (name == StandardSocketOption.IP_MULTICAST_TTL) {
       
   242             int i = ((Integer)value).intValue();
       
   243             if (i < 0 || i > 255)
       
   244                 throw new IllegalArgumentException("Invalid TTL/hop value");
       
   245         }
       
   246 
       
   247         // map option name to platform level/name
       
   248         OptionKey key = SocketOptionRegistry.findOption(name, family);
       
   249         if (key == null)
       
   250             throw new AssertionError("Option not found");
       
   251 
       
   252         int arg;
       
   253         if (type == Integer.class) {
       
   254             arg = ((Integer)value).intValue();
       
   255         } else {
       
   256             boolean b = ((Boolean)value).booleanValue();
       
   257             arg = (b) ? 1 : 0;
       
   258         }
       
   259 
       
   260         boolean mayNeedConversion = (family == UNSPEC);
       
   261         setIntOption0(fd, mayNeedConversion, key.level(), key.name(), arg);
       
   262     }
       
   263 
       
   264     static Object getSocketOption(FileDescriptor fd, ProtocolFamily family,
       
   265                                   SocketOption name)
       
   266         throws IOException
       
   267     {
       
   268         Class<?> type = name.type();
       
   269 
       
   270         // only simple values supported by this method
       
   271         if (type != Integer.class && type != Boolean.class)
       
   272             throw new AssertionError("Should not reach here");
       
   273 
       
   274         // map option name to platform level/name
       
   275         OptionKey key = SocketOptionRegistry.findOption(name, family);
       
   276         if (key == null)
       
   277             throw new AssertionError("Option not found");
       
   278 
       
   279         boolean mayNeedConversion = (family == UNSPEC);
       
   280         int value = getIntOption0(fd, mayNeedConversion, key.level(), key.name());
       
   281 
       
   282         if (type == Integer.class) {
       
   283             return Integer.valueOf(value);
       
   284         } else {
       
   285             return (value == 0) ? Boolean.FALSE : Boolean.TRUE;
       
   286         }
       
   287     }
   108 
   288 
   109     // -- Socket operations --
   289     // -- Socket operations --
   110 
   290 
       
   291     static native boolean isIPv6Available0();
       
   292 
   111     static FileDescriptor socket(boolean stream) {
   293     static FileDescriptor socket(boolean stream) {
   112         return IOUtil.newFD(socket0(stream, false));
   294         return socket(UNSPEC, stream);
       
   295     }
       
   296 
       
   297     static FileDescriptor socket(ProtocolFamily family, boolean stream) {
       
   298         boolean preferIPv6 = isIPv6Available() &&
       
   299             (family != StandardProtocolFamily.INET);
       
   300         return IOUtil.newFD(socket0(preferIPv6, stream, false));
   113     }
   301     }
   114 
   302 
   115     static FileDescriptor serverSocket(boolean stream) {
   303     static FileDescriptor serverSocket(boolean stream) {
   116         return IOUtil.newFD(socket0(stream, true));
   304         return IOUtil.newFD(socket0(isIPv6Available(), stream, true));
   117     }
   305     }
   118 
   306 
   119     // Due to oddities SO_REUSEADDR on windows reuse is ignored
   307     // Due to oddities SO_REUSEADDR on windows reuse is ignored
   120     private static native int socket0(boolean stream, boolean reuse);
   308     private static native int socket0(boolean preferIPv6, boolean stream, boolean reuse);
   121 
   309 
   122     static native void bind(FileDescriptor fd, InetAddress addr, int port)
   310     static void bind(FileDescriptor fd, InetAddress addr, int port)
   123         throws IOException;
   311         throws IOException
   124 
   312     {
   125     static native int connect(FileDescriptor fd,
   313         bind(UNSPEC, fd, addr, port);
   126                               InetAddress remote,
   314     }
   127                               int remotePort,
   315 
   128                               int trafficClass)
   316     static void bind(ProtocolFamily family, FileDescriptor fd,
   129         throws IOException;
   317                      InetAddress addr, int port) throws IOException
   130 
   318     {
       
   319         boolean preferIPv6 = isIPv6Available() &&
       
   320             (family != StandardProtocolFamily.INET);
       
   321         bind0(preferIPv6, fd, addr, port);
       
   322     }
       
   323 
       
   324     private static native void bind0(boolean preferIPv6, FileDescriptor fd,
       
   325                                      InetAddress addr, int port)
       
   326         throws IOException;
       
   327 
       
   328     static native void listen(FileDescriptor fd, int backlog) throws IOException;
       
   329 
       
   330     static int connect(FileDescriptor fd, InetAddress remote, int remotePort)
       
   331         throws IOException
       
   332     {
       
   333         return connect(UNSPEC, fd, remote, remotePort);
       
   334     }
       
   335 
       
   336     static int connect(ProtocolFamily family, FileDescriptor fd, InetAddress remote, int remotePort)
       
   337         throws IOException
       
   338     {
       
   339         boolean preferIPv6 = isIPv6Available() &&
       
   340             (family != StandardProtocolFamily.INET);
       
   341         return connect0(preferIPv6, fd, remote, remotePort);
       
   342     }
       
   343 
       
   344     private static native int connect0(boolean preferIPv6,
       
   345                                        FileDescriptor fd,
       
   346                                        InetAddress remote,
       
   347                                        int remotePort)
       
   348         throws IOException;
       
   349 
       
   350 
       
   351     public final static int SHUT_RD = 0;
       
   352     public final static int SHUT_WR = 1;
       
   353     public final static int SHUT_RDWR = 2;
       
   354 
       
   355     static native void shutdown(FileDescriptor fd, int how) throws IOException;
   131 
   356 
   132     private static native int localPort(FileDescriptor fd)
   357     private static native int localPort(FileDescriptor fd)
   133         throws IOException;
   358         throws IOException;
   134 
   359 
   135     private static native InetAddress localInetAddress(FileDescriptor fd)
   360     private static native InetAddress localInetAddress(FileDescriptor fd)
   136         throws IOException;
   361         throws IOException;
   137 
   362 
   138     static InetSocketAddress localAddress(FileDescriptor fd) {
   363     static InetSocketAddress localAddress(FileDescriptor fd)
   139         try {
   364         throws IOException
   140             return new InetSocketAddress(localInetAddress(fd),
   365     {
   141                                          localPort(fd));
   366         return new InetSocketAddress(localInetAddress(fd), localPort(fd));
   142         } catch (IOException x) {
   367     }
   143             throw new Error(x);         // Can't happen
   368 
   144         }
   369     private static native int remotePort(FileDescriptor fd)
   145     }
   370         throws IOException;
   146 
   371 
   147     static int localPortNumber(FileDescriptor fd) {
   372     private static native InetAddress remoteInetAddress(FileDescriptor fd)
   148         try {
   373         throws IOException;
   149             return localPort(fd);
   374 
   150         } catch (IOException x) {
   375     static InetSocketAddress remoteAddress(FileDescriptor fd)
   151             throw new Error(x);         // Can't happen
   376         throws IOException
   152         }
   377     {
   153     }
   378         return new InetSocketAddress(remoteInetAddress(fd), remotePort(fd));
   154 
   379     }
   155     private static native int getIntOption0(FileDescriptor fd, int opt)
   380 
   156         throws IOException;
   381     private static native int getIntOption0(FileDescriptor fd, boolean mayNeedConversion,
   157 
   382                                             int level, int opt)
   158     static int getIntOption(FileDescriptor fd, int opt)
   383         throws IOException;
   159         throws IOException
   384 
   160     {
   385     private static native void setIntOption0(FileDescriptor fd, boolean mayNeedConversion,
   161         return getIntOption0(fd, opt);
   386                                              int level, int opt, int arg)
   162     }
   387         throws IOException;
   163 
   388 
   164 
   389     // -- Multicast support --
   165     private static native void setIntOption0(FileDescriptor fd,
   390 
   166                                              int opt, int arg)
   391 
   167         throws IOException;
   392     /**
   168 
   393      * Join IPv4 multicast group
   169     static void setIntOption(FileDescriptor fd, int opt, int arg)
   394      */
   170         throws IOException
   395     static int join4(FileDescriptor fd, int group, int interf, int source)
   171     {
   396         throws IOException
   172         setIntOption0(fd, opt, arg);
   397     {
   173     }
   398         return joinOrDrop4(true, fd, group, interf, source);
       
   399     }
       
   400 
       
   401     /**
       
   402      * Drop membership of IPv4 multicast group
       
   403      */
       
   404     static void drop4(FileDescriptor fd, int group, int interf, int source)
       
   405         throws IOException
       
   406     {
       
   407         joinOrDrop4(false, fd, group, interf, source);
       
   408     }
       
   409 
       
   410     private static native int joinOrDrop4(boolean join, FileDescriptor fd, int group, int interf, int source)
       
   411         throws IOException;
       
   412 
       
   413     /**
       
   414      * Block IPv4 source
       
   415      */
       
   416     static int block4(FileDescriptor fd, int group, int interf, int source)
       
   417         throws IOException
       
   418     {
       
   419         return blockOrUnblock4(true, fd, group, interf, source);
       
   420     }
       
   421 
       
   422     /**
       
   423      * Unblock IPv6 source
       
   424      */
       
   425     static void unblock4(FileDescriptor fd, int group, int interf, int source)
       
   426         throws IOException
       
   427     {
       
   428         blockOrUnblock4(false, fd, group, interf, source);
       
   429     }
       
   430 
       
   431     private static native int blockOrUnblock4(boolean block, FileDescriptor fd, int group,
       
   432                                               int interf, int source)
       
   433         throws IOException;
       
   434 
       
   435     /**
       
   436      * Join IPv6 multicast group
       
   437      */
       
   438     static int join6(FileDescriptor fd, byte[] group, int index, byte[] source)
       
   439         throws IOException
       
   440     {
       
   441         return joinOrDrop6(true, fd, group, index, source);
       
   442     }
       
   443 
       
   444     /**
       
   445      * Drop membership of IPv6 multicast group
       
   446      */
       
   447     static void drop6(FileDescriptor fd, byte[] group, int index, byte[] source)
       
   448         throws IOException
       
   449     {
       
   450         joinOrDrop6(false, fd, group, index, source);
       
   451     }
       
   452 
       
   453     private static native int joinOrDrop6(boolean join, FileDescriptor fd, byte[] group, int index, byte[] source)
       
   454         throws IOException;
       
   455 
       
   456     /**
       
   457      * Block IPv6 source
       
   458      */
       
   459     static int block6(FileDescriptor fd, byte[] group, int index, byte[] source)
       
   460         throws IOException
       
   461     {
       
   462         return blockOrUnblock6(true, fd, group, index, source);
       
   463     }
       
   464 
       
   465     /**
       
   466      * Unblock IPv6 source
       
   467      */
       
   468     static void unblock6(FileDescriptor fd, byte[] group, int index, byte[] source)
       
   469         throws IOException
       
   470     {
       
   471         blockOrUnblock6(false, fd, group, index, source);
       
   472     }
       
   473 
       
   474     static native int blockOrUnblock6(boolean block, FileDescriptor fd, byte[] group, int index, byte[] source)
       
   475         throws IOException;
       
   476 
       
   477     static native void setInterface4(FileDescriptor fd, int interf) throws IOException;
       
   478 
       
   479     static native int getInterface4(FileDescriptor fd) throws IOException;
       
   480 
       
   481     static native void setInterface6(FileDescriptor fd, int index) throws IOException;
       
   482 
       
   483     static native int getInterface6(FileDescriptor fd) throws IOException;
   174 
   484 
   175     private static native void initIDs();
   485     private static native void initIDs();
   176 
   486 
   177     static {
   487     static {
   178         Util.load();
   488         Util.load();