42 public String name() { |
42 public String name() { |
43 return "UNSPEC"; |
43 return "UNSPEC"; |
44 } |
44 } |
45 }; |
45 }; |
46 |
46 |
|
47 // set to true if exclusive binding is on for Windows |
|
48 private static final boolean exclusiveBind; |
|
49 |
|
50 static { |
|
51 int availLevel = isExclusiveBindAvailable(); |
|
52 if (availLevel >= 0) { |
|
53 String exclBindProp = |
|
54 java.security.AccessController.doPrivileged( |
|
55 new PrivilegedAction<String>() { |
|
56 @Override |
|
57 public String run() { |
|
58 return System.getProperty( |
|
59 "sun.net.useExclusiveBind"); |
|
60 } |
|
61 }); |
|
62 if (exclBindProp != null) { |
|
63 exclusiveBind = exclBindProp.length() == 0 ? |
|
64 true : Boolean.parseBoolean(exclBindProp); |
|
65 } else if (availLevel == 1) { |
|
66 exclusiveBind = true; |
|
67 } else { |
|
68 exclusiveBind = false; |
|
69 } |
|
70 } else { |
|
71 exclusiveBind = false; |
|
72 } |
|
73 } |
|
74 |
47 // -- Miscellaneous utilities -- |
75 // -- Miscellaneous utilities -- |
48 |
76 |
49 private static volatile boolean checkedIPv6 = false; |
77 private static volatile boolean checkedIPv6 = false; |
50 private static volatile boolean isIPv6Available; |
78 private static volatile boolean isIPv6Available; |
51 |
79 |
306 |
341 |
307 // -- Socket operations -- |
342 // -- Socket operations -- |
308 |
343 |
309 private static native boolean isIPv6Available0(); |
344 private static native boolean isIPv6Available0(); |
310 |
345 |
|
346 /* |
|
347 * Returns 1 for Windows versions that support exclusive binding by default, 0 |
|
348 * for those that do not, and -1 for Solaris/Linux/Mac OS |
|
349 */ |
|
350 private static native int isExclusiveBindAvailable(); |
|
351 |
311 private static native boolean canIPv6SocketJoinIPv4Group0(); |
352 private static native boolean canIPv6SocketJoinIPv4Group0(); |
312 |
353 |
313 private static native boolean canJoin6WithIPv4Group0(); |
354 private static native boolean canJoin6WithIPv4Group0(); |
314 |
355 |
315 static FileDescriptor socket(boolean stream) throws IOException { |
356 static FileDescriptor socket(boolean stream) throws IOException { |
339 static void bind(ProtocolFamily family, FileDescriptor fd, |
380 static void bind(ProtocolFamily family, FileDescriptor fd, |
340 InetAddress addr, int port) throws IOException |
381 InetAddress addr, int port) throws IOException |
341 { |
382 { |
342 boolean preferIPv6 = isIPv6Available() && |
383 boolean preferIPv6 = isIPv6Available() && |
343 (family != StandardProtocolFamily.INET); |
384 (family != StandardProtocolFamily.INET); |
344 bind0(preferIPv6, fd, addr, port); |
385 bind0(fd, preferIPv6, exclusiveBind, addr, port); |
345 } |
386 } |
346 |
387 |
347 private static native void bind0(boolean preferIPv6, FileDescriptor fd, |
388 private static native void bind0(FileDescriptor fd, boolean preferIPv6, |
348 InetAddress addr, int port) |
389 boolean useExclBind, InetAddress addr, |
|
390 int port) |
349 throws IOException; |
391 throws IOException; |
350 |
392 |
351 static native void listen(FileDescriptor fd, int backlog) throws IOException; |
393 static native void listen(FileDescriptor fd, int backlog) throws IOException; |
352 |
394 |
353 static int connect(FileDescriptor fd, InetAddress remote, int remotePort) |
395 static int connect(FileDescriptor fd, InetAddress remote, int remotePort) |