|
1 /* |
|
2 * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. |
|
3 * |
|
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
5 * |
|
6 * This code is free software; you can redistribute it and/or modify it |
|
7 * under the terms of the GNU General Public License version 2 only, as |
|
8 * published by the Free Software Foundation. Oracle designates this |
|
9 * particular file as subject to the "Classpath" exception as provided |
|
10 * by Oracle in the LICENSE file that accompanied this code. |
|
11 * |
|
12 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
15 * version 2 for more details (a copy is included in the LICENSE file that |
|
16 * accompanied this code). |
|
17 * |
|
18 * You should have received a copy of the GNU General Public License version |
|
19 * 2 along with this work; if not, write to the Free Software Foundation, |
|
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
21 * |
|
22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
23 * or visit www.oracle.com if you need additional information or have any |
|
24 * questions. |
|
25 * |
|
26 */ |
|
27 @@END_COPYRIGHT@@ |
|
28 |
|
29 #include <stdio.h> |
|
30 #ifdef _WIN32 |
|
31 #include <winsock2.h> |
|
32 #include <ws2tcpip.h> |
|
33 #else |
|
34 #include <sys/types.h> |
|
35 #include <sys/socket.h> |
|
36 #include <netinet/in.h> |
|
37 #include <netinet/tcp.h> |
|
38 #endif |
|
39 |
|
40 /* Defines SO_REUSEPORT */ |
|
41 #if !defined(SO_REUSEPORT) |
|
42 #ifdef _WIN32 |
|
43 #define SO_REUSEPORT 0 |
|
44 #elif __linux__ |
|
45 #define SO_REUSEPORT 15 |
|
46 #elif __solaris__ |
|
47 #define SO_REUSEPORT 0x100e |
|
48 #elif defined(AIX) || defined(MACOSX) |
|
49 #define SO_REUSEPORT 0x0200 |
|
50 #else |
|
51 #define SO_REUSEPORT 0 |
|
52 #endif |
|
53 #endif |
|
54 |
|
55 /* On Solaris, "sun" is defined as a macro. Undefine to make package |
|
56 declaration valid */ |
|
57 #undef sun |
|
58 |
|
59 /* To be able to name the Java constants the same as the C constants without |
|
60 having the preprocessor rewrite those identifiers, add PREFIX_ to all |
|
61 identifiers matching a C constant. The PREFIX_ is filtered out in the |
|
62 makefile. */ |
|
63 |
|
64 @@START_HERE@@ |
|
65 |
|
66 package sun.nio.ch; |
|
67 import java.net.SocketOption; |
|
68 import java.net.StandardSocketOptions; |
|
69 import java.net.ProtocolFamily; |
|
70 import java.net.StandardProtocolFamily; |
|
71 import java.util.Map; |
|
72 import java.util.HashMap; |
|
73 class SocketOptionRegistry { |
|
74 |
|
75 private SocketOptionRegistry() { } |
|
76 |
|
77 private static class RegistryKey { |
|
78 private final SocketOption<?> name; |
|
79 private final ProtocolFamily family; |
|
80 RegistryKey(SocketOption<?> name, ProtocolFamily family) { |
|
81 this.name = name; |
|
82 this.family = family; |
|
83 } |
|
84 public int hashCode() { |
|
85 return name.hashCode() + family.hashCode(); |
|
86 } |
|
87 public boolean equals(Object ob) { |
|
88 if (ob == null) return false; |
|
89 if (!(ob instanceof RegistryKey)) return false; |
|
90 RegistryKey other = (RegistryKey)ob; |
|
91 if (this.name != other.name) return false; |
|
92 if (this.family != other.family) return false; |
|
93 return true; |
|
94 } |
|
95 } |
|
96 |
|
97 private static class LazyInitialization { |
|
98 |
|
99 static final Map<RegistryKey,OptionKey> options = options(); |
|
100 |
|
101 private static Map<RegistryKey,OptionKey> options() { |
|
102 Map<RegistryKey,OptionKey> map = |
|
103 new HashMap<RegistryKey,OptionKey>(); |
|
104 map.put(new RegistryKey(StandardSocketOptions.PREFIX_SO_BROADCAST, |
|
105 Net.UNSPEC), new OptionKey(SOL_SOCKET, SO_BROADCAST)); |
|
106 map.put(new RegistryKey(StandardSocketOptions.PREFIX_SO_KEEPALIVE, |
|
107 Net.UNSPEC), new OptionKey(SOL_SOCKET, SO_KEEPALIVE)); |
|
108 map.put(new RegistryKey(StandardSocketOptions.PREFIX_SO_LINGER, |
|
109 Net.UNSPEC), new OptionKey(SOL_SOCKET, SO_LINGER)); |
|
110 map.put(new RegistryKey(StandardSocketOptions.PREFIX_SO_SNDBUF, |
|
111 Net.UNSPEC), new OptionKey(SOL_SOCKET, SO_SNDBUF)); |
|
112 map.put(new RegistryKey(StandardSocketOptions.PREFIX_SO_RCVBUF, |
|
113 Net.UNSPEC), new OptionKey(SOL_SOCKET, SO_RCVBUF)); |
|
114 map.put(new RegistryKey(StandardSocketOptions.PREFIX_SO_REUSEADDR, |
|
115 Net.UNSPEC), new OptionKey(SOL_SOCKET, SO_REUSEADDR)); |
|
116 map.put(new RegistryKey(StandardSocketOptions.PREFIX_SO_REUSEPORT, |
|
117 Net.UNSPEC), new OptionKey(SOL_SOCKET, SO_REUSEPORT)); |
|
118 // IPPROTO_TCP is 6 |
|
119 map.put(new RegistryKey(StandardSocketOptions.PREFIX_TCP_NODELAY, |
|
120 Net.UNSPEC), new OptionKey(6, TCP_NODELAY)); |
|
121 |
|
122 // IPPROTO_IP is 0 |
|
123 map.put(new RegistryKey(StandardSocketOptions.PREFIX_IP_TOS, |
|
124 StandardProtocolFamily.INET), new OptionKey(0, IP_TOS)); |
|
125 map.put(new RegistryKey(StandardSocketOptions.PREFIX_IP_MULTICAST_IF, |
|
126 StandardProtocolFamily.INET), new OptionKey(0, IP_MULTICAST_IF)); |
|
127 map.put(new RegistryKey(StandardSocketOptions.PREFIX_IP_MULTICAST_TTL, |
|
128 StandardProtocolFamily.INET), new OptionKey(0, IP_MULTICAST_TTL)); |
|
129 map.put(new RegistryKey(StandardSocketOptions.PREFIX_IP_MULTICAST_LOOP, |
|
130 StandardProtocolFamily.INET), new OptionKey(0, IP_MULTICAST_LOOP)); |
|
131 |
|
132 #ifdef AF_INET6 |
|
133 // IPPROTO_IPV6 is 41 |
|
134 map.put(new RegistryKey(StandardSocketOptions.PREFIX_IP_TOS, |
|
135 StandardProtocolFamily.INET6), new OptionKey(41, IPV6_TCLASS)); |
|
136 map.put(new RegistryKey(StandardSocketOptions.PREFIX_IP_MULTICAST_IF, |
|
137 StandardProtocolFamily.INET6), new OptionKey(41, IPV6_MULTICAST_IF)); |
|
138 map.put(new RegistryKey(StandardSocketOptions.PREFIX_IP_MULTICAST_TTL, |
|
139 StandardProtocolFamily.INET6), new OptionKey(41, IPV6_MULTICAST_HOPS)); |
|
140 map.put(new RegistryKey(StandardSocketOptions.PREFIX_IP_MULTICAST_LOOP, |
|
141 StandardProtocolFamily.INET6), new OptionKey(41, IPV6_MULTICAST_LOOP)); |
|
142 #endif |
|
143 |
|
144 map.put(new RegistryKey(ExtendedSocketOption.PREFIX_SO_OOBINLINE, |
|
145 Net.UNSPEC), new OptionKey(SOL_SOCKET, SO_OOBINLINE)); |
|
146 return map; |
|
147 } |
|
148 } |
|
149 |
|
150 public static OptionKey findOption(SocketOption<?> name, ProtocolFamily family) { |
|
151 RegistryKey key = new RegistryKey(name, family); |
|
152 return LazyInitialization.options.get(key); |
|
153 } |
|
154 } |