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 }