1 /* 2 * Copyright (c) 2008, 2019, 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 defined(__linux__) 45 #define SO_REUSEPORT 15 46 #elif defined(__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 }